From: Thomas Walker Lynch Date: Tue, 2 Apr 2019 12:42:29 +0000 (+0200) Subject: first db namespace -> debug X-Git-Url: https://git.reasoningtechnology.com/style/static/gitweb.js?a=commitdiff_plain;h=3359aa824857124141ee7c936d9cf0c49021b5ca;p=subu first db namespace -> debug --- diff --git a/makefile b/makefile index 2cf9bb5..06d6508 100755 --- a/makefile +++ b/makefile @@ -1,32 +1,38 @@ -#MAKEABLE=$(shell \ -# find src-*\ -# \( -name 'makefile' -o -name 'Makefile' \)\ -# -printf "%h\n"\ -# | grep -v deprecated | grep -v doc | sort -u | sed ':a;N;$!ba;s/\n/ /g' \ -#) -MAKEABLE= module/da module/da/test module/db module/tranche module/dispatch - -.PHONY: all info clean dist-clean +MAKEABLE=\ + module/da\ + module/da/test\ + module/debug\ + module/tranche\ + module/dispatch +.PHONY: all all: $(foreach dir, $(MAKEABLE), \ - make -C $$dir - -make -C $$dir stage + -make -C $$dir dist-clean dep lib exec share + ) + +.PHONY: all +update: + $(foreach dir, $(MAKEABLE), \ + -make -C $$dir lib exec share ) +.PHONY: info info: @echo "SRCDIRS:" $(SRCDIRS) @echo "MAKEABLE:" $(MAKEABLE) +.PHONY: clean clean: for dir in $(MAKEABLE); do pushd $$dir; make clean; popd; done +.PHONY: dist-clean dist-clean : for dir in $(MAKEABLE); do pushd $$dir; make dist-clean; popd; done - for i in $(wildcard stage/lib/*); do rm $$i; done - for i in $(wildcard stage/inc/*); do rm $$i; done - for i in $(wildcard stage/bin/*); do rm $$i; done + for i in $(wildcard module/share/lib/*); do rm $$i; done + for i in $(wildcard module/share/inc/*); do rm $$i; done + for i in $(wildcard module/share/bin/*); do rm $$i; done diff --git a/module/db/lib/libda.a b/module/db/lib/libda.a deleted file mode 100644 index c6e819f..0000000 Binary files a/module/db/lib/libda.a and /dev/null differ diff --git a/module/db/makefile b/module/db/makefile deleted file mode 100644 index 181818b..0000000 --- a/module/db/makefile +++ /dev/null @@ -1,27 +0,0 @@ -# db - -SHELL=/bin/bash -MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc -#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc - --include makefile-flags - -.PHONY: all -all: version - -.PHONY: dep -dep: - if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi - $(MAKE) $@ - -.PHONY: lib -lib: - $(MAKE) $@ - cp $(SRCDIR)/db.lib.h $(INCDIR)/db.h - -%:: - $(MAKE) $@ - - - - diff --git a/module/db/makefile-flags b/module/db/makefile-flags deleted file mode 100644 index 65ef1be..0000000 --- a/module/db/makefile-flags +++ /dev/null @@ -1,31 +0,0 @@ - -MODULE=db - -DEPRDIR=deprecated -DOCDIR=doc -EXECDIR=exec -INCDIR=include -LIBDIR=lib -SHAREDIR=../share -SRCDIR=src -TESTDIR=test -TMPDIR=tmp -TOOLDIR=$(realpath $(PROJECT_SUBU)/tool) -TRYDIR=try - -DEPFILE=$(TMPDIR)/makefile-cc.deps -LIBFILE=$(LIBDIR)/lib$(MODULE).a -INCFILE=$(INCDIR)/$(MODULE).h - -# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo .. -ECHO= echo -#ECHO= echo -e - -# compiler and flags -C=gcc -CFLAGS=-std=gnu11 -fPIC -I. -ggdb -Werror -DDEBUG -DDEBUGDB -#CFLAGS=-std=gnu11 -fPIC -I. -Werror -LINKFLAGS=-Llib -ldb - - - diff --git a/module/db/src/db.lib.c b/module/db/src/db.lib.c deleted file mode 100644 index 8e6fe5d..0000000 --- a/module/db/src/db.lib.c +++ /dev/null @@ -1,14 +0,0 @@ - -#include "db.lib.h" - -#include -#include - -int dbprintf(const char *format, ...){ - va_list args; - va_start(args,format); - int ret = vfprintf(stdout, format, args); - fflush(stdout); - va_end(args); - return ret; -} diff --git a/module/db/src/db.lib.h b/module/db/src/db.lib.h deleted file mode 100644 index 7563eea..0000000 --- a/module/db/src/db.lib.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef DB_LIB_H -#define DB_LIB_H - -int dbprintf(const char *format, ...); - -#endif diff --git a/module/debug/lib/libda.a b/module/debug/lib/libda.a new file mode 100644 index 0000000..c6e819f Binary files /dev/null and b/module/debug/lib/libda.a differ diff --git a/module/debug/makefile b/module/debug/makefile new file mode 100644 index 0000000..181818b --- /dev/null +++ b/module/debug/makefile @@ -0,0 +1,27 @@ +# db + +SHELL=/bin/bash +MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc +#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc + +-include makefile-flags + +.PHONY: all +all: version + +.PHONY: dep +dep: + if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi + $(MAKE) $@ + +.PHONY: lib +lib: + $(MAKE) $@ + cp $(SRCDIR)/db.lib.h $(INCDIR)/db.h + +%:: + $(MAKE) $@ + + + + diff --git a/module/debug/makefile-flags b/module/debug/makefile-flags new file mode 100644 index 0000000..65ef1be --- /dev/null +++ b/module/debug/makefile-flags @@ -0,0 +1,31 @@ + +MODULE=db + +DEPRDIR=deprecated +DOCDIR=doc +EXECDIR=exec +INCDIR=include +LIBDIR=lib +SHAREDIR=../share +SRCDIR=src +TESTDIR=test +TMPDIR=tmp +TOOLDIR=$(realpath $(PROJECT_SUBU)/tool) +TRYDIR=try + +DEPFILE=$(TMPDIR)/makefile-cc.deps +LIBFILE=$(LIBDIR)/lib$(MODULE).a +INCFILE=$(INCDIR)/$(MODULE).h + +# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo .. +ECHO= echo +#ECHO= echo -e + +# compiler and flags +C=gcc +CFLAGS=-std=gnu11 -fPIC -I. -ggdb -Werror -DDEBUG -DDEBUGDB +#CFLAGS=-std=gnu11 -fPIC -I. -Werror +LINKFLAGS=-Llib -ldb + + + diff --git a/module/debug/src/debug.lib.c b/module/debug/src/debug.lib.c new file mode 100644 index 0000000..01ba20d --- /dev/null +++ b/module/debug/src/debug.lib.c @@ -0,0 +1,14 @@ + +#include "debug.lib.h" + +#include +#include + +int debug_printf(const char *format, ...){ + va_list args; + va_start(args,format); + int ret = vfprintf(stdout, format, args); + fflush(stdout); + va_end(args); + return ret; +} diff --git a/module/debug/src/debug.lib.h b/module/debug/src/debug.lib.h new file mode 100644 index 0000000..f1be3d8 --- /dev/null +++ b/module/debug/src/debug.lib.h @@ -0,0 +1,6 @@ +#ifndef DB_LIB_H +#define DB_LIB_H + +int debug_printf(const char *format, ...); + +#endif diff --git a/module/dispatch/#makefile# b/module/dispatch/#makefile# deleted file mode 100644 index d8fe923..0000000 --- a/module/dispatch/#makefile# +++ /dev/null @@ -1,44 +0,0 @@ -# src-dispatch/makefile - -SHELL=/bin/bash -MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc -#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc - --include makefile-flags - - -.PHONY: all -all: version - -.PHONY: info -info: - @echo "TRCDIR: " $(TRCDIR) - $(MAKE) $@ - -.PHONY: setup -setup: - [ ! -e $(TRCDIR) ] && mkdir $(TRCDIR) || true - $(MAKE) $@ - -.PHONY: dep -dep: - if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi - @trcsources=$(wildcard $(TRCDIR)/*.trc.c)$(wildcard $(TRCDIR)/*.trc.cc);\ - if [ ! -z "$$trcsources" ]; then\ - trctargets=$$(tranche-target $$trcsources -sep " " -tdir $(SRCDIR) );\ - $(ECHO) $$trcsources;\ - tranche-make $$trcsources -tdir $(SRCDIR) -mfile $(DEPFILE);\ - $(MAKE) $$trctargets;\ - fi - $(MAKE) $@ - -.PHONY: lib -lib: - $(MAKE) $@ - -o%:: - $(MAKE) $@ - - - - diff --git a/module/dispatch/dispatch.lib.c b/module/dispatch/dispatch.lib.c index c8303d4..de7011f 100644 --- a/module/dispatch/dispatch.lib.c +++ b/module/dispatch/dispatch.lib.c @@ -45,7 +45,7 @@ void dispatch_f_mess(char *fname, int err, char *dispatchee){ // interface call point, dispatch a function int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg){ #ifdef DEBUG - dbprintf("%s %s\n", "dispatch_f", fname); + debug_printf("%s %s\n", "dispatch_f", fname); #endif pid_t pid = fork(); if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process @@ -65,7 +65,7 @@ int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg){ // of course this will only work if our euid is root in the first place int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid){ #ifdef DEBUG - dbprintf("%s %s as euid:%u egid:%u\n", "dispatch_f_euid_egid", fname, euid, egid); + debug_printf("%s %s as euid:%u egid:%u\n", "dispatch_f_euid_egid", fname, euid, egid); #endif pid_t pid = fork(); if( pid == -1 ) return ERR_DISPATCH_F_FORK; @@ -94,13 +94,13 @@ int dispatch_exec(char **argv, char **envp){ { if( !argv || !argv[0] ) return ERR_DISPATCH_NULL_EXECUTABLE; #ifdef DEBUG - dbprintf("dispatch_exec:"); + debug_printf("dispatch_exec:"); char **apt = argv; while( *apt ){ - dbprintf(" %s",*apt); + debug_printf(" %s",*apt); apt++; } - dbprintf("\n"); + debug_printf("\n"); #endif command = argv[0]; } @@ -109,7 +109,7 @@ int dispatch_exec(char **argv, char **envp){ if( pid == 0 ){ // we are the child execvpe(command, argv, envp); // exec will only return if it has an error #ifdef DEBUG - dbprintf("dispatch_exec: exec returned, perror message:"); + debug_printf("dispatch_exec: exec returned, perror message:"); perror("dispatch_exec"); // our only chance to print this message, as this is the child process #endif fflush(stdout); diff --git a/module/dispatch/makefile b/module/dispatch/makefile index 82d110d..ab3ffe5 100644 --- a/module/dispatch/makefile +++ b/module/dispatch/makefile @@ -35,6 +35,7 @@ dep: .PHONY: lib lib: $(MAKE) $@ + cp $(SRCDIR)/dispatch.lib.h $(INCDIR)/dispatch.h %:: $(MAKE) $@ diff --git a/module/dispatch/trc/dispatch.trc.c b/module/dispatch/trc/dispatch.trc.c index 24d7cd3..c24b0ab 100644 --- a/module/dispatch/trc/dispatch.trc.c +++ b/module/dispatch/trc/dispatch.trc.c @@ -1,36 +1,35 @@ #tranche dispatch.lib.c #tranche dispatch.lib.h -/* - Runs a command or function as its own process. + /* + Runs a command or function as its own process. - The return status integer from command or function must be greater than ERR_DISPATCH. - In the case of dispatch_exec, we only have a promise from the user to not dispatch - non compliant commands. + The return status integer from command or function must be greater than ERR_DISPATCH. + In the case of dispatch_exec, we only have a promise from the user to not dispatch + non compliant commands. -*/ -#ifndef DISPATCH_LIB_H -#define DISPATCH_LIB_H -#include -#include + */ + #ifndef DISPATCH_LIB_H + #define DISPATCH_LIB_H + #include + #include -#define ERR_DISPATCH -1024 -#define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024 -#define ERR_DISPATCH_F_FORK -1025 -#define ERR_DISPATCH_F_SETEUID -1026 -#define ERR_DISPATCH_F_SETEGID -1027 -#define ERR_DISPATCH_NULL_EXECUTABLE -1028 -#define ERR_DISPATCH_EXEC -1029 + #define ERR_DISPATCH -1024 + #define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024 + #define ERR_DISPATCH_F_FORK -1025 + #define ERR_DISPATCH_F_SETEUID -1026 + #define ERR_DISPATCH_F_SETEGID -1027 + #define ERR_DISPATCH_NULL_EXECUTABLE -1028 + #define ERR_DISPATCH_EXEC -1029 -// currently both dispatcher and dispatchee strings are statically allocated -struct dispatch_ctx{ - char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.) - char *dispatchee; // name of the function being dispatched - int err; // error code as listed below, or status returned from dispatchee -}; + // currently both dispatcher and dispatchee strings are statically allocated + struct dispatch_ctx{ + char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.) + char *dispatchee; // name of the function being dispatched + int err; // error code as listed below, or status returned from dispatchee + }; #tranche-end -#include "dispatch.lib.h" // we need the declaration for uid_t etc. // without this #define execvpe is undefined @@ -40,6 +39,8 @@ struct dispatch_ctx{ #include #include #include +#include +#include "dispatch.lib.h" #tranche dispatch.lib.h void dispatch_f_mess(char *fname, int err, char *dispatchee); @@ -81,7 +82,7 @@ int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg); #tranche-end int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg){ #ifdef DEBUG - dbprintf("%s %s\n", "dispatch_f", fname); + debug_printf("%s %s\n", "dispatch_f", fname); #endif pid_t pid = fork(); if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process @@ -104,7 +105,7 @@ int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t eu #tranche-end int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid){ #ifdef DEBUG - dbprintf("%s %s as euid:%u egid:%u\n", "dispatch_f_euid_egid", fname, euid, egid); + debug_printf("%s %s as euid:%u egid:%u\n", "dispatch_f_euid_egid", fname, euid, egid); #endif pid_t pid = fork(); if( pid == -1 ) return ERR_DISPATCH_F_FORK; @@ -136,13 +137,13 @@ int dispatch_exec(char **argv, char **envp){ { if( !argv || !argv[0] ) return ERR_DISPATCH_NULL_EXECUTABLE; #ifdef DEBUG - dbprintf("dispatch_exec:"); + debug_printf("dispatch_exec:"); char **apt = argv; while( *apt ){ - dbprintf(" %s",*apt); + debug_printf(" %s",*apt); apt++; } - dbprintf("\n"); + debug_printf("\n"); #endif command = argv[0]; } @@ -151,7 +152,7 @@ int dispatch_exec(char **argv, char **envp){ if( pid == 0 ){ // we are the child execvpe(command, argv, envp); // exec will only return if it has an error #ifdef DEBUG - dbprintf("dispatch_exec: exec returned, perror message:"); + debug_printf("dispatch_exec: exec returned, perror message:"); perror("dispatch_exec"); // our only chance to print this message, as this is the child process #endif fflush(stdout); diff --git a/module/share/include/db.h b/module/share/include/db.h index 7563eea..f1be3d8 100644 --- a/module/share/include/db.h +++ b/module/share/include/db.h @@ -1,6 +1,6 @@ #ifndef DB_LIB_H #define DB_LIB_H -int dbprintf(const char *format, ...); +int debug_printf(const char *format, ...); #endif diff --git a/module/share/include/dispatch.h b/module/share/include/dispatch.h new file mode 100644 index 0000000..8b99d43 --- /dev/null +++ b/module/share/include/dispatch.h @@ -0,0 +1,32 @@ + /* + Runs a command or function as its own process. + + The return status integer from command or function must be greater than ERR_DISPATCH. + In the case of dispatch_exec, we only have a promise from the user to not dispatch + non compliant commands. + + */ + #ifndef DISPATCH_LIB_H + #define DISPATCH_LIB_H + #include + #include + + #define ERR_DISPATCH -1024 + #define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024 + #define ERR_DISPATCH_F_FORK -1025 + #define ERR_DISPATCH_F_SETEUID -1026 + #define ERR_DISPATCH_F_SETEGID -1027 + #define ERR_DISPATCH_NULL_EXECUTABLE -1028 + #define ERR_DISPATCH_EXEC -1029 + + // currently both dispatcher and dispatchee strings are statically allocated + struct dispatch_ctx{ + char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.) + char *dispatchee; // name of the function being dispatched + int err; // error code as listed below, or status returned from dispatchee + }; +void dispatch_f_mess(char *fname, int err, char *dispatchee); +int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg); +int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid); +int dispatch_exec(char **argv, char **envp); +#endif diff --git a/module/share/lib/libda.a b/module/share/lib/libda.a deleted file mode 100644 index c6e819f..0000000 Binary files a/module/share/lib/libda.a and /dev/null differ diff --git a/module/share/lib/libdb.a b/module/share/lib/libdb.a deleted file mode 100644 index c40204a..0000000 Binary files a/module/share/lib/libdb.a and /dev/null differ diff --git a/module/share/lib/libtranche.a b/module/share/lib/libtranche.a deleted file mode 100644 index 3e540aa..0000000 Binary files a/module/share/lib/libtranche.a and /dev/null differ diff --git a/module/subu-0/0_makefile b/module/subu-0/0_makefile deleted file mode 100644 index f0708ef..0000000 --- a/module/subu-0/0_makefile +++ /dev/null @@ -1,40 +0,0 @@ -# src/0_makefile - -SHELL=/bin/bash - --include 0_makefile_flags - -SUID_TOOL=$(TOOLSDIR)/bin/setuid_root.sh -MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tools/lib/makefile-cc - -SOURCES=$(wildcard *.c) -HFILES=$(wildcard *.h) - -all: version deps lib execs - -version: - $(MAKE) $@ - @echo "SUID_TOOL: " $(SUID_TOOL) - -deps: - makeheaders $(SOURCES) $(HFILES) - sed -i '/^ *int *main *(.*)/d' *.h - $(MAKE) $@ - -execs: - $(MAKE) $@ - @echo "-> $(SUID_TOOL) $(EXECSDIR)/subu-mk-0 $(EXECSDIR)/subu-rm-0 $(EXECSDIR)/subu-bind-all" - cat $(SUID_TOOL) - @echo -n "Are you sure? [y/N] " && read ans && [ $${ans:-N} == y ] - sudo $(SUID_TOOL) $(EXECSDIR)/subu-mk-0 $(EXECSDIR)/subu-rm-0 $(EXECSDIR)/subu-bind-all - -clean: - $(MAKE) $@ - for i in $(HFILES); do rm $$i; done - -%:: - $(MAKE) $@ - - - - diff --git a/module/subu-0/0_makefile-flags b/module/subu-0/0_makefile-flags deleted file mode 100644 index d4df01f..0000000 --- a/module/subu-0/0_makefile-flags +++ /dev/null @@ -1,31 +0,0 @@ - -# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo .. -ECHO= echo -#ECHO= echo -e - -# directories used by this makefile, these could all be set to dot for -# the simplest source directory structure - -#LIDBIR, EXECSDIR, HDIR hold the make results that might later be shared -#$(PWD) is the directory that make was called from, this is already build in -#set to dot to use the same directory as the source code -#leave blank to ommit -DEPRDIR=1_deprecated -DOCDIR=1_doc -EXECSDIR=1_execs -HDIR=1_headers -LIBDIR=1_lib -TESTDIR=1_tests -TMPDIR=1_tmp -TOOLSDIR=$(realpath $(PROJECT_SUBU)/tools) -TRYDIR=1_try - - -# compiler and flags -CC=gcc -CFLAGS=-std=gnu11 -fPIC -I. -ggdb -Werror -DDEBUG -DDEBUGDB -#CFLAGS=-std=gnu11 -fPIC -I. -Werror -LINKFLAGS=-L1_lib -lsubu -lsqlite3 - -LIBFILE=$(LIBDIR)/libsubu.a - diff --git a/module/subu-0/1_deprecated/dispatch_exec.lib.c b/module/subu-0/1_deprecated/dispatch_exec.lib.c deleted file mode 100644 index 024bff8..0000000 --- a/module/subu-0/1_deprecated/dispatch_exec.lib.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - fork/execs/wait the command passed in argv[0]; - Returns -1 upon failure. - - The wstatus returned from wait() might be either the error returned by exec - when it failed, or the return value from the command. An arbitary command is - passed in, so we don't know what its return values might be. Consquently, we - have no way of multiplexing a unique exec error code with the command return - value within wstatus. If the prorgrammer knows the return values of the - command passed in, and wants better behavior, he or she can spin a special - version of dispatch for that command. -*/ -#include "dispatch_exec.lib.h" - -// without this #define execvpe is undefined -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include - - - -int dispatch_exec(char **argv, char **envp){ - if( !argv || !argv[0] ){ - fprintf(stderr, "argv[0] null. Null command passed into dispatch().\n"); - return -1; - } - #ifdef DEBUG - dbprintf("dispatching exec, args follow:\n"); - char **apt = argv; - while( *apt ){ - dbprintf("\t%s",*apt); - apt++; - } - dbprintf("\n"); - #endif - char *command = argv[0]; - pid_t pid = fork(); - if( pid == -1 ){ - fprintf(stderr, "fork() failed in dispatch().\n"); - return -1; - } - if( pid == 0 ){ // we are the child - execvpe(command, argv, envp); - // exec will only return if it has an error .. - perror(command); - return -1; - }else{ // we are the parent - int wstatus; - waitpid(pid, &wstatus, 0); - if(wstatus) - return -1; - else - return 0; - } -} diff --git a/module/subu-0/1_deprecated/dispatch_f.lib.c b/module/subu-0/1_deprecated/dispatch_f.lib.c deleted file mode 100644 index 5c199f5..0000000 --- a/module/subu-0/1_deprecated/dispatch_f.lib.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - Forks a new process and runs the a function in that new process. I.e. it 'spawns' a function. - - f must have the specified prototype. I.e. it accepts one void pointer and - returns a positive integer. (Negative integers are used for dispatch error codes.) - - dispatch_f_euid_egid changes to the new euid and egid before running the function. - - If the change to in euid/egid fails, the forked process exits with a negative status. - If the function has an error, it returns a positive status. A status of zero means - that all went well. - - Because f is running in a separate process, the return status is the only means - of communication going back to the calling process. - - -*/ -#define _GNU_SOURCE - -#include "dispatch_f.lib.h" -// we need the declaration for uid_t etc. -// without this #define execvpe is undefined -#define _GNU_SOURCE - -#include -#include -#include -#include - -#if INTERFACE -#include -#include -#endif - -//-------------------------------------------------------------------------------- -// dispatch_f_ctx class -// -#if INTERFACE -#define ERR_NEGATIVE_RETURN_STATUS -1 -#define ERR_DISPATCH_F_FORK -2 -#define ERR_DISPATCH_F_SETEUID -3 -#define ERR_DISPATCH_F_SETEGID -4 - -// both name and fname are static allocations -struct dispatch_f_ctx{ - char *dispatcher; // name of the dispatch function (currently "dispatch_f" or "dispatch_f_euid_egid") - char *dispatchee; // name of the function being dispatched - int err; - int status; // return value from the function -}; -#endif -dispatch_f_ctx *dispatch_f_ctx_mk(char *name, char *fname){ - dispatch_f_ctx *ctxp = malloc(sizeof(dispatch_f_ctx)); - ctxp->dispatcher = name; - ctxp->dispatchee = fname; - ctxp->err = 0; - return ctxp; -} -void dispatch_f_ctx_free(dispatch_f_ctx *ctxp){ - // no dynamic variables to be freed in ctx - free(ctxp); -} -void dispatch_f_mess(struct dispatch_f_ctx *ctxp){ - if(ctxp->err == 0) return; - switch(ctxp->err){ - case ERR_NEGATIVE_RETURN_STATUS: - fprintf(stderr, "%s, function \"%s\" broke contract with a negative return value.", ctxp->dispatcher, ctxp->dispatchee); - break; - case ERR_DISPATCH_F_FORK: - case ERR_DISPATCH_F_SETEUID: - case ERR_DISPATCH_F_SETEGID: - fprintf(stderr, "%s, ", ctxp->dispatcher); - perror(ctxp->dispatcher); - break; - } - fputc('\n', stderr); -} - -//-------------------------------------------------------------------------------- -// interface call point -dispatch_f_ctx *dispatch_f(char *fname, int (*f)(void *arg), void *f_arg){ - dispatch_f_ctx *ctxp = dispatch_f_ctx_mk("dispatch_f", fname); - #ifdef DEBUG - dbprintf("%s %s\n", ctxp->dispatcher, ctxp->dispatchee); - #endif - pid_t pid = fork(); - if( pid == -1 ){ - ctxp->err = ERR_DISPATCH_F_FORK; // we are still in the parent process - return ctxp; - } - if( pid == 0 ){ // we are the child - int status = (*f)(f_arg); // we require that f return a zero or positive value - if( status < 0 ) status = ERR_NEGATIVE_RETURN_STATUS; - exit(status); - }else{ // we are the parent - waitpid(pid, &(ctxp->status), 0); - return ctxp; - } -} - -//-------------------------------------------------------------------------------- -// interface call point -dispatch_f_ctx *dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid){ - dispatch_f_ctx *ctxp = dispatch_f_ctx_mk("dispatch_f_euid_egid", fname); - #ifdef DEBUG - dbprintf("%s %s as euid:%u egid:%u\n", ctxp->dispatcher, ctxp->dispatchee, euid, egid); - #endif - pid_t pid = fork(); - if( pid == -1 ){ - ctxp->err = ERR_DISPATCH_F_FORK; - return ctxp; - } - if( pid == 0 ){ // we are the child - int status; - if( seteuid(euid) == -1 ) - status = ERR_DISPATCH_F_SETEUID; - else if( setegid(egid) == -1 ) - status = ERR_DISPATCH_F_SETEGID; - else{ - status = (*f)(f_arg); - if( status < 0 ) status = ERR_NEGATIVE_RETURN_STATUS; - exit(status); - } - }else{ // we are the parent - waitpid(pid, &(ctxp->status), 0); - return ctxp; - } -} - - diff --git a/module/subu-0/1_deprecated/dispatch_useradd.lib.c b/module/subu-0/1_deprecated/dispatch_useradd.lib.c deleted file mode 100644 index 7b75291..0000000 --- a/module/subu-0/1_deprecated/dispatch_useradd.lib.c +++ /dev/null @@ -1,68 +0,0 @@ -/* -There is no C library interface to useradd(8), but if there were, this function -would be found there instead. - -*/ -#include "dispatch_useradd.lib.h" - -#include -#include -#include -#include -#include - -#if INTERFACE -#include -#include -#define ERR_DISPATCH_USERADD_ARGC 1 -#define ERR_DISPATCH_USERADD_DISPATCH 2 -#define ERR_DISPATCH_USERADD_PWREC 3 -struct dispatch_useradd_ret_t{ - uint error; - struct passwd *pw_record; -}; -#endif - - -// we have a contract with the caller that argv[1] is always the subuname -struct dispatch_useradd_ret_t dispatch_useradd(char **argv, char **envp){ - struct dispatch_useradd_ret_t ret; - { - if( !argv || !argv[0] || !argv[1]){ - fprintf(stderr,"useradd() needs a first argument as the name of the user to be made"); - ret.error = ERR_DISPATCH_USERADD_ARGC; - ret.pw_record = NULL; - return ret; - } - - char *subu_name; - { - subu_name = argv[1]; - if( dispatch_exec(argv, envp) == -1 ){ - fprintf(stderr,"%s failed\n", argv[0]); - ret.error = ERR_DISPATCH_USERADD_DISPATCH; - ret.pw_record = NULL; - return ret; - }} - - { - struct passwd *pw_record = getpwnam(subu_name); - uint count = 1; - while( !pw_record && count <= 3 ){ - #ifdef DEBUG - printf("try %u, getpwnam failed, trying again\n", count); - #endif - sleep(1); - pw_record = getpwnam(subu_name); - count++; - } - if( !pw_record ){ - ret.error = ERR_DISPATCH_USERADD_PWREC; - ret.pw_record = NULL; - return ret; - } - ret.error = 0; - ret.pw_record = pw_record; - return ret; - }}} - diff --git a/module/subu-0/1_deprecated/subu-rm-0.lib.c b/module/subu-0/1_deprecated/subu-rm-0.lib.c deleted file mode 100644 index ccad437..0000000 --- a/module/subu-0/1_deprecated/subu-rm-0.lib.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - subu-rm-0 subuname - - 1. get our uid and lookup masteru_name in /etc/passwd - 2. lookup masteru_name/subuname in config file, which gives us subu_username - 3. unmount subuland/subuname - 4. userdel subu_username - 5. rmdir subuland/subuname - - Note, as per the man page, we are not allowed to free the memory allocated by getpwid(). - -*/ -#include "subu-mk-0.lib.h" - -// without this #define we get the warning: implicit declaration of function ‘seteuid’/‘setegid’ -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include - -#if INTERFACE -#include -#include -#include -#endif - -//-------------------------------------------------------------------------------- -// an instance is subu_rm_0_ctx is returned by subu_rm_0 -// -#if INTERFACE -#define ERR_SUBU_RM_0_MKDIR_SUBUHOME 1 -#define ERR_SUBU_RM_0_RMDIR_SUBUHOME 2 -#define ERR_SUBU_RM_0_SUBUNAME_MALFORMED 3 -#define ERR_SUBU_RM_0_SETUID_ROOT 4 -#define ERR_SUBU_RM_0_MASTERU_HOMELESS 5 -#define ERR_SUBU_RM_0_MALLOC 6 -#define ERR_SUBU_RM_0_CONFIG_FILE 7 -#define ERR_SUBU_RM_0_SUBUHOME_EXISTS 8 -#define ERR_SUBU_RM_0_BUG_SSS 9 -#define ERR_SUBU_RM_0_FAILED_USERADD 10 - -struct subu_rm_0_ctx{ - char *name; - char *subuland; - char *subuhome; - char *subu_username; - bool free_aux; - char *aux; - uint err; -}; -#endif -struct subu_rm_0_ctx *subu_rm_0_ctx_mk(){ - struct subu_rm_0_ctx *ctxp = malloc(sizeof(struct subu_rm_0_ctx)); - ctxp->name = "subu_rm_0"; - ctxp->subuland = 0; - ctxp->subuhome = 0; - ctxp->subu_username = 0; - ctxp->free_aux = false; - ctxp->aux = 0; -} -void subu_rm_0_ctx_free(struct subu_rm_0_ctx *ctxp){ - free(ctxp->subuland); - free(ctxp->subuhome); - free(ctxp->subu_username); - if(ctxp->free_aux) free(ctxp->aux); - free(ctxp); -} -// must be called before any system calls, otherwise perror() will be messed up -void subu_rm_0_mess(struct subu_rm_0_ctx *ctxp){ - switch(ctxp->err){ - case 0: return; - case ERR_SUBU_RM_0_MKDIR_SUBUHOME: - fprintf(stderr, "masteru could not make subuhome, \"%s\"", ctxp->subuhome); - break; - case ERR_SUBU_RM_0_SUBUNAME_MALFORMED: - fprintf(stderr, "subuname, \"%s\" is not in [ _.-a-zA-Z0-9]*", ctxp->aux); - break; - case ERR_SUBU_RM_0_SETUID_ROOT: - fprintf(stderr, "This program must be run setuid root from a user account."); - break; - case ERR_SUBU_RM_0_MASTERU_HOMELESS: - fprintf(stderr,"Masteru, \"%s\", has no home directory", ctxp->aux); - break; - case ERR_SUBU_RM_0_MALLOC: - perror(ctxp->name); - break; - case ERR_SUBU_RM_0_CONFIG_FILE: - fprintf(stderr, "config file error: %s", ctxp->aux); - break; - case ERR_SUBU_RM_0_SUBUHOME_EXISTS: - fprintf(stderr, "a file system object already exists at subuhome, \"%s\"\n", ctxp->subuhome); - break; - case ERR_SUBU_RM_0_BUG_SSS: - perror(ctxp->name); - break; - case ERR_SUBU_RM_0_FAILED_USERADD: - fprintf(stderr, "%u useradd failed\n", ctxp->subu_username); - break; - default: - fprintf(stderr, "unknown error code %d\n", ctxp->err); - } - fputc('\n', stderr); -} - -//-------------------------------------------------------------------------------- -// dispatched functions -// -// the making of subuhome is dispatched to its own process so as to give it its own uid/gid -static int masteru_mkdir_subuhome(void *arg){ - char *subuhome = (char *) arg; - if( mkdir( subuhome, subuhome_perms ) == -1 ){ // find subuhome perms in common - perror("masteru_mkdir_subuhome"); - return ERR_SUBU_RM_0_MKDIR_SUBUHOME; - } - return 0; -} -static int masteru_rmdir_subuhome(void *arg){ - char *subuhome = (char *) arg; - if( rmdir( subuhome ) == -1 ){ // find subuhome perms in common - perror("masteru_rmdir_subuhome"); - return ERR_SUBU_RM_0_RMDIR_SUBUHOME; - } - return 0; -} - -//-------------------------------------------------------------------------------- -// the public call point -struct subu_rm_0_ctx *subu_rm_0(sqlite3 *db, char *subuname){ - - struct subu_rm_0_ctx *ctxp = subu_rm_0_ctx_mk(); - - //-------------------------------------------------------------------------------- - #ifdef DEBUG - dbprintf("Checking that subuname is well formed and finding its length\n"); - #endif - size_t subuname_len; - { - int ret = allowed_subuname(subuname, &subuname_len); - if( ret == -1 ){ - ctxp->err = ERR_SUBU_RM_0_SUBUNAME_MALFORMED; - ctxp->aux = subuname; - return ctxp; - }} - - //-------------------------------------------------------------------------------- - #ifdef DEBUG - dbprintf("Checking that we are running from a user and are setuid root.\n"); - #endif - uid_t masteru_uid; - gid_t masteru_gid; - uid_t set_euid; - gid_t set_egid; - { - masteru_uid = getuid(); - masteru_gid = getgid(); - set_euid = geteuid(); - set_egid = getegid(); - #ifdef DEBUG - dbprintf("masteru_uid %u, masteru_gid %u, set_euid %u set_egid %u\n", masteru_uid, masteru_gid, set_euid, set_egid); - #endif - if( masteru_uid == 0 || set_euid != 0 ){ - ctxp->err = ERR_SUBU_RM_0_SETUID_ROOT; - return ctxp; - } - } - - //-------------------------------------------------------------------------------- - #ifdef DEBUG - dbprintf("strings masteru_name and masteru_home\n"); - #endif - - char *masteru_name; - size_t masteru_name_len; - char *masteru_home; - size_t masteru_home_len; - size_t subuland_len; - { - struct passwd *masteru_pw_record_pt = getpwuid(masteru_uid); // reading /etc/passwd - masteru_name = masteru_pw_record_pt->pw_name; - masteru_name_len = strlen(masteru_name); - #ifdef DEBUG - dbprintf("masteru_name \"%s\" %zu\n", masteru_name, masteru_name_len); - #endif - masteru_home = masteru_pw_record_pt->pw_dir; - masteru_home_len = strlen(masteru_home); - #ifdef DEBUG - dbprintf("masteru_home \"%s\" %zu\n", masteru_home, masteru_home_len); - #endif - masteru_home_len = strlen(masteru_home); - if( masteru_home_len == 0 || masteru_home[0] == '(' ){ - ctxp->err = ERR_SUBU_RM_0_MASTERU_HOMELESS; - ctxp->aux = masteru_name; // we can not free a passwd struct, or its fields. I assume then it isn't re-entrant safe. - return ctxp; - } - // char *subuland_extension = "/subuland/"; // moved to common.lib.c - size_t subuland_extension_len = strlen(subuland_extension); - ctxp->subuland = (char *)malloc( masteru_home_len + subuland_extension_len + 1 ); - if(!ctxp->subuland){ - ctxp->err = ERR_SUBU_RM_0_MALLOC; - return ctxp; - } - strcpy(ctxp->subuland, masteru_home); - strcpy(ctxp->subuland + masteru_home_len, subuland_extension); - subuland_len = masteru_home_len + subuland_extension_len; - #ifdef DEBUG - dbprintf("subuland \"%s\" %zu\n", ctxp->subuland, subuland_len); - #endif - } - - //-------------------------------------------------------------------------------- - #ifdef DEBUG - dbprintf("lookup subu_username from masteru_name/subuname in config file\n"); - #endif - char *subu_username; // this is part of ctx and must be freed - { - int ret = subu_get_masteru_subu(db, masteru_name, subuname, &subu_username); - if( ret != SQLITE_DONE ){ - printf("get failed\n"); - return 2; - } - #ifdef DEBUG - printf("subu_username: %s\n", subu_username); - #endif - - } - - //-------------------------------------------------------------------------------- - #ifdef DEBUG - dbprintf("strings subu_username and subuhome\n"); - #endif - size_t subu_username_len; - size_t subuhome_len; - { - char *ns=0; // 'ns' Number as String - char *mess=0; - if( subu_number_get( db, &ns, &mess ) != SQLITE_OK ){ - ctxp->err = ERR_SUBU_RM_0_CONFIG_FILE; - ctxp->aux = mess; - ctxp->free_aux = true; - return ctxp; - } - size_t ns_len = strlen(ns); - ctxp->subu_username = malloc(1 + ns_len + 1); - if( !ctxp->subu_username ){ - ctxp->err = ERR_SUBU_RM_0_MALLOC; - return ctxp; - } - strcpy(ctxp->subu_username, "s"); - strcpy(ctxp->subu_username + 1, ns); - subu_username_len = ns_len + 1; - #ifdef DEBUG - dbprintf("subu_username \"%s\" %zu\n", ctxp->subu_username, subu_username_len); - #endif - - subuhome_len = subuland_len + subuname_len; - ctxp->subuhome = (char *)malloc(subuhome_len + 1); - if( !ctxp->subuhome ){ - ctxp->err = ERR_SUBU_RM_0_MALLOC; - return ctxp; - } - strcpy (ctxp->subuhome, ctxp->subuland); - strcpy (ctxp->subuhome + subuland_len, subuname); - #ifdef DEBUG - dbprintf("subuhome \"%s\" %zu\n", ctxp->subuhome, subuhome_len); - #endif - } - - //-------------------------------------------------------------------------------- - // By having masteru create the subuhome, we know that masteru has rights to - // to access this directory. This will be the mount point for bindfs - { - #ifdef DEBUG - dbprintf("as masteru, making the directory \"%s\"\n", ctxp->subuhome); - #endif - struct stat st; - if( stat(ctxp->subuhome, &st) != -1 ){ - ctxp->err = ERR_SUBU_RM_0_SUBUHOME_EXISTS; - return ctxp; - } - dispatch_ctx *dfr = dispatch_f_euid_egid - ( - "masteru_mkdir_subuhome", - masteru_mkdir_subuhome, - (void *)ctxp->subuhome, - masteru_uid, - masteru_gid - ); - if( dfr->err <= ERR_DISPATCH || dfr->err == ERR_SUBU_RM_0_MKDIR_SUBUHOME ){ - #ifdef DEBUG - if( dfr->err == ERR_SUBU_RM_0_MKDIR_SUBUHOME ) - perror("mkdir"); - else - dispatch_f_mess(dfr); - #endif - ctxp->err = ERR_SUBU_RM_0_MKDIR_SUBUHOME; - return ctxp; - } - } - #ifdef DEBUG - dbprintf("masteru made directory \"%s\"\n", ctxp->subuhome); - #endif - - //-------------------------------------------------------------------------------- - // Make the subservient user account, i.e. the subu - { - #ifdef DEBUG - dbprintf("making subu \"%s\" as user \"%s\"\n", subuname, ctxp->subu_username); - #endif - #if BUG_SSS_CACHE_RUID - #ifdef DEBUG - dbprintf("setting inherited real uid to 0 to accomodate SSS_CACHE UID BUG\n"); - #endif - if( setuid(0) == -1 ){ - ctxp->err = ERR_SUBU_RM_0_BUG_SSS; - return ctxp; - } - #endif - char *command = "/usr/sbin/useradd"; - char *argv[3]; - argv[0] = command; - argv[1] = ctxp->subu_username; - argv[2] = (char *) NULL; - char *envp[1]; - envp[0] = (char *) NULL; - dispatch_ctx *dfr = dispatch_exec(argv, envp); - if( dfr->err != 0 ){ - #ifdef DEBUG - if( dfr->err <= ERR_DISPATCH ) - dispatch_f_mess(dfr); - else - perror("useradd"); - #endif - // go back and remove the directory we made in subuland - dispatch_ctx *dfr = dispatch_f_euid_egid - ( - "masteru_rmdir_subuhome", - masteru_rmdir_subuhome, - (void *)ctxp->subuhome, - masteru_uid, - masteru_gid - ); - #ifdef DEBUG - if( dfr->err <= ERR_DISPATCH || dfr->err == ERR_SUBU_RM_0_RMDIR_SUBUHOME ) - if( dfr->err == ERR_SUBU_RM_0_RMDIR_SUBUHOME ) - perror("rmdir"); - else - dispatch_f_mess(dfr); - #endif - ctxp->err = ERR_SUBU_RM_0_FAILED_USERADD; - return ctxp; - } - #ifdef DEBUG - dbprintf("added user \"%s\"\n", ctxp->subu_username); - #endif - } - - //-------------------------------------------------------------------------------- - #ifdef DEBUG - dbprintf("setting the masteru_name, subuname, subu_username relation\n"); - #endif - { - int ret = subu_put_masteru_subu(db, masteru_name, subuname, ctxp->subu_username); - if( ret != SQLITE_DONE ){ - ctxp->err = ERR_SUBU_RM_0_CONFIG_FILE; - ctxp->aux = "insert of masteru subu relation failed"; - return ctxp; - } - } - - #ifdef DEBUG - dbprintf("finished subu-mk-0(%s)\n", subuname); - #endif - ctxp->err = 0; - return ctxp; -} diff --git a/module/subu-0/1_deprecated/subudb-number-next.cli.c b/module/subu-0/1_deprecated/subudb-number-next.cli.c deleted file mode 100644 index 3373173..0000000 --- a/module/subu-0/1_deprecated/subudb-number-next.cli.c +++ /dev/null @@ -1,45 +0,0 @@ -/* -Set or get a new maximum subu number. Currently doesn't do the setting part. - -*/ -#include "subudb-number-next.cli.h" -#include -#include -#include - -int main(int argc, char **argv){ - - if( argc != 2 ){ - fprintf(stderr, "usage: %s masteru_name \n",argv[0]); - return SUBU_ERR_ARG_CNT; - } - char *masteru_name = argv[1]; - - int rc; - sqlite3 *db; - rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); - if( rc != SQLITE_OK ){ - sqlite3_close(db); - fprintf(stderr, "error exit, could not open db file\n"); - return SUBU_ERR_DB_FILE; - } - - // read and print the current max - char *mess; - int n; - rc = subudb_number_next(db, masteru_name, &n, &mess); - if( rc == SQLITE_DONE ){ - printf("%d\n", n); - }else{ - fprintf(stderr, "subudb_number_next indicates failure by returning %d\n",rc); - fprintf(stderr, "and issues message, %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - return SUBU_ERR_DB_FILE; - } - rc = sqlite3_close(db); - if( rc != SQLITE_OK ){ - fprintf(stderr, "when closing db, %s\n", sqlite3_errmsg(db)); - return SUBU_ERR_DB_FILE; - } - return 0; -} diff --git a/module/subu-0/1_doc/to_do.txt b/module/subu-0/1_doc/to_do.txt deleted file mode 100644 index 0b989cc..0000000 --- a/module/subu-0/1_doc/to_do.txt +++ /dev/null @@ -1,38 +0,0 @@ -2019-02-05T23:14:40Z - error can cause subu-mk-0 to leave the creating of a subu in an intermediate - state. Rather than bailing on some of the errors we need to clean up instead. - Perhaps the yet to be written subu-rm program will be resilent enough to do - more general cleanup. - -2019-02-23T18:56:31Z - need to modify subu-init to take a configuration file name argument instead of - using a global variabel value. might want to add arguments to other subu - commands also - -2019-03-11T13:48:03Z - in subu.lib.c append cascading rmdir failure mess to useradd failure mess - -2019-03-11T13:48:03Z - want to add subu-type to masteru_subu(), I imagine there will be static, - permanent, and temporary subu types. - -2019-03-12T18:35:06Z - the masteru subu relation should contain the uid of the masteru as - well as the backup type for the subu: git, rdiff, rsync, none. - and the persisitance fo the subu: indefinite, session. - seems that operations need to be logged, in case the db is lost - the transcript can be played back. It should also be possible - to co-opt an existing user as a subu, though, would require - sudo privs. - - need to add messages for subu errors I've added to the end of - the list in subu.lib.c - -2019-03-14T10:43:50Z - - should mod all to he subudb routines to return a message, probably - strdup(sqlite_errmsg(db)), then the callers to these routines can just pass - mess in rather than making up new ones for each situation. The error code - probably already carries the contexts specific message. Or perhaps add - a string cat function for message strings, that would run through a stream - and free the originals. diff --git a/module/subu-0/1_tests/0_makefile b/module/subu-0/1_tests/0_makefile deleted file mode 100644 index c16998b..0000000 --- a/module/subu-0/1_tests/0_makefile +++ /dev/null @@ -1,32 +0,0 @@ -# src/1_tests/0_makefile - -SHELL=/bin/bash - --include 0_makefile_flags - -MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tools/lib/makefile-cc - -SOURCES=$(wildcard *.c) -HFILES=$(wildcard *.h) - -all: version deps lib execs - -deps: - makeheaders $(SOURCES) $(HFILES) - sed -i '/^ *int *main *(.*)/d' *.h - $(MAKE) $@ - -clean: - $(MAKE) $@ - for i in $(HFILES); do rm $$i; done - -dist-clean: - $(MAKE) $@ - if [ -f subudb ]; then rm subudb; fi - -%:: - $(MAKE) $@ - - - - diff --git a/module/subu-0/1_tests/0_makefile_flags b/module/subu-0/1_tests/0_makefile_flags deleted file mode 100644 index bc6bd25..0000000 --- a/module/subu-0/1_tests/0_makefile_flags +++ /dev/null @@ -1,31 +0,0 @@ - -# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo .. -ECHO= echo -#ECHO= echo -e - -# directories used by this makefile, these could all be set to dot for -# the simplest source directory structure - -#LIDBIR, EXECSDIR, HDIR hold the make results that might later be shared -#$(PWD) is the directory that make was called from, this is already build in -#set to dot to use the same directory as the source code -#leave blank to ommit -DEPRDIR= -DOCDIR= -EXECSDIR=. -HDIR=. -LIBDIR=. -TESTDIR=. -TMPDIR=1_tmp -TOOLSDIR=$(realpath $(PROJECT_SUBU)/tools) -TRYDIR= - - -# compiler and flags -CC=gcc -CFLAGS=-std=gnu11 -fPIC -I. -ggdb -Werror -DDEBUG -DDEBUGDB -#CFLAGS=-std=gnu11 -fPIC -I. -Werror -LINKFLAGS=-L$(PROJECT_SUBU)/src/$(LIBDIR) -L. -lsubu -lsqlite3 -lsubutests - -LIBFILE=$(LIBDIR)/libtests.a - diff --git a/module/subu-0/1_tests/1_tmp/makefile_deps b/module/subu-0/1_tests/1_tmp/makefile_deps deleted file mode 100644 index 9486ae8..0000000 --- a/module/subu-0/1_tests/1_tmp/makefile_deps +++ /dev/null @@ -1,4 +0,0 @@ -da.cli.o: da.cli.c da.cli.h - -./da : da.cli.o ./libtests.a - gcc -o ./da da.cli.o -L/home/morpheus/subu_land/subu/src/. -L. -lsubu -lsqlite3 -lsubutests diff --git a/module/subu-0/1_tests/da.cli.c b/module/subu-0/1_tests/da.cli.c deleted file mode 100644 index 910a15e..0000000 --- a/module/subu-0/1_tests/da.cli.c +++ /dev/null @@ -1,50 +0,0 @@ -/* -Tests for da. - -*/ - -#include -#include - -int test_da_0(){ - da da0; - da_alloc(&da0, sizeof(int)); // leaves room for 4 ints - int i = 0; - int *pt = da0->base; - // will double, 4 -> 8, then double 8 -> 16 - while( i < 10 ){ - if(da_boundq(&da0, pt)){ - char *old_base = da_expand(&da); - da_rebase(&da, old_base, pt); - } - *pt = i; - i++; - pt++; - } - - bool f0 = da.size == sizof(int) * 16; - bool f1 = 10 == (da.end - da.base) / sizeof(int); - bool f2 = true; - pt = da0->base; - while( i < 10 ){ - f2 = f2 && *pt == i && !da_endq(&da, pt); - i++; - pt++; - } - bool f3 = da_endq(&da, pt); - - return f0 && f1 && f2 && f3; -} - - -int main(){ - - bool da_0_passed = test_da_0(); - if( da_0_passed ){ - printf("da_0_passed"); - return 0; - } - printf("da_0_failed"); - return 1; - -} diff --git a/module/subu-0/1_tests/libtests.a b/module/subu-0/1_tests/libtests.a deleted file mode 100644 index 8b277f0..0000000 --- a/module/subu-0/1_tests/libtests.a +++ /dev/null @@ -1 +0,0 @@ -! diff --git a/module/subu-0/1_tmp/da.lib.h b/module/subu-0/1_tmp/da.lib.h deleted file mode 100644 index 4702189..0000000 --- a/module/subu-0/1_tmp/da.lib.h +++ /dev/null @@ -1,23 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -#include -void daps_map(char **base,char **end_pt,void f(void *)); -#define RETURN(rc) \ - { daps_map(mrs, mrs_end, free); return rc; } -void daps_alloc(char ***base,size_t *s); -#define MK_MRS \ - char **mrs; \ - char **mrs_end; \ - size_t mrs_size; \ - daps_alloc(&mrs, &mrs_size);\ - mrs_end = mrs; -void daps_push(char ***base,char ***pt,size_t *s,char *item); -bool daps_bound(char **base,char **pt,size_t s); -void daps_expand(char ***base,char ***pt,size_t *s); -void da_map(void *base,void *end_pt,void f(void *),size_t item_size); -void da_push(void **base,void **pt,size_t *s,void *item,size_t item_size); -bool da_bound(void *base,void *pt,size_t s); -void da_expand(void **base,void **pt,size_t *s); -void da_alloc(void **base,size_t *s,size_t item_size); -#define INTERFACE 0 diff --git a/module/subu-0/1_tmp/dbprintf.lib.h b/module/subu-0/1_tmp/dbprintf.lib.h deleted file mode 100644 index 3056cf6..0000000 --- a/module/subu-0/1_tmp/dbprintf.lib.h +++ /dev/null @@ -1,3 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -int dbprintf(const char *format,...); diff --git a/module/subu-0/1_tmp/dispatch.lib.h b/module/subu-0/1_tmp/dispatch.lib.h deleted file mode 100644 index 07e2271..0000000 --- a/module/subu-0/1_tmp/dispatch.lib.h +++ /dev/null @@ -1,24 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -#include -int dispatch_exec(char **argv,char **envp); -typedef unsigned int uint; -int dispatch_f_euid_egid(char *fname,int(*f)(void *arg),void *f_arg,uid_t euid,gid_t egid); -int dbprintf(const char *format,...); -int dispatch_f(char *fname,int(*f)(void *arg),void *f_arg); -void dispatch_f_mess(char *fname,int err,char *dispatchee); -#define ERR_DISPATCH_EXEC -1029 -#define ERR_DISPATCH_NULL_EXECUTABLE -1028 -#define ERR_DISPATCH_F_SETEGID -1027 -#define ERR_DISPATCH_F_SETEUID -1026 -#define ERR_DISPATCH_F_FORK -1025 -#define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024 -#define ERR_DISPATCH -1024 -typedef struct dispatch_ctx dispatch_ctx; -struct dispatch_ctx { - char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.) - char *dispatchee; // name of the function being dispatched - int err; // error code as listed below, or status returned from dispatchee -}; -#define INTERFACE 0 diff --git a/module/subu-0/1_tmp/subu-bind-all.cli.h b/module/subu-0/1_tmp/subu-bind-all.cli.h deleted file mode 100644 index 7e52675..0000000 --- a/module/subu-0/1_tmp/subu-bind-all.cli.h +++ /dev/null @@ -1,9 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -#include -#include -int subu_bind_all(char **mess,sqlite3 *db); -#define SUBU_ERR_DB_FILE 8 -extern char DB_File[]; -#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/1_tmp/subu-bind.cli.h b/module/subu-0/1_tmp/subu-bind.cli.h deleted file mode 100644 index af12d61..0000000 --- a/module/subu-0/1_tmp/subu-bind.cli.h +++ /dev/null @@ -1,7 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -#include -#include -int subu_bind(char **mess,char *masteru_name,char *subu_username,char *subuhome); -#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/1_tmp/subu-common.lib.h b/module/subu-0/1_tmp/subu-common.lib.h deleted file mode 100644 index cfdc520..0000000 --- a/module/subu-0/1_tmp/subu-common.lib.h +++ /dev/null @@ -1,9 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -extern char Subuland_Extension[]; -typedef unsigned int uint; -extern uint First_Max_Subunumber; -extern uint Subuhome_Perms; -extern char DB_File[]; -#define BUG_SSS_CACHE_RUID 1 -#define INTERFACE 0 diff --git a/module/subu-0/1_tmp/subu-mk-0.cli.h b/module/subu-0/1_tmp/subu-mk-0.cli.h deleted file mode 100644 index 487b509..0000000 --- a/module/subu-0/1_tmp/subu-mk-0.cli.h +++ /dev/null @@ -1,10 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -#include -#include -void subu_err(char *fname,int err,char *mess); -int subu_mk_0(char **mess,sqlite3 *db,char *subuname); -#define SUBU_ERR_DB_FILE 8 -extern char DB_File[]; -#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/1_tmp/subu-rm-0.cli.h b/module/subu-0/1_tmp/subu-rm-0.cli.h deleted file mode 100644 index 070bfe8..0000000 --- a/module/subu-0/1_tmp/subu-rm-0.cli.h +++ /dev/null @@ -1,10 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -#include -#include -void subu_err(char *fname,int err,char *mess); -int subu_rm_0(char **mess,sqlite3 *db,char *subuname); -#define SUBU_ERR_DB_FILE 8 -extern char DB_File[]; -#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/1_tmp/subu.lib.h b/module/subu-0/1_tmp/subu.lib.h deleted file mode 100644 index 69c5da7..0000000 --- a/module/subu-0/1_tmp/subu.lib.h +++ /dev/null @@ -1,66 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -typedef unsigned int uint; -#include -typedef struct subudb_subu_element subudb_subu_element; -int subudb_Masteru_Subu_get_subus(sqlite3 *db,char *masteru_name,subudb_subu_element **sa_pt,subudb_subu_element **sa_end_pt); -struct subudb_subu_element { - char *subuname; - char *subu_username; -}; -#include -#include -int subu_bind_all(char **mess,sqlite3 *db); -int subu_bind(char **mess,char *masteru_name,char *subu_username,char *subuhome); -int subudb_Masteru_Subu_rm(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -int subudb_Masteru_Subu_get_subu_username(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username); -int subu_rm_0(char **mess,sqlite3 *db,char *subuname); -int subudb_Masteru_Subu_put(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -#include -#include -int dispatch_exec(char **argv,char **envp); -#define BUG_SSS_CACHE_RUID 1 -void dispatch_f_mess(char *fname,int err,char *dispatchee); -#define ERR_DISPATCH -1024 -int dispatch_f_euid_egid(char *fname,int(*f)(void *arg),void *f_arg,uid_t euid,gid_t egid); -#include -void daps_map(char **base,char **end_pt,void f(void *)); -#define RETURN(rc) \ - { daps_map(mrs, mrs_end, free); return rc; } -void daps_push(char ***base,char ***pt,size_t *s,char *item); -int dbprintf(const char *format,...); -void daps_alloc(char ***base,size_t *s); -#define MK_MRS \ - char **mrs; \ - char **mrs_end; \ - size_t mrs_size; \ - daps_alloc(&mrs, &mrs_size);\ - mrs_end = mrs; -int subu_mk_0(char **mess,sqlite3 *db,char *subuname); -extern char Subuland_Extension[]; -int db_commit(sqlite3 *db); -int db_rollback(sqlite3 *db); -int subudb_number_set(sqlite3 *db,int n); -int subudb_number_get(sqlite3 *db,int *n); -int db_begin(sqlite3 *db); -extern uint Subuhome_Perms; -extern char DB_File[]; -void subu_err(char *fname,int err,char *mess); -#define SUBU_ERR_BIND 15 -#define SUBU_ERR_N 14 -#define SUBU_ERR_SUBU_NOT_FOUND 13 -#define SUBU_ERR_FAILED_USERDEL 12 -#define SUBU_ERR_FAILED_USERADD 11 -#define SUBU_ERR_BUG_SSS 10 -#define SUBU_ERR_SUBUHOME_EXISTS 9 -#define SUBU_ERR_DB_FILE 8 -#define SUBU_ERR_HOMELESS 7 -#define SUBU_ERR_SUBUNAME_MALFORMED 6 -#define SUBU_ERR_RMDIR_SUBUHOME 5 -#define SUBU_ERR_MKDIR_SUBUHOME 4 -#define SUBU_ERR_MALLOC 3 -#define SUBU_ERR_SETUID_ROOT 2 -#define SUBU_ERR_ARG_CNT 1 -char *userdel_mess(int err); -char *useradd_mess(int err); -#define INTERFACE 0 diff --git a/module/subu-0/1_tmp/subudb-init.cli.h b/module/subu-0/1_tmp/subudb-init.cli.h deleted file mode 100644 index 4435103..0000000 --- a/module/subu-0/1_tmp/subudb-init.cli.h +++ /dev/null @@ -1,11 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int db_commit(sqlite3 *db); -int db_rollback(sqlite3 *db); -int subudb_schema(sqlite3 *db); -int db_begin(sqlite3 *db); -#include -#include -#define SUBU_ERR_DB_FILE 8 -extern char DB_File[]; diff --git a/module/subu-0/1_tmp/subudb-number.cli.h b/module/subu-0/1_tmp/subudb-number.cli.h deleted file mode 100644 index c130fbb..0000000 --- a/module/subu-0/1_tmp/subudb-number.cli.h +++ /dev/null @@ -1,11 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subudb_number_get(sqlite3 *db,int *n); -int subudb_number_set(sqlite3 *db,int n); -#include -#include -#define SUBU_ERR_N 14 -#define SUBU_ERR_DB_FILE 8 -extern char DB_File[]; -#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/1_tmp/subudb-rel-get.cli.h b/module/subu-0/1_tmp/subudb-rel-get.cli.h deleted file mode 100644 index 4f335be..0000000 --- a/module/subu-0/1_tmp/subudb-rel-get.cli.h +++ /dev/null @@ -1,9 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subudb_Masteru_Subu_get_subu_username(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username); -#include -#include -#define SUBU_ERR_DB_FILE 8 -extern char DB_File[]; -#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/1_tmp/subudb-rel-put.cli.h b/module/subu-0/1_tmp/subudb-rel-put.cli.h deleted file mode 100644 index 243b3a9..0000000 --- a/module/subu-0/1_tmp/subudb-rel-put.cli.h +++ /dev/null @@ -1,8 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subudb_Masteru_Subu_put(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -#include -#include -#define SUBU_ERR_DB_FILE 8 -extern char DB_File[]; diff --git a/module/subu-0/1_tmp/subudb-rel-rm.cli.h b/module/subu-0/1_tmp/subudb-rel-rm.cli.h deleted file mode 100644 index 595427f..0000000 --- a/module/subu-0/1_tmp/subudb-rel-rm.cli.h +++ /dev/null @@ -1,8 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subudb_Masteru_Subu_rm(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -#include -#include -#define SUBU_ERR_DB_FILE 8 -extern char DB_File[]; diff --git a/module/subu-0/1_tmp/subudb-subus.cli.h b/module/subu-0/1_tmp/subudb-subus.cli.h deleted file mode 100644 index 16310b7..0000000 --- a/module/subu-0/1_tmp/subudb-subus.cli.h +++ /dev/null @@ -1,14 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -typedef struct subudb_subu_element subudb_subu_element; -int subudb_Masteru_Subu_get_subus(sqlite3 *db,char *masteru_name,subudb_subu_element **sa_pt,subudb_subu_element **sa_end_pt); -struct subudb_subu_element { - char *subuname; - char *subu_username; -}; -#include -#include -#define SUBU_ERR_DB_FILE 8 -extern char DB_File[]; -#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/1_tmp/subudb.lib.h b/module/subu-0/1_tmp/subudb.lib.h deleted file mode 100644 index be73823..0000000 --- a/module/subu-0/1_tmp/subudb.lib.h +++ /dev/null @@ -1,27 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subudb_Masteru_Subu_rm(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -#include -#include -void da_expand(void **base,void **pt,size_t *s); -bool da_bound(void *base,void *pt,size_t s); -typedef struct subudb_subu_element subudb_subu_element; -int subudb_Masteru_Subu_get_subus(sqlite3 *db,char *masteru_name,subudb_subu_element **sa_pt,subudb_subu_element **sa_end_pt); -void subu_element_free(subudb_subu_element *base,subudb_subu_element *end_pt); -void da_alloc(void **base,size_t *s,size_t item_size); -struct subudb_subu_element { - char *subuname; - char *subu_username; -}; -int subudb_Masteru_Subu_get_subu_username(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username); -int subudb_Masteru_Subu_put(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -int subudb_number_set(sqlite3 *db,int n); -int subudb_number_get(sqlite3 *db,int *n); -typedef unsigned int uint; -extern uint First_Max_Subunumber; -int subudb_schema(sqlite3 *db); -int db_rollback(sqlite3 *db); -int db_commit(sqlite3 *db); -int db_begin(sqlite3 *db); -#define INTERFACE 0 diff --git a/module/subu-0/1_try/split.c b/module/subu-0/1_try/split.c deleted file mode 100644 index 6d4c6ac..0000000 --- a/module/subu-0/1_try/split.c +++ /dev/null @@ -1,20 +0,0 @@ -/* -Using preprocessor to make header file? - -gcc -E split.c -DPROTOTYPE - -Outputs source code source comment lines starting with a hash. Resolves all macro commands, -hence the resulting header can not have macro commands. - - */ - -#if PROTOTYPE -##define GREATNESS 21 -int f(int x); -#endif - -#if IMPLEMENTATION -int f(int x){ - return x; -} -#endif diff --git a/module/subu-0/1_try/split_arg.c b/module/subu-0/1_try/split_arg.c deleted file mode 100644 index 6d4c6ac..0000000 --- a/module/subu-0/1_try/split_arg.c +++ /dev/null @@ -1,20 +0,0 @@ -/* -Using preprocessor to make header file? - -gcc -E split.c -DPROTOTYPE - -Outputs source code source comment lines starting with a hash. Resolves all macro commands, -hence the resulting header can not have macro commands. - - */ - -#if PROTOTYPE -##define GREATNESS 21 -int f(int x); -#endif - -#if IMPLEMENTATION -int f(int x){ - return x; -} -#endif diff --git a/module/subu-0/1_try/subudb b/module/subu-0/1_try/subudb deleted file mode 100644 index e69de29..0000000 diff --git a/module/subu-0/1_try/voidptr.c b/module/subu-0/1_try/voidptr.c deleted file mode 100644 index bd9c3e5..0000000 --- a/module/subu-0/1_try/voidptr.c +++ /dev/null @@ -1,48 +0,0 @@ -/* -They say a cast is not required passing a typed pointer to a void * argument, -but What about void **? - -gcc -std=gnu11 -o voidptr voidptr.c -voidptr.c: In function ‘main’: -voidptr.c:28:5: warning: passing argument 1 of ‘g’ from incompatible pointer type [-Wincompatible-pointer-types] - g(&pt, y); - ^~~ -voidptr.c:13:15: note: expected ‘void **’ but argument is of type ‘int **’ - void g(void **pt0, void *pt1){ - ~~~~~~~^~~ - -*/ -#include - -int f(void *pt){ - return *(int *)pt; -} - -/* fails -void g(void **pt0, int *pt1){ - *pt0 = pt1; -} -*/ - -// passes -void g(void *pt0, int *pt1){ - *(int **)pt0 = pt1; -} - -int main(){ - int x = 5; - int *xp = &x; - printf("%d\n",f(xp)); - - int y[3]; - y[0] = 10; - y[1] = 11; - y[2] = 12; - - int *pt; - g(&pt, y); - printf("%d\n",*pt); - - printf("that's all folks\n"); - return 0; -} diff --git a/module/subu-0/common.lib.c b/module/subu-0/common.lib.c deleted file mode 100644 index 9ce5a27..0000000 --- a/module/subu-0/common.lib.c +++ /dev/null @@ -1,20 +0,0 @@ - -#include "subu-common.lib.h" - -#if INTERFACE -typedef unsigned int uint; -/* - Fedora 29's sss_cache is checking the inherited uid instead of the effective - uid, so setuid root scripts will fail when calling sss_cache. - - Fedora 29's 'useradd' calls sss_cache, and useradd is called by our setuid root - program subu-mk-0. -*/ -#define BUG_SSS_CACHE_RUID 1 -#endif - -// char *DB_File = "/etc/subudb"; -char DB_File[] = "subudb"; -uint Subuhome_Perms = 0700; -uint First_Max_Subunumber = 114; -char Subuland_Extension[] = "/subuland/"; diff --git a/module/subu-0/db.lib.c b/module/subu-0/db.lib.c deleted file mode 100644 index 17a5419..0000000 --- a/module/subu-0/db.lib.c +++ /dev/null @@ -1,192 +0,0 @@ -/* -The db file is maintained in SQLite - -Because user names of are of limited length, subu user names are always named _s. -A separate table translates the numbers into the subu names. - -The first argument is the biggest subu number in the system, or one minus an -starting point for subu numbering. - -currently a unit converted to base 10 will always fit in a 21 bit buffer. - -Each of these returns SQLITE_OK upon success -*/ -#include "subudb.lib.h" - -#if INTERFACE -#include -#endif - -#include -#include -#include -#include - -//-------------------------------------------------------------------------------- -// sqlite transactions don't nest. There is a way to use save points, but still -// we can't just nest transactions. Instead use these wrappers around the whole -// of something that needs to be in a transaction. -int db_begin(sqlite3 *db){ - return sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, NULL); -} -int db_commit(sqlite3 *db){ - return sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL); -} -int db_rollback(sqlite3 *db){ - return sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL); -} - -//-------------------------------------------------------------------------------- -int subudb_schema(sqlite3 *db){ - int rc; - - { // build tables - char sql[] = - "CREATE TABLE Masteru_Subu(masteru_name TEXT, subuname TEXT, subu_username TEXT);" - "CREATE TABLE Attribute_Int(attribute TEXT, value INT);" - ; - rc = sqlite3_exec(db, sql, NULL, NULL, NULL); - if(rc != SQLITE_OK) return rc; - } - - { // data initialization - char *sql = "INSERT INTO Attribute_Int (attribute, value) VALUES ('Max_Subunumber', ?1);"; - sqlite3_stmt *stmt; - sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); - sqlite3_bind_int(stmt, 1, First_Max_Subunumber); - rc = sqlite3_step(stmt); - sqlite3_finalize(stmt); - if( rc != SQLITE_DONE ) return rc; - } - - return SQLITE_OK; -} - -//-------------------------------------------------------------------------------- -int subudb_number_get(sqlite3 *db, int *n){ - char *sql = "SELECT value FROM Attribute_Int WHERE attribute = 'Max_Subunumber';"; - sqlite3_stmt *stmt; - sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); - int rc = sqlite3_step(stmt); - if( rc == SQLITE_ROW ){ - *n = sqlite3_column_int(stmt,0); - rc = sqlite3_step(stmt); - sqlite3_finalize(stmt); - if( rc != SQLITE_DONE ) return rc; - return SQLITE_OK; - } - // should have a message return, suppose - sqlite3_finalize(stmt); - return SQLITE_NOTFOUND; -} - -int subudb_number_set(sqlite3 *db, int n){ - int rc; - char *sql = "UPDATE Attribute_Int SET value = ?1 WHERE attribute = 'Max_Subunumber';"; - sqlite3_stmt *stmt; - sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); - sqlite3_bind_int(stmt, 1, n); - rc = sqlite3_step(stmt); - sqlite3_finalize(stmt); - if( rc == SQLITE_DONE ) return SQLITE_OK; - return rc; -} - -//-------------------------------------------------------------------------------- -// put relation into Masteru_Subu table -int subudb_Masteru_Subu_put(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username){ - char *sql = "INSERT INTO Masteru_Subu VALUES (?1, ?2, ?3);"; - sqlite3_stmt *stmt; - sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); - sqlite3_bind_text(stmt, 1, masteru_name, -1, SQLITE_STATIC); - sqlite3_bind_text(stmt, 2, subuname, -1, SQLITE_STATIC); - sqlite3_bind_text(stmt, 3, subu_username, -1, SQLITE_STATIC); - int rc = sqlite3_step(stmt); - sqlite3_finalize(stmt); - if( rc == SQLITE_DONE ) return SQLITE_OK; - return rc; -} - -//-------------------------------------------------------------------------------- -int subudb_Masteru_Subu_get_subu_username(sqlite3 *db, char *masteru_name, char *subuname, char **subu_username){ - char *sql = "SELECT subu_username FROM Masteru_Subu WHERE masteru_name = ?1 AND subuname = ?2;"; - size_t sql_len = strlen(sql); - sqlite3_stmt *stmt; - int rc; - rc = sqlite3_prepare_v2(db, sql, sql_len, &stmt, NULL); - if( rc != SQLITE_OK ) return rc; - sqlite3_bind_text(stmt, 1, masteru_name, strlen(masteru_name), SQLITE_STATIC); - sqlite3_bind_text(stmt, 2, subuname, strlen(subuname), SQLITE_STATIC); - rc = sqlite3_step(stmt); - if( rc == SQLITE_ROW ){ - const char *username = sqlite3_column_text(stmt, 0); - *subu_username = strdup(username); - }else{ - sqlite3_finalize(stmt); - return rc; // woops this needs to return an error!, be sure it is not SQLITE_DONE - } - rc = sqlite3_step(stmt); - if( rc == SQLITE_DONE ) return SQLITE_OK; - return rc; -} - -//-------------------------------------------------------------------------------- - -// we return and array of subudb_subu_info -#if INTERFACE -struct subudb_subu_element{ - char *subuname; - char *subu_username; -}; -#endif - -int subudb_Masteru_Subu_get_subus -( - sqlite3 *db, - char *masteru_name, - da *subus -){ - char *sql = "SELECT subuname, subu_username" - " FROM Masteru_Subu" - " WHERE masteru_name = ?1;"; - size_t sql_len = strlen(sql); - sqlite3_stmt *stmt; - int rc; - rc = sqlite3_prepare_v2(db, sql, sql_len, &stmt, NULL); - if( rc != SQLITE_OK ) return rc; - sqlite3_bind_text(stmt, 1, masteru_name, strlen(masteru_name), SQLITE_STATIC); - - da_alloc(subus, sizeof(subudb_subu_element)); - subudb_subu_element *pt = (subudb_subu_element *)subus->base; - rc = sqlite3_step(stmt); - while( rc == SQLITE_ROW ){ - if( da_boundq(subus, pt) ){ - char *old_base = da_expand(subus); - da_rebase(subus, old_base, pt); - } - pt->subuname = strdup(sqlite3_column_text(stmt, 0)); - pt->subu_username = strdup(sqlite3_column_text(stmt, 1)); - rc = sqlite3_step(stmt); - pt++; - } - sqlite3_finalize(stmt); - if( rc != SQLITE_DONE ) return rc; - return SQLITE_OK; -} - -//-------------------------------------------------------------------------------- -int subudb_Masteru_Subu_rm(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username){ - char *sql = "DELETE FROM Masteru_Subu WHERE masteru_name = ?1 AND subuname = ?2 AND subu_username = ?3;"; - size_t sql_len = strlen(sql); - sqlite3_stmt *stmt; - int rc; - rc = sqlite3_prepare_v2(db, sql, sql_len, &stmt, NULL); - if( rc != SQLITE_OK ) return rc; - sqlite3_bind_text(stmt, 1, masteru_name, -1, SQLITE_STATIC); - sqlite3_bind_text(stmt, 2, subuname, -1, SQLITE_STATIC); - sqlite3_bind_text(stmt, 3, subu_username, -1, SQLITE_STATIC); - rc = sqlite3_step(stmt); - sqlite3_finalize(stmt); - if( rc == SQLITE_DONE ) return SQLITE_OK; - return rc; -} diff --git a/module/subu-0/deprecated/0_makefile b/module/subu-0/deprecated/0_makefile new file mode 100644 index 0000000..f0708ef --- /dev/null +++ b/module/subu-0/deprecated/0_makefile @@ -0,0 +1,40 @@ +# src/0_makefile + +SHELL=/bin/bash + +-include 0_makefile_flags + +SUID_TOOL=$(TOOLSDIR)/bin/setuid_root.sh +MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tools/lib/makefile-cc + +SOURCES=$(wildcard *.c) +HFILES=$(wildcard *.h) + +all: version deps lib execs + +version: + $(MAKE) $@ + @echo "SUID_TOOL: " $(SUID_TOOL) + +deps: + makeheaders $(SOURCES) $(HFILES) + sed -i '/^ *int *main *(.*)/d' *.h + $(MAKE) $@ + +execs: + $(MAKE) $@ + @echo "-> $(SUID_TOOL) $(EXECSDIR)/subu-mk-0 $(EXECSDIR)/subu-rm-0 $(EXECSDIR)/subu-bind-all" + cat $(SUID_TOOL) + @echo -n "Are you sure? [y/N] " && read ans && [ $${ans:-N} == y ] + sudo $(SUID_TOOL) $(EXECSDIR)/subu-mk-0 $(EXECSDIR)/subu-rm-0 $(EXECSDIR)/subu-bind-all + +clean: + $(MAKE) $@ + for i in $(HFILES); do rm $$i; done + +%:: + $(MAKE) $@ + + + + diff --git a/module/subu-0/deprecated/0_makefile-flags b/module/subu-0/deprecated/0_makefile-flags new file mode 100644 index 0000000..d4df01f --- /dev/null +++ b/module/subu-0/deprecated/0_makefile-flags @@ -0,0 +1,31 @@ + +# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo .. +ECHO= echo +#ECHO= echo -e + +# directories used by this makefile, these could all be set to dot for +# the simplest source directory structure + +#LIDBIR, EXECSDIR, HDIR hold the make results that might later be shared +#$(PWD) is the directory that make was called from, this is already build in +#set to dot to use the same directory as the source code +#leave blank to ommit +DEPRDIR=1_deprecated +DOCDIR=1_doc +EXECSDIR=1_execs +HDIR=1_headers +LIBDIR=1_lib +TESTDIR=1_tests +TMPDIR=1_tmp +TOOLSDIR=$(realpath $(PROJECT_SUBU)/tools) +TRYDIR=1_try + + +# compiler and flags +CC=gcc +CFLAGS=-std=gnu11 -fPIC -I. -ggdb -Werror -DDEBUG -DDEBUGDB +#CFLAGS=-std=gnu11 -fPIC -I. -Werror +LINKFLAGS=-L1_lib -lsubu -lsqlite3 + +LIBFILE=$(LIBDIR)/libsubu.a + diff --git a/module/subu-0/deprecated/1_tmp/da.lib.h b/module/subu-0/deprecated/1_tmp/da.lib.h new file mode 100644 index 0000000..4702189 --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/da.lib.h @@ -0,0 +1,23 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +#include +#include +void daps_map(char **base,char **end_pt,void f(void *)); +#define RETURN(rc) \ + { daps_map(mrs, mrs_end, free); return rc; } +void daps_alloc(char ***base,size_t *s); +#define MK_MRS \ + char **mrs; \ + char **mrs_end; \ + size_t mrs_size; \ + daps_alloc(&mrs, &mrs_size);\ + mrs_end = mrs; +void daps_push(char ***base,char ***pt,size_t *s,char *item); +bool daps_bound(char **base,char **pt,size_t s); +void daps_expand(char ***base,char ***pt,size_t *s); +void da_map(void *base,void *end_pt,void f(void *),size_t item_size); +void da_push(void **base,void **pt,size_t *s,void *item,size_t item_size); +bool da_bound(void *base,void *pt,size_t s); +void da_expand(void **base,void **pt,size_t *s); +void da_alloc(void **base,size_t *s,size_t item_size); +#define INTERFACE 0 diff --git a/module/subu-0/deprecated/1_tmp/dbprintf.lib.h b/module/subu-0/deprecated/1_tmp/dbprintf.lib.h new file mode 100644 index 0000000..3056cf6 --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/dbprintf.lib.h @@ -0,0 +1,3 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +int dbprintf(const char *format,...); diff --git a/module/subu-0/deprecated/1_tmp/dispatch.lib.h b/module/subu-0/deprecated/1_tmp/dispatch.lib.h new file mode 100644 index 0000000..07e2271 --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/dispatch.lib.h @@ -0,0 +1,24 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +#include +#include +int dispatch_exec(char **argv,char **envp); +typedef unsigned int uint; +int dispatch_f_euid_egid(char *fname,int(*f)(void *arg),void *f_arg,uid_t euid,gid_t egid); +int dbprintf(const char *format,...); +int dispatch_f(char *fname,int(*f)(void *arg),void *f_arg); +void dispatch_f_mess(char *fname,int err,char *dispatchee); +#define ERR_DISPATCH_EXEC -1029 +#define ERR_DISPATCH_NULL_EXECUTABLE -1028 +#define ERR_DISPATCH_F_SETEGID -1027 +#define ERR_DISPATCH_F_SETEUID -1026 +#define ERR_DISPATCH_F_FORK -1025 +#define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024 +#define ERR_DISPATCH -1024 +typedef struct dispatch_ctx dispatch_ctx; +struct dispatch_ctx { + char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.) + char *dispatchee; // name of the function being dispatched + int err; // error code as listed below, or status returned from dispatchee +}; +#define INTERFACE 0 diff --git a/module/subu-0/deprecated/1_tmp/subu-bind-all.cli.h b/module/subu-0/deprecated/1_tmp/subu-bind-all.cli.h new file mode 100644 index 0000000..7e52675 --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/subu-bind-all.cli.h @@ -0,0 +1,9 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +#include +#include +#include +int subu_bind_all(char **mess,sqlite3 *db); +#define SUBU_ERR_DB_FILE 8 +extern char DB_File[]; +#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/deprecated/1_tmp/subu-bind.cli.h b/module/subu-0/deprecated/1_tmp/subu-bind.cli.h new file mode 100644 index 0000000..af12d61 --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/subu-bind.cli.h @@ -0,0 +1,7 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +#include +#include +#include +int subu_bind(char **mess,char *masteru_name,char *subu_username,char *subuhome); +#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/deprecated/1_tmp/subu-common.lib.h b/module/subu-0/deprecated/1_tmp/subu-common.lib.h new file mode 100644 index 0000000..cfdc520 --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/subu-common.lib.h @@ -0,0 +1,9 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +extern char Subuland_Extension[]; +typedef unsigned int uint; +extern uint First_Max_Subunumber; +extern uint Subuhome_Perms; +extern char DB_File[]; +#define BUG_SSS_CACHE_RUID 1 +#define INTERFACE 0 diff --git a/module/subu-0/deprecated/1_tmp/subu-mk-0.cli.h b/module/subu-0/deprecated/1_tmp/subu-mk-0.cli.h new file mode 100644 index 0000000..487b509 --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/subu-mk-0.cli.h @@ -0,0 +1,10 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +#include +#include +#include +void subu_err(char *fname,int err,char *mess); +int subu_mk_0(char **mess,sqlite3 *db,char *subuname); +#define SUBU_ERR_DB_FILE 8 +extern char DB_File[]; +#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/deprecated/1_tmp/subu-rm-0.cli.h b/module/subu-0/deprecated/1_tmp/subu-rm-0.cli.h new file mode 100644 index 0000000..070bfe8 --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/subu-rm-0.cli.h @@ -0,0 +1,10 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +#include +#include +#include +void subu_err(char *fname,int err,char *mess); +int subu_rm_0(char **mess,sqlite3 *db,char *subuname); +#define SUBU_ERR_DB_FILE 8 +extern char DB_File[]; +#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/deprecated/1_tmp/subu.lib.h b/module/subu-0/deprecated/1_tmp/subu.lib.h new file mode 100644 index 0000000..69c5da7 --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/subu.lib.h @@ -0,0 +1,66 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +typedef unsigned int uint; +#include +typedef struct subudb_subu_element subudb_subu_element; +int subudb_Masteru_Subu_get_subus(sqlite3 *db,char *masteru_name,subudb_subu_element **sa_pt,subudb_subu_element **sa_end_pt); +struct subudb_subu_element { + char *subuname; + char *subu_username; +}; +#include +#include +int subu_bind_all(char **mess,sqlite3 *db); +int subu_bind(char **mess,char *masteru_name,char *subu_username,char *subuhome); +int subudb_Masteru_Subu_rm(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); +int subudb_Masteru_Subu_get_subu_username(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username); +int subu_rm_0(char **mess,sqlite3 *db,char *subuname); +int subudb_Masteru_Subu_put(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); +#include +#include +int dispatch_exec(char **argv,char **envp); +#define BUG_SSS_CACHE_RUID 1 +void dispatch_f_mess(char *fname,int err,char *dispatchee); +#define ERR_DISPATCH -1024 +int dispatch_f_euid_egid(char *fname,int(*f)(void *arg),void *f_arg,uid_t euid,gid_t egid); +#include +void daps_map(char **base,char **end_pt,void f(void *)); +#define RETURN(rc) \ + { daps_map(mrs, mrs_end, free); return rc; } +void daps_push(char ***base,char ***pt,size_t *s,char *item); +int dbprintf(const char *format,...); +void daps_alloc(char ***base,size_t *s); +#define MK_MRS \ + char **mrs; \ + char **mrs_end; \ + size_t mrs_size; \ + daps_alloc(&mrs, &mrs_size);\ + mrs_end = mrs; +int subu_mk_0(char **mess,sqlite3 *db,char *subuname); +extern char Subuland_Extension[]; +int db_commit(sqlite3 *db); +int db_rollback(sqlite3 *db); +int subudb_number_set(sqlite3 *db,int n); +int subudb_number_get(sqlite3 *db,int *n); +int db_begin(sqlite3 *db); +extern uint Subuhome_Perms; +extern char DB_File[]; +void subu_err(char *fname,int err,char *mess); +#define SUBU_ERR_BIND 15 +#define SUBU_ERR_N 14 +#define SUBU_ERR_SUBU_NOT_FOUND 13 +#define SUBU_ERR_FAILED_USERDEL 12 +#define SUBU_ERR_FAILED_USERADD 11 +#define SUBU_ERR_BUG_SSS 10 +#define SUBU_ERR_SUBUHOME_EXISTS 9 +#define SUBU_ERR_DB_FILE 8 +#define SUBU_ERR_HOMELESS 7 +#define SUBU_ERR_SUBUNAME_MALFORMED 6 +#define SUBU_ERR_RMDIR_SUBUHOME 5 +#define SUBU_ERR_MKDIR_SUBUHOME 4 +#define SUBU_ERR_MALLOC 3 +#define SUBU_ERR_SETUID_ROOT 2 +#define SUBU_ERR_ARG_CNT 1 +char *userdel_mess(int err); +char *useradd_mess(int err); +#define INTERFACE 0 diff --git a/module/subu-0/deprecated/1_tmp/subudb-init.cli.h b/module/subu-0/deprecated/1_tmp/subudb-init.cli.h new file mode 100644 index 0000000..4435103 --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/subudb-init.cli.h @@ -0,0 +1,11 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +#include +int db_commit(sqlite3 *db); +int db_rollback(sqlite3 *db); +int subudb_schema(sqlite3 *db); +int db_begin(sqlite3 *db); +#include +#include +#define SUBU_ERR_DB_FILE 8 +extern char DB_File[]; diff --git a/module/subu-0/deprecated/1_tmp/subudb-number.cli.h b/module/subu-0/deprecated/1_tmp/subudb-number.cli.h new file mode 100644 index 0000000..c130fbb --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/subudb-number.cli.h @@ -0,0 +1,11 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +#include +int subudb_number_get(sqlite3 *db,int *n); +int subudb_number_set(sqlite3 *db,int n); +#include +#include +#define SUBU_ERR_N 14 +#define SUBU_ERR_DB_FILE 8 +extern char DB_File[]; +#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/deprecated/1_tmp/subudb-rel-get.cli.h b/module/subu-0/deprecated/1_tmp/subudb-rel-get.cli.h new file mode 100644 index 0000000..4f335be --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/subudb-rel-get.cli.h @@ -0,0 +1,9 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +#include +int subudb_Masteru_Subu_get_subu_username(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username); +#include +#include +#define SUBU_ERR_DB_FILE 8 +extern char DB_File[]; +#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/deprecated/1_tmp/subudb-rel-put.cli.h b/module/subu-0/deprecated/1_tmp/subudb-rel-put.cli.h new file mode 100644 index 0000000..243b3a9 --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/subudb-rel-put.cli.h @@ -0,0 +1,8 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +#include +int subudb_Masteru_Subu_put(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); +#include +#include +#define SUBU_ERR_DB_FILE 8 +extern char DB_File[]; diff --git a/module/subu-0/deprecated/1_tmp/subudb-rel-rm.cli.h b/module/subu-0/deprecated/1_tmp/subudb-rel-rm.cli.h new file mode 100644 index 0000000..595427f --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/subudb-rel-rm.cli.h @@ -0,0 +1,8 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +#include +int subudb_Masteru_Subu_rm(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); +#include +#include +#define SUBU_ERR_DB_FILE 8 +extern char DB_File[]; diff --git a/module/subu-0/deprecated/1_tmp/subudb-subus.cli.h b/module/subu-0/deprecated/1_tmp/subudb-subus.cli.h new file mode 100644 index 0000000..16310b7 --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/subudb-subus.cli.h @@ -0,0 +1,14 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +#include +typedef struct subudb_subu_element subudb_subu_element; +int subudb_Masteru_Subu_get_subus(sqlite3 *db,char *masteru_name,subudb_subu_element **sa_pt,subudb_subu_element **sa_end_pt); +struct subudb_subu_element { + char *subuname; + char *subu_username; +}; +#include +#include +#define SUBU_ERR_DB_FILE 8 +extern char DB_File[]; +#define SUBU_ERR_ARG_CNT 1 diff --git a/module/subu-0/deprecated/1_tmp/subudb.lib.h b/module/subu-0/deprecated/1_tmp/subudb.lib.h new file mode 100644 index 0000000..be73823 --- /dev/null +++ b/module/subu-0/deprecated/1_tmp/subudb.lib.h @@ -0,0 +1,27 @@ +/* This file was automatically generated. Do not edit! */ +#undef INTERFACE +#include +int subudb_Masteru_Subu_rm(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); +#include +#include +void da_expand(void **base,void **pt,size_t *s); +bool da_bound(void *base,void *pt,size_t s); +typedef struct subudb_subu_element subudb_subu_element; +int subudb_Masteru_Subu_get_subus(sqlite3 *db,char *masteru_name,subudb_subu_element **sa_pt,subudb_subu_element **sa_end_pt); +void subu_element_free(subudb_subu_element *base,subudb_subu_element *end_pt); +void da_alloc(void **base,size_t *s,size_t item_size); +struct subudb_subu_element { + char *subuname; + char *subu_username; +}; +int subudb_Masteru_Subu_get_subu_username(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username); +int subudb_Masteru_Subu_put(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); +int subudb_number_set(sqlite3 *db,int n); +int subudb_number_get(sqlite3 *db,int *n); +typedef unsigned int uint; +extern uint First_Max_Subunumber; +int subudb_schema(sqlite3 *db); +int db_rollback(sqlite3 *db); +int db_commit(sqlite3 *db); +int db_begin(sqlite3 *db); +#define INTERFACE 0 diff --git a/module/subu-0/doc/to_do.txt b/module/subu-0/doc/to_do.txt new file mode 100644 index 0000000..0b989cc --- /dev/null +++ b/module/subu-0/doc/to_do.txt @@ -0,0 +1,38 @@ +2019-02-05T23:14:40Z + error can cause subu-mk-0 to leave the creating of a subu in an intermediate + state. Rather than bailing on some of the errors we need to clean up instead. + Perhaps the yet to be written subu-rm program will be resilent enough to do + more general cleanup. + +2019-02-23T18:56:31Z + need to modify subu-init to take a configuration file name argument instead of + using a global variabel value. might want to add arguments to other subu + commands also + +2019-03-11T13:48:03Z + in subu.lib.c append cascading rmdir failure mess to useradd failure mess + +2019-03-11T13:48:03Z + want to add subu-type to masteru_subu(), I imagine there will be static, + permanent, and temporary subu types. + +2019-03-12T18:35:06Z + the masteru subu relation should contain the uid of the masteru as + well as the backup type for the subu: git, rdiff, rsync, none. + and the persisitance fo the subu: indefinite, session. + seems that operations need to be logged, in case the db is lost + the transcript can be played back. It should also be possible + to co-opt an existing user as a subu, though, would require + sudo privs. + + need to add messages for subu errors I've added to the end of + the list in subu.lib.c + +2019-03-14T10:43:50Z + + should mod all to he subudb routines to return a message, probably + strdup(sqlite_errmsg(db)), then the callers to these routines can just pass + mess in rather than making up new ones for each situation. The error code + probably already carries the contexts specific message. Or perhaps add + a string cat function for message strings, that would run through a stream + and free the originals. diff --git a/module/subu-0/makefile b/module/subu-0/makefile new file mode 100644 index 0000000..ab3ffe5 --- /dev/null +++ b/module/subu-0/makefile @@ -0,0 +1,45 @@ +# src-dispatch/makefile + +SHELL=/bin/bash +MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc +#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc + +-include makefile-flags + + +.PHONY: all +all: version + +.PHONY: info +info: + @echo "TRCDIR: " $(TRCDIR) + $(MAKE) $@ + +.PHONY: setup +setup: + [ ! -e $(TRCDIR) ] && mkdir $(TRCDIR) || true + $(MAKE) $@ + +.PHONY: dep +dep: + if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi + @trcsources=$(wildcard $(TRCDIR)/*.trc.c)$(wildcard $(TRCDIR)/*.trc.cc);\ + if [ ! -z "$$trcsources" ]; then\ + trctargets=$$(tranche-target $$trcsources -sep " " -tdir $(SRCDIR) );\ + $(ECHO) $$trcsources;\ + tranche-make $$trcsources -tdir $(SRCDIR) -mfile $(DEPFILE);\ + $(MAKE) $$trctargets;\ + fi + $(MAKE) $@ + +.PHONY: lib +lib: + $(MAKE) $@ + cp $(SRCDIR)/dispatch.lib.h $(INCDIR)/dispatch.h + +%:: + $(MAKE) $@ + + + + diff --git a/module/subu-0/makefile-flags b/module/subu-0/makefile-flags new file mode 100644 index 0000000..854b84f --- /dev/null +++ b/module/subu-0/makefile-flags @@ -0,0 +1,33 @@ + +MODULE=dispatch + +DEPRDIR=deprecated +DOCDIR=doc +EXECDIR=exec +INCDIR=include +LIBDIR=lib +SHAREDIR=../share +SRCDIR=tmp +TESTDIR=test +TMPDIR=tmp +TOOLDIR=$(realpath $(PROJECT_SUBU)/tool) +TRCDIR=trc +TRYDIR=try + +DEPFILE=$(TMPDIR)/makefile-trc.deps +LIBFILE=$(LIBDIR)/lib$(MODULE).a +INCFILE=$(INCDIR)/$(MODULE).h + +# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo .. +ECHO= echo +#ECHO= echo -e + +# compiler and flags +C=gcc +CFLAGS=-std=gnu11 -fPIC -I. -I../share/include -ggdb -Werror -DDEBUG -DDEBUGDB +#CFLAGS=-std=gnu11 -fPIC -I. -I../share/include -Werror + +LINKFLAGS=-L1_lib -lda + + + diff --git a/module/subu-0/subu-bind-all.cli.c b/module/subu-0/subu-bind-all.cli.c deleted file mode 100644 index e942909..0000000 --- a/module/subu-0/subu-bind-all.cli.c +++ /dev/null @@ -1,31 +0,0 @@ -/* -mount all the subu user directories into master's subuland -uses unmount to undo this - -*/ -#include "subu-bind-all.cli.h" -#include -#include - -int main(int argc, char **argv){ - if( argc != 1){ - fprintf(stderr, "%s does not take arguments\n",argv[0]); - return SUBU_ERR_ARG_CNT; - } - - int rc; - sqlite3 *db; - rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); - if( rc != SQLITE_OK ){ - fprintf(stderr, "could not open db file \"%s\"\n", DB_File); - return SUBU_ERR_DB_FILE; - } - - char *mess; - rc = subu_bind_all(&mess, db); - if(rc != 0){ - fprintf(stderr, "subu-bind: %s\n", mess); - return rc; - } - return 0; -} diff --git a/module/subu-0/subu-bind.cli.c b/module/subu-0/subu-bind.cli.c deleted file mode 100644 index f315823..0000000 --- a/module/subu-0/subu-bind.cli.c +++ /dev/null @@ -1,25 +0,0 @@ -/* -mount a subu user directory into master's subuland -uses unmount to undo this - -*/ -#include "subu-bind.cli.h" -#include -#include - -int main(int argc, char **argv){ - - if( argc != 4){ - fprintf(stderr, "usage: %s masteru subu_username subuhome\n",argv[0]); - return SUBU_ERR_ARG_CNT; - } - - int rc; - char *mess; - rc = subu_bind(&mess, argv[1], argv[2], argv[3]); - if(rc != 0){ - fprintf(stderr, "subu-bind: %s\n", mess); - return rc; - } - return 0; -} diff --git a/module/subu-0/subu-mk-0.cli.c b/module/subu-0/subu-mk-0.cli.c deleted file mode 100644 index af0888b..0000000 --- a/module/subu-0/subu-mk-0.cli.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - subu-mk-0 command - -*/ -#include "subu-mk-0.cli.h" -#include -#include - -int main(int argc, char **argv){ - char *command = argv[0]; - if( argc != 2 ){ - fprintf(stderr, "usage: %s subu", command); - return SUBU_ERR_ARG_CNT; - } - char *subuname = argv[1]; - - int rc; - sqlite3 *db; - rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); - if( rc != SQLITE_OK ){ - fprintf(stderr, "error when opening db, %s\n", DB_File); - fprintf(stderr, "sqlite3 says: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - return SUBU_ERR_DB_FILE; - } - - char *mess; - rc = subu_mk_0(&mess, db, subuname); - if( rc ){ - subu_err("subu_mk_0", rc, mess); - free(mess); - sqlite3_close(db); - return rc; - } - - rc = sqlite3_close(db); - if( rc != SQLITE_OK ){ - fprintf(stderr, "when closing db, %s\n", sqlite3_errmsg(db)); - return SUBU_ERR_DB_FILE; - } - return 0; - -} diff --git a/module/subu-0/subu-rm-0.cli.c b/module/subu-0/subu-rm-0.cli.c deleted file mode 100644 index a7e5926..0000000 --- a/module/subu-0/subu-rm-0.cli.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - subu-mk-0 command - -*/ -#include "subu-rm-0.cli.h" -#include -#include - -int main(int argc, char **argv){ - char *command = argv[0]; - if( argc != 2 ){ - fprintf(stderr, "usage: %s subu", command); - return SUBU_ERR_ARG_CNT; - } - char *subuname = argv[1]; - - sqlite3 *db; - { - int ret = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); - if( ret != SQLITE_OK ){ - fprintf(stderr, "error exit, could not open db file \"%s\"\n", DB_File); - return SUBU_ERR_DB_FILE; - }} - - { - char *mess=0; - int ret = subu_rm_0(&mess, db, subuname); - subu_err("subu_rm_0", ret, mess); - free(mess); - return ret; - } -} diff --git a/module/subu-0/subu.lib.c b/module/subu-0/subu.lib.c deleted file mode 100644 index 988bd28..0000000 --- a/module/subu-0/subu.lib.c +++ /dev/null @@ -1,713 +0,0 @@ -/* - sqllite3 is used to maintain the db file, which is currently compiled - in as /etc/subu.db, (or just subu.db for testing). - - masteru is the user who ran this script. The masteru name comes from getuid - and /etc/passwd. - - subu is a subservient user. The subuname is passed in as an argument. - - subu-mk-0 synthesizes a new user user name s, calls useradd to creat - the new uswer account, and enters the relationship between masteru, subu, and - s in the db file. It is this relation in the db file that - associates the subuname with the s user. - - subu-rm-0 uses userdel to delete the related s user account. It - then removes the relaton from the db file. - - subu-mk-0 and subu-rm-0 are setuid root scripts. - -*/ -#include "subu.lib.h" - -// without this #define we get the warning: implicit declaration of function ‘seteuid’/‘setegid’ -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include - -#if INTERFACE -#include -#include -#include -#endif - -//-------------------------------------------------------------------------------- -// dispatched command errors .. should add mkdir and rmdir ... -// -char *useradd_mess(int err){ - if(err <= 0) return NULL; - char *mess; - switch(err){ - case 1: mess = "can't update password file"; break; - case 2: mess = "invalid command syntax"; break; - case 3: mess = "invalid argument to option"; break; - case 4: mess = "UID already in use (and no -o)"; break; - case 5: mess = "undefined"; break; - case 6: mess = "specified group doesn't exist"; break; - case 7: - case 8: mess = "undefined"; break; - case 9: mess = "username already in use"; break; - case 10: mess = "can't update group file:"; break; - case 11: mess = "undefined"; break; - case 12: mess = "can't create home directory"; break; - case 13: mess = "undefined"; break; - case 14: mess = "can't update SELinux user mapping"; break; - default: mess = "undefined"; break; - } - return strdup(mess); -} -char *userdel_mess(int err){ - if(err <= 0) return NULL; - char *mess; - switch(err){ - case 1: mess = "can't update password file"; break; - case 2: mess = "invalid command syntax"; break; - case 3: - case 4: - case 5: mess = "undefined"; break; - case 6: mess = "specified user doesn't exist"; break; - case 7: - case 8: - case 9: mess = "undefined"; break; - case 10: mess = "can't update group file:"; break; - case 11: mess = "undefined"; break; - case 12: mess = "can't remove home directory"; break; - default: mess = "undefined"; break; - } - return strdup(mess); -} - - -//-------------------------------------------------------------------------------- -// -#if INTERFACE -#define SUBU_ERR_ARG_CNT 1 -#define SUBU_ERR_SETUID_ROOT 2 -#define SUBU_ERR_MALLOC 3 -#define SUBU_ERR_MKDIR_SUBUHOME 4 -#define SUBU_ERR_RMDIR_SUBUHOME 5 -#define SUBU_ERR_SUBUNAME_MALFORMED 6 -#define SUBU_ERR_HOMELESS 7 -#define SUBU_ERR_DB_FILE 8 -#define SUBU_ERR_SUBUHOME_EXISTS 9 -#define SUBU_ERR_BUG_SSS 10 -#define SUBU_ERR_FAILED_USERADD 11 -#define SUBU_ERR_FAILED_USERDEL 12 -#define SUBU_ERR_SUBU_NOT_FOUND 13 -#define SUBU_ERR_N 14 -#define SUBU_ERR_BIND 15 -#endif - -void subu_err(char *fname, int err, char *mess){ - if(!mess) mess = ""; - switch(err){ - case 0: return; - case SUBU_ERR_ARG_CNT: - if(mess[0]) - fprintf(stderr, "Incorrect number of arguments, %s", mess); - else - fprintf(stderr, "Incorrect number of arguments.", mess); - break; - case SUBU_ERR_SETUID_ROOT: - fprintf(stderr, "This program must be run setuid root from a user account."); - break; - case SUBU_ERR_MALLOC: - perror(fname); - break; - case SUBU_ERR_DB_FILE: - fprintf(stderr, "error on %s", DB_File); // DB_File is in common - fprintf(stderr, ": %s", mess); - break; - case SUBU_ERR_HOMELESS: - fprintf(stderr,"Masteru, \"%s\", has no home directory", mess); - break; - case SUBU_ERR_SUBUNAME_MALFORMED: - fprintf(stderr, "subuname, \"%s\" is not in [ _.-a-zA-Z0-9]*", mess); - break; - case SUBU_ERR_SUBUHOME_EXISTS: - fprintf(stderr, "a file system object already exists at subuhome, \"%s\"\n", mess); - break; - case SUBU_ERR_MKDIR_SUBUHOME: - fprintf(stderr, "masteru could not make subuhome, \"%s\"", mess); - break; - case SUBU_ERR_BUG_SSS: - perror(fname); - break; - case SUBU_ERR_FAILED_USERADD: - fprintf(stderr, "%s useradd failed\n", mess); - break; - default: - fprintf(stderr, "unknown error code %d\n", err); - } - fputc('\n', stderr); -} - - -//-------------------------------------------------------------------------------- -// a well formed subuname -// returns the length of the subuname, or -1 -// -static int allowed_subuname(char **mess, char *subuname, size_t *subuname_len){ - char *ch = subuname; - size_t i = 0; - while( - *ch - && - ( *ch >= 'a' && *ch <= 'z' - || - *ch >= 'A' && *ch <= 'Z' - || - *ch >= '0' && *ch <= '9' - || - *ch == '-' - || - *ch == '_' - || - *ch == '.' - || - *ch == ' ' - ) - ){ - ch++; - i++; - } - if( !*ch ){ - *subuname_len = i; - return 0; - }else{ - if(mess) *mess = strdup(subuname); - return SUBU_ERR_SUBUNAME_MALFORMED; - } -} - -//-------------------------------------------------------------------------------- -// dispatched functions -// -static int masteru_mkdir_subuhome(void *arg){ - char *subuhome = (char *) arg; - if( mkdir( subuhome, Subuhome_Perms ) == -1 ){ // find subuhome perms in common - perror("masteru_mkdir_subuhome"); - return SUBU_ERR_MKDIR_SUBUHOME; - } - return 0; -} -static int masteru_rmdir_subuhome(void *arg){ - char *subuhome = (char *) arg; - if( rmdir( subuhome ) == -1 ){ // find subuhome perms in common - perror("masteru_rmdir_subuhome"); - return SUBU_ERR_RMDIR_SUBUHOME; - } - return 0; -} - -//-------------------------------------------------------------------------------- -// build strings -// -static int mk_subu_username(char **mess, sqlite3 *db, char **subu_username){ - int rc,n; - db_begin(db); - if( - (rc = subudb_number_get(db, &n)) - || - (rc = subudb_number_set(db, ++n)) - ){ - db_rollback(db); - return SUBU_ERR_DB_FILE; - } - db_commit(db); - - size_t len = 0; - FILE* name_stream = open_memstream(subu_username, &len); - fprintf(name_stream, "s%d", n); - fclose(name_stream); - return 0; -} - -// man page says that getpwuid strings may not be freed, I don't know how long until they -// are overwritten, so I just make my own copies that can be freed -static int uid_to_name_and_home(uid_t uid, char **name, char **home ){ - struct passwd *pw_record_pt = getpwuid(uid); // reading /etc/passwd - *name = strdup(pw_record_pt->pw_name); - *home = strdup(pw_record_pt->pw_dir); - if( !home || !home[0] || (*home)[0] == '(' ) return SUBU_ERR_HOMELESS; - return 0; -} - -static int username_to_home(char *name, char **home ){ - struct passwd *pw_record_pt = getpwnam(name); // reading /etc/passwd - *home = strdup(pw_record_pt->pw_dir); - if( !home || !home[0] || (*home)[0] == '(' ) return SUBU_ERR_HOMELESS; - return 0; -} - -static int mk_subuland(char *masteru_home, char **subuland){ - size_t masteru_home_len = strlen(masteru_home); - char *Subuland_Extension = "/subuland/"; - size_t Subuland_Extension_len = strlen(Subuland_Extension); - *subuland = (char *)malloc( masteru_home_len + Subuland_Extension_len + 1 ); - if(!*subuland) SUBU_ERR_MALLOC; - strcpy(*subuland, masteru_home); - strcpy(*subuland + masteru_home_len, Subuland_Extension); - return 0; -} - -static int mk_subuhome(char *subuland, char *subuname, char **subuhome){ - size_t subuland_len = strlen(subuland); - size_t subuhome_len = subuland_len + strlen(subuname); // subuland has a trailing '/' - *subuhome = (char *)malloc(subuhome_len + 1); - if(!*subuhome) return SUBU_ERR_MALLOC; - strcpy (*subuhome, subuland); - strcpy (*subuhome + subuland_len, subuname); - return 0; -} - - - -//=============================================================================== -int subu_mk_0(char **mess, sqlite3 *db, char *subuname){ - - int rc; - if(mess)*mess = 0; - da resources; - da_alloc(&resources, sizeof(char *)); - - //-------------------------------------------------------------------------------- - size_t subuname_len; - rc = allowed_subuname(mess, subuname, &subuname_len); - if(rc) return rc; - #ifdef DEBUG - dbprintf("subuname is well formed\n"); - #endif - - //-------------------------------------------------------------------------------- - uid_t masteru_uid; - gid_t masteru_gid; - uid_t set_euid; - gid_t set_egid; - { - masteru_uid = getuid(); - masteru_gid = getgid(); - set_euid = geteuid(); - set_egid = getegid(); - #ifdef DEBUG - dbprintf("masteru_uid %u, masteru_gid %u, set_euid %u set_egid %u\n", masteru_uid, masteru_gid, set_euid, set_egid); - #endif - if( masteru_uid == 0 || set_euid != 0 ) return SUBU_ERR_SETUID_ROOT; - } - - //-------------------------------------------------------------------------------- - char *masteru_name = 0; - char *masteru_home = 0; - char *subu_username = 0; - char *subuland = 0; - char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir - da_push(&resources, masteru_name); - da_push(&resources, masteru_home); - da_push(&resources, subu_username); - da_push(&resources, subuland); - da_push(&resources, subuhome); - rc = - uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home) - || - mk_subu_username(mess, db, &subu_username) - || - mk_subuland(masteru_home, &subuland) - || - mk_subuhome(subuland, subuname, &subuhome) - ; - if(rc) RETURN(&resources, rc); - #ifdef DEBUG - dbprintf("subu_username, subuland, subuhome: \"%s\"\"%s\"\"%s\"\n", subu_username, subuland, subuhome); - #endif - - //-------------------------------------------------------------------------------- - // By having masteru create the subuhome, we know that masteru has rights to - // to access this directory. This will be the mount point for bindfs - { - struct stat st; - if( stat(subuhome, &st) != -1 ){ - if(mess)*mess = strdup(subuhome); - RETURN(&resources, SUBU_ERR_SUBUHOME_EXISTS); - } - int dispatch_err = dispatch_f_euid_egid - ( - "masteru_mkdir_subuhome", - masteru_mkdir_subuhome, - (void *)subuhome, - masteru_uid, - masteru_gid - ); - if( dispatch_err <= ERR_DISPATCH || dispatch_err == SUBU_ERR_MKDIR_SUBUHOME ){ - #ifdef DEBUG - dispatch_f_mess("dispatch_f_euid_egid", dispatch_err, "masteru_mkdir_subuhome"); - #endif - if(mess)*mess = strdup(subuhome); - RETURN(&resources, SUBU_ERR_MKDIR_SUBUHOME); - } - } - #ifdef DEBUG - dbprintf("made directory \"%s\"\n", subuhome); - #endif - - //-------------------------------------------------------------------------------- - // Make the subservient user account, i.e. the subu - { - #ifdef DEBUG - dbprintf("making subu \"%s\" as user \"%s\"\n", subuname, subu_username); - #endif - #if BUG_SSS_CACHE_RUID - #ifdef DEBUG - dbprintf("setting inherited real uid to 0 to accomodate SSS_CACHE UID BUG\n"); - #endif - if( setuid(0) == -1 ) RETURN(&resources, SUBU_ERR_BUG_SSS); - #endif - char *command = "/usr/sbin/useradd"; - char *argv[3]; - argv[0] = command; - argv[1] = subu_username; - argv[2] = (char *) NULL; - char *envp[1]; - envp[0] = (char *) NULL; - int dispatch_err = dispatch_exec(argv, envp); - if( dispatch_err != 0 ){ - #ifdef DEBUG - dispatch_f_mess("dispatch_exec", dispatch_err, command); - #endif - // go back and remove the directory we made in subuland - int dispatch_err_rmdir = dispatch_f_euid_egid - ( - "masteru_rmdir_subuhome", - masteru_rmdir_subuhome, - (void *)subuhome, - masteru_uid, - masteru_gid - ); - #ifdef DEBUG - dispatch_f_mess("dispatch_f_euid_egid", dispatch_err_rmdir, "masteru_rmdir_subuhome"); - #endif - if(mess)*mess = useradd_mess(dispatch_err); - RETURN(&resources, SUBU_ERR_FAILED_USERADD); - } - #ifdef DEBUG - dbprintf("added user \"%s\"\n", subu_username); - #endif - } - - //-------------------------------------------------------------------------------- - #ifdef DEBUG - dbprintf("setting the masteru_name, subuname, subu_username relation\n"); - #endif - { - int rc = subudb_Masteru_Subu_put(db, masteru_name, subuname, subu_username); - if( rc != SQLITE_OK ){ - if(mess)*mess = strdup("insert of masteru subu relation failed"); - RETURN(&resources, SUBU_ERR_DB_FILE); - } - } - #ifdef DEBUG - dbprintf("finished subu-mk-0(%s)\n", subuname); - #endif - RETURN(&resources, 0); -} - -//================================================================================ -int subu_rm_0(char **mess, sqlite3 *db, char *subuname){ - - int rc; - if(mess)*mess = 0; - da resources; - da_alloc(&resources, sizeof(char *)); - - //-------------------------------------------------------------------------------- - size_t subuname_len; - rc = allowed_subuname(mess, subuname, &subuname_len); - if(rc) return rc; - #ifdef DEBUG - dbprintf("subuname is well formed\n"); - #endif - - //-------------------------------------------------------------------------------- - uid_t masteru_uid; - gid_t masteru_gid; - uid_t set_euid; - gid_t set_egid; - { - masteru_uid = getuid(); - masteru_gid = getgid(); - set_euid = geteuid(); - set_egid = getegid(); - #ifdef DEBUG - dbprintf("masteru_uid %u, masteru_gid %u, set_euid %u set_egid %u\n", masteru_uid, masteru_gid, set_euid, set_egid); - #endif - if( masteru_uid == 0 || set_euid != 0 ) return SUBU_ERR_SETUID_ROOT; - } - - //-------------------------------------------------------------------------------- - // various strings that we will need - char *masteru_name = 0; - char *masteru_home = 0; - char *subuland = 0; - char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir - da_push(&resources, masteru_name); - da_push(&resources, masteru_home); - da_push(&resources, subuland); - da_push(&resources, subuhome); - rc = - uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home) - || - mk_subuland(masteru_home, &subuland) - || - mk_subuhome(subuland, subuname, &subuhome) - ; - if(rc) RETURN(&resources, rc); - #ifdef DEBUG - dbprintf("masteru_home, subuhome: \"%s\", \"%s\"\n", masteru_home, subuhome); - #endif - - //-------------------------------------------------------------------------------- - // removal from db - char *subu_username = 0; - da_push(&resources, subu_username); - - db_begin(db); - - rc = subudb_Masteru_Subu_get_subu_username(db, masteru_name, subuname, &subu_username); - if( rc != SQLITE_OK ){ - if(mess) *mess = strdup("subu requested for removal not found under this masteru in db file"); - rc = SUBU_ERR_SUBU_NOT_FOUND; - db_rollback(db); - RETURN(&resources, rc); - } - #ifdef DEBUG - printf("subu_username: \"%s\"\n", subu_username); - #endif - - rc = subudb_Masteru_Subu_rm(db, masteru_name, subuname, subu_username); - if( rc != SQLITE_OK ){ - if(mess)*mess = strdup("removal of masteru subu relation failed"); - db_rollback(db); - RETURN(&resources, SUBU_ERR_DB_FILE); - } - #ifdef DEBUG - dbprintf("removed the masteru_name, subuname, subu_username relation\n"); - #endif - - rc = db_commit(db); - if( rc != SQLITE_OK ){ - if(mess)*mess = strdup("removal of masteru subu relation in unknown state, exiting"); - RETURN(&resources, SUBU_ERR_DB_FILE); - } - - // even after removing the last masteru subu relation, we still do not remove - // the max subu count. Hence, a masteru will keep such for a life time. - - - //-------------------------------------------------------------------------------- - // Only masteru can remove directories from masteru/subuland, so we switch to - // masteru's uid to perform the rmdir. - // - { - #ifdef DEBUG - dbprintf("as masteru, removing the directory \"%s\"\n", subuhome); - #endif - int dispatch_err = dispatch_f_euid_egid - ( - "masteru_rmdir_subuhome", - masteru_rmdir_subuhome, - (void *)subuhome, - masteru_uid, - masteru_gid - ); - if( dispatch_err <= ERR_DISPATCH || dispatch_err == SUBU_ERR_RMDIR_SUBUHOME ){ - #ifdef DEBUG - dispatch_f_mess("dispatch_f_euid_egid", dispatch_err, "masteru_rmdir_subuhome"); - #endif - if(mess)*mess = strdup(subuhome); - RETURN(&resources, SUBU_ERR_RMDIR_SUBUHOME); - } - } - - //-------------------------------------------------------------------------------- - // Delete the subservient user account - { - #ifdef DEBUG - dbprintf("deleting user \"%s\"\n", subu_username); - #endif - #if BUG_SSS_CACHE_RUID - #ifdef DEBUG - dbprintf("setting inherited real uid to 0 to accomodate SSS_CACHE UID BUG\n"); - #endif - if( setuid(0) == -1 ){ - RETURN(&resources, SUBU_ERR_BUG_SSS); - } - #endif - char *command = "/usr/sbin/userdel"; - char *argv[4]; - argv[0] = command; - argv[1] = subu_username; - argv[2] = "-r"; - argv[3] = (char *) NULL; - char *envp[1]; - envp[0] = (char *) NULL; - int dispatch_err = dispatch_exec(argv, envp); - if( dispatch_err != 0 ){ - #ifdef DEBUG - dispatch_f_mess("dispatch_exec", dispatch_err, command); - #endif - if(mess)*mess = userdel_mess(dispatch_err); - RETURN(&resources, SUBU_ERR_FAILED_USERDEL); - } - #ifdef DEBUG - dbprintf("deleted user \"%s\"\n", subu_username); - #endif - } - - #ifdef DEBUG - dbprintf("finished subu-rm-0(%s)\n", subuname); - #endif - RETURN(&resources, 0); -} - -//================================================================================ -// identifies masteru, the bindfs maps each subu_user's home to its mount point -// in subuland. -int subu_bind(char **mess, char *masteru_name, char *subu_username, char *subuhome){ - - int rc; - if(mess)*mess = 0; - da resources; - da_alloc(&resources, sizeof(char *)); - - // lookup the subu_user_home - char *subu_user_home = 0; - da_push(&resources, subu_user_home); - - rc = username_to_home(subu_username, &subu_user_home); - if( rc ){ - if(mess) *mess = strdup("in subu_bind, subu user home directory lookup in /etc/passwd failed."); - RETURN(&resources, rc); - } - - size_t len = 0; - char *map = 0; - da_push(&resources, map); - - FILE* map_stream = open_memstream(&map, &len); - fprintf(map_stream, "--map=%s/%s:@%s/@%s", subu_username, masteru_name, subu_username, masteru_name); - fclose(map_stream); - - char *command = "/usr/bin/bindfs"; - char *argv[5]; - argv[0] = command; - argv[1] = map; - argv[2] = subu_user_home; - argv[3] = subuhome; - argv[4] = (char *) NULL; - char *envp[1]; - envp[0] = (char *) NULL; - int dispatch_err = dispatch_exec(argv, envp); - if( dispatch_err != 0 ){ - #ifdef DEBUG - dispatch_f_mess(command, dispatch_err, "dispatch_exec"); - #endif - if(mess)*mess = strdup("bind failed"); - RETURN(&resources, SUBU_ERR_BIND); - } - #ifdef DEBUG - dbprintf("mapped \"%s\" as \"%s\"\n", subu_user_home, subuhome); - #endif - RETURN(&resources, 0); -} - -int subu_bind_all(char **mess, sqlite3 *db){ - - int rc; - if(mess)*mess = 0; - da resources; - da_alloc(&resources, sizeof(char *)); - - //-------------------------------------------------------------------------------- - uid_t masteru_uid; - gid_t masteru_gid; - uid_t set_euid; - gid_t set_egid; - { - masteru_uid = getuid(); - masteru_gid = getgid(); - set_euid = geteuid(); - set_egid = getegid(); - #ifdef DEBUG - dbprintf("masteru_uid %u, masteru_gid %u, set_euid %u set_egid %u\n", masteru_uid, masteru_gid, set_euid, set_egid); - #endif - if( masteru_uid == 0 || set_euid != 0 ) return SUBU_ERR_SETUID_ROOT; - } - - //-------------------------------------------------------------------------------- - // various strings that we will need - char *masteru_name = 0; - char *masteru_home = 0; - char *subuland = 0; - da_push(&resources, masteru_name); - da_push(&resources, masteru_home); - da_push(&resources, subuland); - rc = - uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home) - || - mk_subuland(masteru_home, &subuland) - ; - if(rc) RETURN(&resources, rc); - #ifdef DEBUG - if(masteru_name) - dbprintf("masteru_name: \"%s\"", masteru_name); - else - dbprintf("masteru_name unknown"); - if(subuland) - dbprintf("subuland: \"%s\"", subuland); - else - dbprintf("subuland unknown"); - dbprintf("\n"); - #endif - - //-------------------------------------------------------------------------------- - da subus; - rc = subudb_Masteru_Subu_get_subus(db, masteru_name, &subus); - if( rc != SQLITE_OK ){ - if(mess)*mess = strdup("db access failed when fetching a list of subus"); - return rc; - } - // a limitation of our error reporting approach is that we can only - // return one error, but here is a loop that might generate many - rc = 0; - char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir - uint err_cnt = 0; - subudb_subu_element *pt = (subudb_subu_element *)(subus.base); - while( !da_endq(&subus,pt) ){ - rc = mk_subuhome(subuland, pt->subuname, &subuhome); - #ifdef DEBUG - if(subuhome) - dbprintf("subuhome: \"%s\"\n", subuhome); - else - dbprintf("subuhome unknown \n"); - #endif - if(!rc) rc = subu_bind(NULL, masteru_name, pt->subu_username, subuhome); - if(rc) err_cnt++; - free(subuhome); - subuhome=0; - pt++; - } - if(err_cnt==1){ - RETURN(&resources, rc); - } - if(err_cnt > 1){ - *mess = strdup("multiple errors occured while binding subus"); - RETURN(&resources, SUBU_ERR_BIND); - } - RETURN(&resources, 0); -} diff --git a/module/subu-0/subudb-init.cli.c b/module/subu-0/subudb-init.cli.c deleted file mode 100644 index 714c7e4..0000000 --- a/module/subu-0/subudb-init.cli.c +++ /dev/null @@ -1,26 +0,0 @@ -/* -This command initializes the db file. - -*/ -#include "subudb-init.cli.h" -#include - -int main(){ - sqlite3 *db; - if( sqlite3_open(DB_File, &db) != SQLITE_OK ){ - fprintf(stderr, "error exit, could not open db file \"%s\"\n", DB_File); - return SUBU_ERR_DB_FILE; - } - db_begin(db); - if( subudb_schema(db) != SQLITE_OK ){ - db_rollback(db); - fprintf(stderr, "error exit, opened db file but could not build schema\n"); - return SUBU_ERR_DB_FILE; - } - db_commit(db); - if( sqlite3_close(db) != SQLITE_OK ){ - fprintf(stderr, "error exit, could not close the db\n"); - return SUBU_ERR_DB_FILE; - } - return 0; -} diff --git a/module/subu-0/subudb-number.cli.c b/module/subu-0/subudb-number.cli.c deleted file mode 100644 index 60304e3..0000000 --- a/module/subu-0/subudb-number.cli.c +++ /dev/null @@ -1,63 +0,0 @@ -/* -Set or get a new maximum subu number. Currently doesn't do the setting part. - -*/ -#include "subudb-number.cli.h" -#include -#include -#include - -int main(int argc, char **argv){ - - if( argc < 1 || argc > 2){ - fprintf(stderr, "usage: %s [n]\n",argv[0]); - return SUBU_ERR_ARG_CNT; - } - - int rc; - sqlite3 *db; - rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); - if( rc != SQLITE_OK ){ - fprintf(stderr, "error exit, could not open db file\n"); - sqlite3_close(db); - return SUBU_ERR_DB_FILE; - } - - // then arg[1] holds a number to set the max to - if(argc == 2){ - long int i = strtol(argv[1], NULL, 10); - if( i < 0 ){ - fprintf(stderr, "n must be positive\n"); - sqlite3_close(db); - return SUBU_ERR_N; - } - if( i > INT_MAX ){ - fprintf(stderr, "n is too big, max supported by this program is %d\n", INT_MAX); - sqlite3_close(db); - return SUBU_ERR_N; - } - rc = subudb_number_set(db, i); - if( rc != SQLITE_OK ){ - fprintf(stderr, "couldn't set Max_Subunumber: %s\n", sqlite3_errmsg(db)); - return SUBU_ERR_N; - } - } - - // read and print the current max - int n; - rc = subudb_number_get(db, &n); - if( rc == SQLITE_OK ){ - printf("%d\n", n); - }else{ - fprintf(stderr, "couldn't get Max_Subunumber: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - return SUBU_ERR_DB_FILE; - } - rc = sqlite3_close(db); - if( rc != SQLITE_OK ){ - fprintf(stderr, "when closing db, %s\n", sqlite3_errmsg(db)); - return SUBU_ERR_DB_FILE; - } - return 0; - -} diff --git a/module/subu-0/subudb-rel-get.cli.c b/module/subu-0/subudb-rel-get.cli.c deleted file mode 100644 index 9828b15..0000000 --- a/module/subu-0/subudb-rel-get.cli.c +++ /dev/null @@ -1,42 +0,0 @@ -/* -get the username from the db file -for testing subudb_Masteru_Subu_get_subu_username - -*/ -#include "subudb-rel-get.cli.h" -#include -#include - -int main(int argc, char **argv){ - - if(argc != 3){ - fprintf(stderr, "usage: %s masteru_name subuname\n", argv[0]); - return SUBU_ERR_ARG_CNT; - } - - int rc; - sqlite3 *db; - rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); - if( rc != SQLITE_OK ){ - fprintf(stderr, "could not open db file \"%s\"\n", DB_File); - return SUBU_ERR_DB_FILE; - } - - char *masteru_name = argv[1]; - char *subuname = argv[2]; - char *subu_username; - - int ret = subudb_Masteru_Subu_get_subu_username(db, masteru_name, subuname, &subu_username); - if( ret != SQLITE_DONE ){ - fprintf(stderr, "subudb_Masteru_Subu_get_subu_username indicates failure by returning %d\n",ret); - fprintf(stderr, "sqlite3 issues message, %s\n", sqlite3_errmsg(db)); - return SUBU_ERR_DB_FILE; - } - ret = sqlite3_close(db); - if( ret != SQLITE_OK ){ - fprintf(stderr, "sqlite3_close(db) indicates failure by returning %d\n",ret); - fprintf(stderr, "sqlite3 issues message: %s\n", sqlite3_errmsg(db)); - return SUBU_ERR_DB_FILE; - } - return 0; -} diff --git a/module/subu-0/subudb-rel-put.cli.c b/module/subu-0/subudb-rel-put.cli.c deleted file mode 100644 index b19896e..0000000 --- a/module/subu-0/subudb-rel-put.cli.c +++ /dev/null @@ -1,40 +0,0 @@ -/* -puts a relation in the masteru/subu table - -*/ -#include "subudb-rel-put.cli.h" -#include -#include - -int main(int argc, char **argv){ - - if(argc != 4){ - fprintf(stderr, "expected: %s masteru_name subuname subu_username\n", argv[0]); - return 1; - } - char *masteru_name = argv[1]; - char *subuname = argv[2]; - char *subu_username = argv[3]; - - sqlite3 *db; - { - int ret = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); - if( ret != SQLITE_OK ){ - fprintf(stderr, "could not open db file \"%s\"\n", DB_File); - return SUBU_ERR_DB_FILE; - }} - - int ret = subudb_Masteru_Subu_put(db, masteru_name, subuname, subu_username); - if( ret != SQLITE_OK ){ - fprintf(stderr, "subudb_Masteru_Subu_put indicates failure by returning %d\n",ret); - fprintf(stderr, "sqlite3 issues message, %s\n", sqlite3_errmsg(db)); - return SUBU_ERR_DB_FILE; - } - ret = sqlite3_close(db); - if( ret != SQLITE_OK ){ - fprintf(stderr, "sqlite3_close(db) indicates failure by returning %d\n",ret); - fprintf(stderr, "sqlite3 issues message: %s\n", sqlite3_errmsg(db)); - return SUBU_ERR_DB_FILE; - } - return 0; -} diff --git a/module/subu-0/subudb-rel-rm.cli.c b/module/subu-0/subudb-rel-rm.cli.c deleted file mode 100644 index 3d15ca9..0000000 --- a/module/subu-0/subudb-rel-rm.cli.c +++ /dev/null @@ -1,41 +0,0 @@ -/* -puts a relation in the masteru/subu table - -*/ -#include "subudb-rel-rm.cli.h" -#include -#include - -int main(int argc, char **argv){ - - if(argc != 4){ - fprintf(stderr, "expected: %s masteru_name subuname subu_username\n", argv[0]); - return 1; - } - char *masteru_name = argv[1]; - char *subuname = argv[2]; - char *subu_username = argv[3]; - - sqlite3 *db; - { - int ret = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); - if( ret != SQLITE_OK ){ - fprintf(stderr, "could not open db file \"%s\"\n", DB_File); - return SUBU_ERR_DB_FILE; - }} - - int ret = subudb_Masteru_Subu_rm(db, masteru_name, subuname, subu_username); - if( ret != SQLITE_DONE ){ - fprintf(stderr, "subudb_Masteru_Subu_rm indicates failure by returning %d\n",ret); - fprintf(stderr, "sqlite3 issues message, %s\n", sqlite3_errmsg(db)); - printf("put failed\n"); - return 2; - } - ret = sqlite3_close(db); - if( ret != SQLITE_OK ){ - fprintf(stderr, "sqlite3_close(db) indicates failure by returning %d\n",ret); - fprintf(stderr, "sqlite3 issues message: %s\n", sqlite3_errmsg(db)); - return SUBU_ERR_DB_FILE; - } - return 0; -} diff --git a/module/subu-0/subudb-subus.cli.c b/module/subu-0/subudb-subus.cli.c deleted file mode 100644 index be3af20..0000000 --- a/module/subu-0/subudb-subus.cli.c +++ /dev/null @@ -1,47 +0,0 @@ -/* -Set or get a new maximum subu number. Currently doesn't do the setting part. - -*/ -#include "subudb-subus.cli.h" -#include -#include -#include - -int main(int argc, char **argv){ - - if( argc != 2){ - fprintf(stderr, "usage: %s masteru_name\n",argv[0]); - return SUBU_ERR_ARG_CNT; - } - char *masteru_name = argv[1]; - - int rc; - sqlite3 *db; - rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); - if( rc != SQLITE_OK ){ - fprintf(stderr, "error exit, could not open db file\n"); - sqlite3_close(db); - return SUBU_ERR_DB_FILE; - } - - subudb_subu_element *sa; - subudb_subu_element *sa_end; - rc = subudb_Masteru_Subu_get_subus(db, masteru_name, &sa, &sa_end); - if( rc == SQLITE_OK ){ - subudb_subu_element *pt = sa; - while( pt != sa_end ){ - printf("%s %s\n", pt->subuname, pt->subu_username); - pt++; - } - rc = sqlite3_close(db); - if( rc != SQLITE_OK ){ - fprintf(stderr, "when closing db, %s\n", sqlite3_errmsg(db)); - return SUBU_ERR_DB_FILE; - } - return 0; - } - fprintf(stderr, "lookup failed %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - return SUBU_ERR_DB_FILE; - -} diff --git a/module/subu-0/test/0_makefile b/module/subu-0/test/0_makefile new file mode 100644 index 0000000..c16998b --- /dev/null +++ b/module/subu-0/test/0_makefile @@ -0,0 +1,32 @@ +# src/1_tests/0_makefile + +SHELL=/bin/bash + +-include 0_makefile_flags + +MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tools/lib/makefile-cc + +SOURCES=$(wildcard *.c) +HFILES=$(wildcard *.h) + +all: version deps lib execs + +deps: + makeheaders $(SOURCES) $(HFILES) + sed -i '/^ *int *main *(.*)/d' *.h + $(MAKE) $@ + +clean: + $(MAKE) $@ + for i in $(HFILES); do rm $$i; done + +dist-clean: + $(MAKE) $@ + if [ -f subudb ]; then rm subudb; fi + +%:: + $(MAKE) $@ + + + + diff --git a/module/subu-0/test/0_makefile_flags b/module/subu-0/test/0_makefile_flags new file mode 100644 index 0000000..bc6bd25 --- /dev/null +++ b/module/subu-0/test/0_makefile_flags @@ -0,0 +1,31 @@ + +# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo .. +ECHO= echo +#ECHO= echo -e + +# directories used by this makefile, these could all be set to dot for +# the simplest source directory structure + +#LIDBIR, EXECSDIR, HDIR hold the make results that might later be shared +#$(PWD) is the directory that make was called from, this is already build in +#set to dot to use the same directory as the source code +#leave blank to ommit +DEPRDIR= +DOCDIR= +EXECSDIR=. +HDIR=. +LIBDIR=. +TESTDIR=. +TMPDIR=1_tmp +TOOLSDIR=$(realpath $(PROJECT_SUBU)/tools) +TRYDIR= + + +# compiler and flags +CC=gcc +CFLAGS=-std=gnu11 -fPIC -I. -ggdb -Werror -DDEBUG -DDEBUGDB +#CFLAGS=-std=gnu11 -fPIC -I. -Werror +LINKFLAGS=-L$(PROJECT_SUBU)/src/$(LIBDIR) -L. -lsubu -lsqlite3 -lsubutests + +LIBFILE=$(LIBDIR)/libtests.a + diff --git a/module/subu-0/test/1_tmp/makefile_deps b/module/subu-0/test/1_tmp/makefile_deps new file mode 100644 index 0000000..9486ae8 --- /dev/null +++ b/module/subu-0/test/1_tmp/makefile_deps @@ -0,0 +1,4 @@ +da.cli.o: da.cli.c da.cli.h + +./da : da.cli.o ./libtests.a + gcc -o ./da da.cli.o -L/home/morpheus/subu_land/subu/src/. -L. -lsubu -lsqlite3 -lsubutests diff --git a/module/subu-0/test/da.cli.c b/module/subu-0/test/da.cli.c new file mode 100644 index 0000000..910a15e --- /dev/null +++ b/module/subu-0/test/da.cli.c @@ -0,0 +1,50 @@ +/* +Tests for da. + +*/ + +#include +#include + +int test_da_0(){ + da da0; + da_alloc(&da0, sizeof(int)); // leaves room for 4 ints + int i = 0; + int *pt = da0->base; + // will double, 4 -> 8, then double 8 -> 16 + while( i < 10 ){ + if(da_boundq(&da0, pt)){ + char *old_base = da_expand(&da); + da_rebase(&da, old_base, pt); + } + *pt = i; + i++; + pt++; + } + + bool f0 = da.size == sizof(int) * 16; + bool f1 = 10 == (da.end - da.base) / sizeof(int); + bool f2 = true; + pt = da0->base; + while( i < 10 ){ + f2 = f2 && *pt == i && !da_endq(&da, pt); + i++; + pt++; + } + bool f3 = da_endq(&da, pt); + + return f0 && f1 && f2 && f3; +} + + +int main(){ + + bool da_0_passed = test_da_0(); + if( da_0_passed ){ + printf("da_0_passed"); + return 0; + } + printf("da_0_failed"); + return 1; + +} diff --git a/module/subu-0/test/libtests.a b/module/subu-0/test/libtests.a new file mode 100644 index 0000000..8b277f0 --- /dev/null +++ b/module/subu-0/test/libtests.a @@ -0,0 +1 @@ +! diff --git a/module/subu-0/trc/common.lib.c b/module/subu-0/trc/common.lib.c new file mode 100644 index 0000000..fec4853 --- /dev/null +++ b/module/subu-0/trc/common.lib.c @@ -0,0 +1,29 @@ +#tranche common.lib.c +#include "common.lib.h" + +#tranche common.lib.h + typedef unsigned int uint; + /* + Fedora 29's sss_cache is checking the inherited uid instead of the effective + uid, so setuid root scripts will fail when calling sss_cache. + + Fedora 29's 'useradd' calls sss_cache, and useradd is called by our setuid root + program subu-mk-0. + */ + #define BUG_SSS_CACHE_RUID 1 +#tranche-end + +#tranche common.lib.h + // extern char *DB_File; + extern char DB_File[]; + extern uint Subuhome_Perms; + extern uint First_Max_Subunumber; + extern char Subuland_Extension[]; +#tranche-end +// char *DB_File = "/etc/subudb"; +char DB_File[] = "subudb"; +uint Subuhome_Perms = 0700; +uint First_Max_Subunumber = 114; +char Subuland_Extension[] = "/subuland/"; + +#tranche-end diff --git a/module/subu-0/trc/db.lib.c b/module/subu-0/trc/db.lib.c new file mode 100644 index 0000000..17a5419 --- /dev/null +++ b/module/subu-0/trc/db.lib.c @@ -0,0 +1,192 @@ +/* +The db file is maintained in SQLite + +Because user names of are of limited length, subu user names are always named _s. +A separate table translates the numbers into the subu names. + +The first argument is the biggest subu number in the system, or one minus an +starting point for subu numbering. + +currently a unit converted to base 10 will always fit in a 21 bit buffer. + +Each of these returns SQLITE_OK upon success +*/ +#include "subudb.lib.h" + +#if INTERFACE +#include +#endif + +#include +#include +#include +#include + +//-------------------------------------------------------------------------------- +// sqlite transactions don't nest. There is a way to use save points, but still +// we can't just nest transactions. Instead use these wrappers around the whole +// of something that needs to be in a transaction. +int db_begin(sqlite3 *db){ + return sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, NULL); +} +int db_commit(sqlite3 *db){ + return sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL); +} +int db_rollback(sqlite3 *db){ + return sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL); +} + +//-------------------------------------------------------------------------------- +int subudb_schema(sqlite3 *db){ + int rc; + + { // build tables + char sql[] = + "CREATE TABLE Masteru_Subu(masteru_name TEXT, subuname TEXT, subu_username TEXT);" + "CREATE TABLE Attribute_Int(attribute TEXT, value INT);" + ; + rc = sqlite3_exec(db, sql, NULL, NULL, NULL); + if(rc != SQLITE_OK) return rc; + } + + { // data initialization + char *sql = "INSERT INTO Attribute_Int (attribute, value) VALUES ('Max_Subunumber', ?1);"; + sqlite3_stmt *stmt; + sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + sqlite3_bind_int(stmt, 1, First_Max_Subunumber); + rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + if( rc != SQLITE_DONE ) return rc; + } + + return SQLITE_OK; +} + +//-------------------------------------------------------------------------------- +int subudb_number_get(sqlite3 *db, int *n){ + char *sql = "SELECT value FROM Attribute_Int WHERE attribute = 'Max_Subunumber';"; + sqlite3_stmt *stmt; + sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + int rc = sqlite3_step(stmt); + if( rc == SQLITE_ROW ){ + *n = sqlite3_column_int(stmt,0); + rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + if( rc != SQLITE_DONE ) return rc; + return SQLITE_OK; + } + // should have a message return, suppose + sqlite3_finalize(stmt); + return SQLITE_NOTFOUND; +} + +int subudb_number_set(sqlite3 *db, int n){ + int rc; + char *sql = "UPDATE Attribute_Int SET value = ?1 WHERE attribute = 'Max_Subunumber';"; + sqlite3_stmt *stmt; + sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + sqlite3_bind_int(stmt, 1, n); + rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + if( rc == SQLITE_DONE ) return SQLITE_OK; + return rc; +} + +//-------------------------------------------------------------------------------- +// put relation into Masteru_Subu table +int subudb_Masteru_Subu_put(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username){ + char *sql = "INSERT INTO Masteru_Subu VALUES (?1, ?2, ?3);"; + sqlite3_stmt *stmt; + sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + sqlite3_bind_text(stmt, 1, masteru_name, -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, subuname, -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 3, subu_username, -1, SQLITE_STATIC); + int rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + if( rc == SQLITE_DONE ) return SQLITE_OK; + return rc; +} + +//-------------------------------------------------------------------------------- +int subudb_Masteru_Subu_get_subu_username(sqlite3 *db, char *masteru_name, char *subuname, char **subu_username){ + char *sql = "SELECT subu_username FROM Masteru_Subu WHERE masteru_name = ?1 AND subuname = ?2;"; + size_t sql_len = strlen(sql); + sqlite3_stmt *stmt; + int rc; + rc = sqlite3_prepare_v2(db, sql, sql_len, &stmt, NULL); + if( rc != SQLITE_OK ) return rc; + sqlite3_bind_text(stmt, 1, masteru_name, strlen(masteru_name), SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, subuname, strlen(subuname), SQLITE_STATIC); + rc = sqlite3_step(stmt); + if( rc == SQLITE_ROW ){ + const char *username = sqlite3_column_text(stmt, 0); + *subu_username = strdup(username); + }else{ + sqlite3_finalize(stmt); + return rc; // woops this needs to return an error!, be sure it is not SQLITE_DONE + } + rc = sqlite3_step(stmt); + if( rc == SQLITE_DONE ) return SQLITE_OK; + return rc; +} + +//-------------------------------------------------------------------------------- + +// we return and array of subudb_subu_info +#if INTERFACE +struct subudb_subu_element{ + char *subuname; + char *subu_username; +}; +#endif + +int subudb_Masteru_Subu_get_subus +( + sqlite3 *db, + char *masteru_name, + da *subus +){ + char *sql = "SELECT subuname, subu_username" + " FROM Masteru_Subu" + " WHERE masteru_name = ?1;"; + size_t sql_len = strlen(sql); + sqlite3_stmt *stmt; + int rc; + rc = sqlite3_prepare_v2(db, sql, sql_len, &stmt, NULL); + if( rc != SQLITE_OK ) return rc; + sqlite3_bind_text(stmt, 1, masteru_name, strlen(masteru_name), SQLITE_STATIC); + + da_alloc(subus, sizeof(subudb_subu_element)); + subudb_subu_element *pt = (subudb_subu_element *)subus->base; + rc = sqlite3_step(stmt); + while( rc == SQLITE_ROW ){ + if( da_boundq(subus, pt) ){ + char *old_base = da_expand(subus); + da_rebase(subus, old_base, pt); + } + pt->subuname = strdup(sqlite3_column_text(stmt, 0)); + pt->subu_username = strdup(sqlite3_column_text(stmt, 1)); + rc = sqlite3_step(stmt); + pt++; + } + sqlite3_finalize(stmt); + if( rc != SQLITE_DONE ) return rc; + return SQLITE_OK; +} + +//-------------------------------------------------------------------------------- +int subudb_Masteru_Subu_rm(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username){ + char *sql = "DELETE FROM Masteru_Subu WHERE masteru_name = ?1 AND subuname = ?2 AND subu_username = ?3;"; + size_t sql_len = strlen(sql); + sqlite3_stmt *stmt; + int rc; + rc = sqlite3_prepare_v2(db, sql, sql_len, &stmt, NULL); + if( rc != SQLITE_OK ) return rc; + sqlite3_bind_text(stmt, 1, masteru_name, -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, subuname, -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 3, subu_username, -1, SQLITE_STATIC); + rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + if( rc == SQLITE_DONE ) return SQLITE_OK; + return rc; +} diff --git a/module/subu-0/trc/subu-bind-all.cli.c b/module/subu-0/trc/subu-bind-all.cli.c new file mode 100644 index 0000000..e942909 --- /dev/null +++ b/module/subu-0/trc/subu-bind-all.cli.c @@ -0,0 +1,31 @@ +/* +mount all the subu user directories into master's subuland +uses unmount to undo this + +*/ +#include "subu-bind-all.cli.h" +#include +#include + +int main(int argc, char **argv){ + if( argc != 1){ + fprintf(stderr, "%s does not take arguments\n",argv[0]); + return SUBU_ERR_ARG_CNT; + } + + int rc; + sqlite3 *db; + rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); + if( rc != SQLITE_OK ){ + fprintf(stderr, "could not open db file \"%s\"\n", DB_File); + return SUBU_ERR_DB_FILE; + } + + char *mess; + rc = subu_bind_all(&mess, db); + if(rc != 0){ + fprintf(stderr, "subu-bind: %s\n", mess); + return rc; + } + return 0; +} diff --git a/module/subu-0/trc/subu-bind.cli.c b/module/subu-0/trc/subu-bind.cli.c new file mode 100644 index 0000000..f315823 --- /dev/null +++ b/module/subu-0/trc/subu-bind.cli.c @@ -0,0 +1,25 @@ +/* +mount a subu user directory into master's subuland +uses unmount to undo this + +*/ +#include "subu-bind.cli.h" +#include +#include + +int main(int argc, char **argv){ + + if( argc != 4){ + fprintf(stderr, "usage: %s masteru subu_username subuhome\n",argv[0]); + return SUBU_ERR_ARG_CNT; + } + + int rc; + char *mess; + rc = subu_bind(&mess, argv[1], argv[2], argv[3]); + if(rc != 0){ + fprintf(stderr, "subu-bind: %s\n", mess); + return rc; + } + return 0; +} diff --git a/module/subu-0/trc/subu-mk-0.cli.c b/module/subu-0/trc/subu-mk-0.cli.c new file mode 100644 index 0000000..af0888b --- /dev/null +++ b/module/subu-0/trc/subu-mk-0.cli.c @@ -0,0 +1,43 @@ +/* + subu-mk-0 command + +*/ +#include "subu-mk-0.cli.h" +#include +#include + +int main(int argc, char **argv){ + char *command = argv[0]; + if( argc != 2 ){ + fprintf(stderr, "usage: %s subu", command); + return SUBU_ERR_ARG_CNT; + } + char *subuname = argv[1]; + + int rc; + sqlite3 *db; + rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); + if( rc != SQLITE_OK ){ + fprintf(stderr, "error when opening db, %s\n", DB_File); + fprintf(stderr, "sqlite3 says: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return SUBU_ERR_DB_FILE; + } + + char *mess; + rc = subu_mk_0(&mess, db, subuname); + if( rc ){ + subu_err("subu_mk_0", rc, mess); + free(mess); + sqlite3_close(db); + return rc; + } + + rc = sqlite3_close(db); + if( rc != SQLITE_OK ){ + fprintf(stderr, "when closing db, %s\n", sqlite3_errmsg(db)); + return SUBU_ERR_DB_FILE; + } + return 0; + +} diff --git a/module/subu-0/trc/subu-rm-0.cli.c b/module/subu-0/trc/subu-rm-0.cli.c new file mode 100644 index 0000000..a7e5926 --- /dev/null +++ b/module/subu-0/trc/subu-rm-0.cli.c @@ -0,0 +1,32 @@ +/* + subu-mk-0 command + +*/ +#include "subu-rm-0.cli.h" +#include +#include + +int main(int argc, char **argv){ + char *command = argv[0]; + if( argc != 2 ){ + fprintf(stderr, "usage: %s subu", command); + return SUBU_ERR_ARG_CNT; + } + char *subuname = argv[1]; + + sqlite3 *db; + { + int ret = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); + if( ret != SQLITE_OK ){ + fprintf(stderr, "error exit, could not open db file \"%s\"\n", DB_File); + return SUBU_ERR_DB_FILE; + }} + + { + char *mess=0; + int ret = subu_rm_0(&mess, db, subuname); + subu_err("subu_rm_0", ret, mess); + free(mess); + return ret; + } +} diff --git a/module/subu-0/trc/subu.lib.c b/module/subu-0/trc/subu.lib.c new file mode 100644 index 0000000..cd6bc2f --- /dev/null +++ b/module/subu-0/trc/subu.lib.c @@ -0,0 +1,713 @@ +/* + sqllite3 is used to maintain the db file, which is currently compiled + in as /etc/subu.db, (or just subu.db for testing). + + masteru is the user who ran this script. The masteru name comes from getuid + and /etc/passwd. + + subu is a subservient user. The subuname is passed in as an argument. + + subu-mk-0 synthesizes a new user user name s, calls useradd to creat + the new uswer account, and enters the relationship between masteru, subu, and + s in the db file. It is this relation in the db file that + associates the subuname with the s user. + + subu-rm-0 uses userdel to delete the related s user account. It + then removes the relaton from the db file. + + subu-mk-0 and subu-rm-0 are setuid root scripts. + +*/ +#include "subu.lib.h" + +// without this #define we get the warning: implicit declaration of function ‘seteuid’/‘setegid’ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +#if INTERFACE +#include +#include +#include +#endif + +//-------------------------------------------------------------------------------- +// dispatched command errors .. should add mkdir and rmdir ... +// +char *useradd_mess(int err){ + if(err <= 0) return NULL; + char *mess; + switch(err){ + case 1: mess = "can't update password file"; break; + case 2: mess = "invalid command syntax"; break; + case 3: mess = "invalid argument to option"; break; + case 4: mess = "UID already in use (and no -o)"; break; + case 5: mess = "undefined"; break; + case 6: mess = "specified group doesn't exist"; break; + case 7: + case 8: mess = "undefined"; break; + case 9: mess = "username already in use"; break; + case 10: mess = "can't update group file:"; break; + case 11: mess = "undefined"; break; + case 12: mess = "can't create home directory"; break; + case 13: mess = "undefined"; break; + case 14: mess = "can't update SELinux user mapping"; break; + default: mess = "undefined"; break; + } + return strdup(mess); +} +char *userdel_mess(int err){ + if(err <= 0) return NULL; + char *mess; + switch(err){ + case 1: mess = "can't update password file"; break; + case 2: mess = "invalid command syntax"; break; + case 3: + case 4: + case 5: mess = "undefined"; break; + case 6: mess = "specified user doesn't exist"; break; + case 7: + case 8: + case 9: mess = "undefined"; break; + case 10: mess = "can't update group file:"; break; + case 11: mess = "undefined"; break; + case 12: mess = "can't remove home directory"; break; + default: mess = "undefined"; break; + } + return strdup(mess); +} + + +//-------------------------------------------------------------------------------- +// +#if INTERFACE +#define SUBU_ERR_ARG_CNT 1 +#define SUBU_ERR_SETUID_ROOT 2 +#define SUBU_ERR_MALLOC 3 +#define SUBU_ERR_MKDIR_SUBUHOME 4 +#define SUBU_ERR_RMDIR_SUBUHOME 5 +#define SUBU_ERR_SUBUNAME_MALFORMED 6 +#define SUBU_ERR_HOMELESS 7 +#define SUBU_ERR_DB_FILE 8 +#define SUBU_ERR_SUBUHOME_EXISTS 9 +#define SUBU_ERR_BUG_SSS 10 +#define SUBU_ERR_FAILED_USERADD 11 +#define SUBU_ERR_FAILED_USERDEL 12 +#define SUBU_ERR_SUBU_NOT_FOUND 13 +#define SUBU_ERR_N 14 +#define SUBU_ERR_BIND 15 +#endif + +void subu_err(char *fname, int err, char *mess){ + if(!mess) mess = ""; + switch(err){ + case 0: return; + case SUBU_ERR_ARG_CNT: + if(mess[0]) + fprintf(stderr, "Incorrect number of arguments, %s", mess); + else + fprintf(stderr, "Incorrect number of arguments.", mess); + break; + case SUBU_ERR_SETUID_ROOT: + fprintf(stderr, "This program must be run setuid root from a user account."); + break; + case SUBU_ERR_MALLOC: + perror(fname); + break; + case SUBU_ERR_DB_FILE: + fprintf(stderr, "error on %s", DB_File); // DB_File is in common + fprintf(stderr, ": %s", mess); + break; + case SUBU_ERR_HOMELESS: + fprintf(stderr,"Masteru, \"%s\", has no home directory", mess); + break; + case SUBU_ERR_SUBUNAME_MALFORMED: + fprintf(stderr, "subuname, \"%s\" is not in [ _.-a-zA-Z0-9]*", mess); + break; + case SUBU_ERR_SUBUHOME_EXISTS: + fprintf(stderr, "a file system object already exists at subuhome, \"%s\"\n", mess); + break; + case SUBU_ERR_MKDIR_SUBUHOME: + fprintf(stderr, "masteru could not make subuhome, \"%s\"", mess); + break; + case SUBU_ERR_BUG_SSS: + perror(fname); + break; + case SUBU_ERR_FAILED_USERADD: + fprintf(stderr, "%s useradd failed\n", mess); + break; + default: + fprintf(stderr, "unknown error code %d\n", err); + } + fputc('\n', stderr); +} + + +//-------------------------------------------------------------------------------- +// a well formed subuname +// returns the length of the subuname, or -1 +// +static int allowed_subuname(char **mess, char *subuname, size_t *subuname_len){ + char *ch = subuname; + size_t i = 0; + while( + *ch + && + ( *ch >= 'a' && *ch <= 'z' + || + *ch >= 'A' && *ch <= 'Z' + || + *ch >= '0' && *ch <= '9' + || + *ch == '-' + || + *ch == '_' + || + *ch == '.' + || + *ch == ' ' + ) + ){ + ch++; + i++; + } + if( !*ch ){ + *subuname_len = i; + return 0; + }else{ + if(mess) *mess = strdup(subuname); + return SUBU_ERR_SUBUNAME_MALFORMED; + } +} + +//-------------------------------------------------------------------------------- +// dispatched functions +// +static int masteru_mkdir_subuhome(void *arg){ + char *subuhome = (char *) arg; + if( mkdir( subuhome, Subuhome_Perms ) == -1 ){ // find subuhome perms in common + perror("masteru_mkdir_subuhome"); + return SUBU_ERR_MKDIR_SUBUHOME; + } + return 0; +} +static int masteru_rmdir_subuhome(void *arg){ + char *subuhome = (char *) arg; + if( rmdir( subuhome ) == -1 ){ // find subuhome perms in common + perror("masteru_rmdir_subuhome"); + return SUBU_ERR_RMDIR_SUBUHOME; + } + return 0; +} + +//-------------------------------------------------------------------------------- +// build strings +// +static int mk_subu_username(char **mess, sqlite3 *db, char **subu_username){ + int rc,n; + db_begin(db); + if( + (rc = subudb_number_get(db, &n)) + || + (rc = subudb_number_set(db, ++n)) + ){ + db_rollback(db); + return SUBU_ERR_DB_FILE; + } + db_commit(db); + + size_t len = 0; + FILE* name_stream = open_memstream(subu_username, &len); + fprintf(name_stream, "s%d", n); + fclose(name_stream); + return 0; +} + +// man page says that getpwuid strings may not be freed, I don't know how long until they +// are overwritten, so I just make my own copies that can be freed +static int uid_to_name_and_home(uid_t uid, char **name, char **home ){ + struct passwd *pw_record_pt = getpwuid(uid); // reading /etc/passwd + *name = strdup(pw_record_pt->pw_name); + *home = strdup(pw_record_pt->pw_dir); + if( !home || !home[0] || (*home)[0] == '(' ) return SUBU_ERR_HOMELESS; + return 0; +} + +static int username_to_home(char *name, char **home ){ + struct passwd *pw_record_pt = getpwnam(name); // reading /etc/passwd + *home = strdup(pw_record_pt->pw_dir); + if( !home || !home[0] || (*home)[0] == '(' ) return SUBU_ERR_HOMELESS; + return 0; +} + +static int mk_subuland(char *masteru_home, char **subuland){ + size_t masteru_home_len = strlen(masteru_home); + char *Subuland_Extension = "/subuland/"; + size_t Subuland_Extension_len = strlen(Subuland_Extension); + *subuland = (char *)malloc( masteru_home_len + Subuland_Extension_len + 1 ); + if(!*subuland) SUBU_ERR_MALLOC; + strcpy(*subuland, masteru_home); + strcpy(*subuland + masteru_home_len, Subuland_Extension); + return 0; +} + +static int mk_subuhome(char *subuland, char *subuname, char **subuhome){ + size_t subuland_len = strlen(subuland); + size_t subuhome_len = subuland_len + strlen(subuname); // subuland has a trailing '/' + *subuhome = (char *)malloc(subuhome_len + 1); + if(!*subuhome) return SUBU_ERR_MALLOC; + strcpy (*subuhome, subuland); + strcpy (*subuhome + subuland_len, subuname); + return 0; +} + + + +//=============================================================================== +int subu_mk_0(char **mess, sqlite3 *db, char *subuname){ + + int rc; + if(mess)*mess = 0; + da resources; + da_alloc(&resources, sizeof(char *)); + + //-------------------------------------------------------------------------------- + size_t subuname_len; + rc = allowed_subuname(mess, subuname, &subuname_len); + if(rc) return rc; + #ifdef DEBUG + debug_printf("subuname is well formed\n"); + #endif + + //-------------------------------------------------------------------------------- + uid_t masteru_uid; + gid_t masteru_gid; + uid_t set_euid; + gid_t set_egid; + { + masteru_uid = getuid(); + masteru_gid = getgid(); + set_euid = geteuid(); + set_egid = getegid(); + #ifdef DEBUG + debug_printf("masteru_uid %u, masteru_gid %u, set_euid %u set_egid %u\n", masteru_uid, masteru_gid, set_euid, set_egid); + #endif + if( masteru_uid == 0 || set_euid != 0 ) return SUBU_ERR_SETUID_ROOT; + } + + //-------------------------------------------------------------------------------- + char *masteru_name = 0; + char *masteru_home = 0; + char *subu_username = 0; + char *subuland = 0; + char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir + da_push(&resources, masteru_name); + da_push(&resources, masteru_home); + da_push(&resources, subu_username); + da_push(&resources, subuland); + da_push(&resources, subuhome); + rc = + uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home) + || + mk_subu_username(mess, db, &subu_username) + || + mk_subuland(masteru_home, &subuland) + || + mk_subuhome(subuland, subuname, &subuhome) + ; + if(rc) RETURN(&resources, rc); + #ifdef DEBUG + debug_printf("subu_username, subuland, subuhome: \"%s\"\"%s\"\"%s\"\n", subu_username, subuland, subuhome); + #endif + + //-------------------------------------------------------------------------------- + // By having masteru create the subuhome, we know that masteru has rights to + // to access this directory. This will be the mount point for bindfs + { + struct stat st; + if( stat(subuhome, &st) != -1 ){ + if(mess)*mess = strdup(subuhome); + RETURN(&resources, SUBU_ERR_SUBUHOME_EXISTS); + } + int dispatch_err = dispatch_f_euid_egid + ( + "masteru_mkdir_subuhome", + masteru_mkdir_subuhome, + (void *)subuhome, + masteru_uid, + masteru_gid + ); + if( dispatch_err <= ERR_DISPATCH || dispatch_err == SUBU_ERR_MKDIR_SUBUHOME ){ + #ifdef DEBUG + dispatch_f_mess("dispatch_f_euid_egid", dispatch_err, "masteru_mkdir_subuhome"); + #endif + if(mess)*mess = strdup(subuhome); + RETURN(&resources, SUBU_ERR_MKDIR_SUBUHOME); + } + } + #ifdef DEBUG + debug_printf("made directory \"%s\"\n", subuhome); + #endif + + //-------------------------------------------------------------------------------- + // Make the subservient user account, i.e. the subu + { + #ifdef DEBUG + debug_printf("making subu \"%s\" as user \"%s\"\n", subuname, subu_username); + #endif + #if BUG_SSS_CACHE_RUID + #ifdef DEBUG + debug_printf("setting inherited real uid to 0 to accomodate SSS_CACHE UID BUG\n"); + #endif + if( setuid(0) == -1 ) RETURN(&resources, SUBU_ERR_BUG_SSS); + #endif + char *command = "/usr/sbin/useradd"; + char *argv[3]; + argv[0] = command; + argv[1] = subu_username; + argv[2] = (char *) NULL; + char *envp[1]; + envp[0] = (char *) NULL; + int dispatch_err = dispatch_exec(argv, envp); + if( dispatch_err != 0 ){ + #ifdef DEBUG + dispatch_f_mess("dispatch_exec", dispatch_err, command); + #endif + // go back and remove the directory we made in subuland + int dispatch_err_rmdir = dispatch_f_euid_egid + ( + "masteru_rmdir_subuhome", + masteru_rmdir_subuhome, + (void *)subuhome, + masteru_uid, + masteru_gid + ); + #ifdef DEBUG + dispatch_f_mess("dispatch_f_euid_egid", dispatch_err_rmdir, "masteru_rmdir_subuhome"); + #endif + if(mess)*mess = useradd_mess(dispatch_err); + RETURN(&resources, SUBU_ERR_FAILED_USERADD); + } + #ifdef DEBUG + debug_printf("added user \"%s\"\n", subu_username); + #endif + } + + //-------------------------------------------------------------------------------- + #ifdef DEBUG + debug_printf("setting the masteru_name, subuname, subu_username relation\n"); + #endif + { + int rc = subudb_Masteru_Subu_put(db, masteru_name, subuname, subu_username); + if( rc != SQLITE_OK ){ + if(mess)*mess = strdup("insert of masteru subu relation failed"); + RETURN(&resources, SUBU_ERR_DB_FILE); + } + } + #ifdef DEBUG + debug_printf("finished subu-mk-0(%s)\n", subuname); + #endif + RETURN(&resources, 0); +} + +//================================================================================ +int subu_rm_0(char **mess, sqlite3 *db, char *subuname){ + + int rc; + if(mess)*mess = 0; + da resources; + da_alloc(&resources, sizeof(char *)); + + //-------------------------------------------------------------------------------- + size_t subuname_len; + rc = allowed_subuname(mess, subuname, &subuname_len); + if(rc) return rc; + #ifdef DEBUG + debug_printf("subuname is well formed\n"); + #endif + + //-------------------------------------------------------------------------------- + uid_t masteru_uid; + gid_t masteru_gid; + uid_t set_euid; + gid_t set_egid; + { + masteru_uid = getuid(); + masteru_gid = getgid(); + set_euid = geteuid(); + set_egid = getegid(); + #ifdef DEBUG + debug_printf("masteru_uid %u, masteru_gid %u, set_euid %u set_egid %u\n", masteru_uid, masteru_gid, set_euid, set_egid); + #endif + if( masteru_uid == 0 || set_euid != 0 ) return SUBU_ERR_SETUID_ROOT; + } + + //-------------------------------------------------------------------------------- + // various strings that we will need + char *masteru_name = 0; + char *masteru_home = 0; + char *subuland = 0; + char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir + da_push(&resources, masteru_name); + da_push(&resources, masteru_home); + da_push(&resources, subuland); + da_push(&resources, subuhome); + rc = + uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home) + || + mk_subuland(masteru_home, &subuland) + || + mk_subuhome(subuland, subuname, &subuhome) + ; + if(rc) RETURN(&resources, rc); + #ifdef DEBUG + debug_printf("masteru_home, subuhome: \"%s\", \"%s\"\n", masteru_home, subuhome); + #endif + + //-------------------------------------------------------------------------------- + // removal from db + char *subu_username = 0; + da_push(&resources, subu_username); + + db_begin(db); + + rc = subudb_Masteru_Subu_get_subu_username(db, masteru_name, subuname, &subu_username); + if( rc != SQLITE_OK ){ + if(mess) *mess = strdup("subu requested for removal not found under this masteru in db file"); + rc = SUBU_ERR_SUBU_NOT_FOUND; + db_rollback(db); + RETURN(&resources, rc); + } + #ifdef DEBUG + printf("subu_username: \"%s\"\n", subu_username); + #endif + + rc = subudb_Masteru_Subu_rm(db, masteru_name, subuname, subu_username); + if( rc != SQLITE_OK ){ + if(mess)*mess = strdup("removal of masteru subu relation failed"); + db_rollback(db); + RETURN(&resources, SUBU_ERR_DB_FILE); + } + #ifdef DEBUG + debug_printf("removed the masteru_name, subuname, subu_username relation\n"); + #endif + + rc = db_commit(db); + if( rc != SQLITE_OK ){ + if(mess)*mess = strdup("removal of masteru subu relation in unknown state, exiting"); + RETURN(&resources, SUBU_ERR_DB_FILE); + } + + // even after removing the last masteru subu relation, we still do not remove + // the max subu count. Hence, a masteru will keep such for a life time. + + + //-------------------------------------------------------------------------------- + // Only masteru can remove directories from masteru/subuland, so we switch to + // masteru's uid to perform the rmdir. + // + { + #ifdef DEBUG + debug_printf("as masteru, removing the directory \"%s\"\n", subuhome); + #endif + int dispatch_err = dispatch_f_euid_egid + ( + "masteru_rmdir_subuhome", + masteru_rmdir_subuhome, + (void *)subuhome, + masteru_uid, + masteru_gid + ); + if( dispatch_err <= ERR_DISPATCH || dispatch_err == SUBU_ERR_RMDIR_SUBUHOME ){ + #ifdef DEBUG + dispatch_f_mess("dispatch_f_euid_egid", dispatch_err, "masteru_rmdir_subuhome"); + #endif + if(mess)*mess = strdup(subuhome); + RETURN(&resources, SUBU_ERR_RMDIR_SUBUHOME); + } + } + + //-------------------------------------------------------------------------------- + // Delete the subservient user account + { + #ifdef DEBUG + debug_printf("deleting user \"%s\"\n", subu_username); + #endif + #if BUG_SSS_CACHE_RUID + #ifdef DEBUG + debug_printf("setting inherited real uid to 0 to accomodate SSS_CACHE UID BUG\n"); + #endif + if( setuid(0) == -1 ){ + RETURN(&resources, SUBU_ERR_BUG_SSS); + } + #endif + char *command = "/usr/sbin/userdel"; + char *argv[4]; + argv[0] = command; + argv[1] = subu_username; + argv[2] = "-r"; + argv[3] = (char *) NULL; + char *envp[1]; + envp[0] = (char *) NULL; + int dispatch_err = dispatch_exec(argv, envp); + if( dispatch_err != 0 ){ + #ifdef DEBUG + dispatch_f_mess("dispatch_exec", dispatch_err, command); + #endif + if(mess)*mess = userdel_mess(dispatch_err); + RETURN(&resources, SUBU_ERR_FAILED_USERDEL); + } + #ifdef DEBUG + debug_printf("deleted user \"%s\"\n", subu_username); + #endif + } + + #ifdef DEBUG + debug_printf("finished subu-rm-0(%s)\n", subuname); + #endif + RETURN(&resources, 0); +} + +//================================================================================ +// identifies masteru, the bindfs maps each subu_user's home to its mount point +// in subuland. +int subu_bind(char **mess, char *masteru_name, char *subu_username, char *subuhome){ + + int rc; + if(mess)*mess = 0; + da resources; + da_alloc(&resources, sizeof(char *)); + + // lookup the subu_user_home + char *subu_user_home = 0; + da_push(&resources, subu_user_home); + + rc = username_to_home(subu_username, &subu_user_home); + if( rc ){ + if(mess) *mess = strdup("in subu_bind, subu user home directory lookup in /etc/passwd failed."); + RETURN(&resources, rc); + } + + size_t len = 0; + char *map = 0; + da_push(&resources, map); + + FILE* map_stream = open_memstream(&map, &len); + fprintf(map_stream, "--map=%s/%s:@%s/@%s", subu_username, masteru_name, subu_username, masteru_name); + fclose(map_stream); + + char *command = "/usr/bin/bindfs"; + char *argv[5]; + argv[0] = command; + argv[1] = map; + argv[2] = subu_user_home; + argv[3] = subuhome; + argv[4] = (char *) NULL; + char *envp[1]; + envp[0] = (char *) NULL; + int dispatch_err = dispatch_exec(argv, envp); + if( dispatch_err != 0 ){ + #ifdef DEBUG + dispatch_f_mess(command, dispatch_err, "dispatch_exec"); + #endif + if(mess)*mess = strdup("bind failed"); + RETURN(&resources, SUBU_ERR_BIND); + } + #ifdef DEBUG + debug_printf("mapped \"%s\" as \"%s\"\n", subu_user_home, subuhome); + #endif + RETURN(&resources, 0); +} + +int subu_bind_all(char **mess, sqlite3 *db){ + + int rc; + if(mess)*mess = 0; + da resources; + da_alloc(&resources, sizeof(char *)); + + //-------------------------------------------------------------------------------- + uid_t masteru_uid; + gid_t masteru_gid; + uid_t set_euid; + gid_t set_egid; + { + masteru_uid = getuid(); + masteru_gid = getgid(); + set_euid = geteuid(); + set_egid = getegid(); + #ifdef DEBUG + debug_printf("masteru_uid %u, masteru_gid %u, set_euid %u set_egid %u\n", masteru_uid, masteru_gid, set_euid, set_egid); + #endif + if( masteru_uid == 0 || set_euid != 0 ) return SUBU_ERR_SETUID_ROOT; + } + + //-------------------------------------------------------------------------------- + // various strings that we will need + char *masteru_name = 0; + char *masteru_home = 0; + char *subuland = 0; + da_push(&resources, masteru_name); + da_push(&resources, masteru_home); + da_push(&resources, subuland); + rc = + uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home) + || + mk_subuland(masteru_home, &subuland) + ; + if(rc) RETURN(&resources, rc); + #ifdef DEBUG + if(masteru_name) + debug_printf("masteru_name: \"%s\"", masteru_name); + else + debug_printf("masteru_name unknown"); + if(subuland) + debug_printf("subuland: \"%s\"", subuland); + else + debug_printf("subuland unknown"); + debug_printf("\n"); + #endif + + //-------------------------------------------------------------------------------- + da subus; + rc = subudb_Masteru_Subu_get_subus(db, masteru_name, &subus); + if( rc != SQLITE_OK ){ + if(mess)*mess = strdup("db access failed when fetching a list of subus"); + return rc; + } + // a limitation of our error reporting approach is that we can only + // return one error, but here is a loop that might generate many + rc = 0; + char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir + uint err_cnt = 0; + subudb_subu_element *pt = (subudb_subu_element *)(subus.base); + while( !da_endq(&subus,pt) ){ + rc = mk_subuhome(subuland, pt->subuname, &subuhome); + #ifdef DEBUG + if(subuhome) + debug_printf("subuhome: \"%s\"\n", subuhome); + else + debug_printf("subuhome unknown \n"); + #endif + if(!rc) rc = subu_bind(NULL, masteru_name, pt->subu_username, subuhome); + if(rc) err_cnt++; + free(subuhome); + subuhome=0; + pt++; + } + if(err_cnt==1){ + RETURN(&resources, rc); + } + if(err_cnt > 1){ + *mess = strdup("multiple errors occured while binding subus"); + RETURN(&resources, SUBU_ERR_BIND); + } + RETURN(&resources, 0); +} diff --git a/module/subu-0/trc/subudb-init.cli.c b/module/subu-0/trc/subudb-init.cli.c new file mode 100644 index 0000000..714c7e4 --- /dev/null +++ b/module/subu-0/trc/subudb-init.cli.c @@ -0,0 +1,26 @@ +/* +This command initializes the db file. + +*/ +#include "subudb-init.cli.h" +#include + +int main(){ + sqlite3 *db; + if( sqlite3_open(DB_File, &db) != SQLITE_OK ){ + fprintf(stderr, "error exit, could not open db file \"%s\"\n", DB_File); + return SUBU_ERR_DB_FILE; + } + db_begin(db); + if( subudb_schema(db) != SQLITE_OK ){ + db_rollback(db); + fprintf(stderr, "error exit, opened db file but could not build schema\n"); + return SUBU_ERR_DB_FILE; + } + db_commit(db); + if( sqlite3_close(db) != SQLITE_OK ){ + fprintf(stderr, "error exit, could not close the db\n"); + return SUBU_ERR_DB_FILE; + } + return 0; +} diff --git a/module/subu-0/trc/subudb-number.cli.c b/module/subu-0/trc/subudb-number.cli.c new file mode 100644 index 0000000..60304e3 --- /dev/null +++ b/module/subu-0/trc/subudb-number.cli.c @@ -0,0 +1,63 @@ +/* +Set or get a new maximum subu number. Currently doesn't do the setting part. + +*/ +#include "subudb-number.cli.h" +#include +#include +#include + +int main(int argc, char **argv){ + + if( argc < 1 || argc > 2){ + fprintf(stderr, "usage: %s [n]\n",argv[0]); + return SUBU_ERR_ARG_CNT; + } + + int rc; + sqlite3 *db; + rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); + if( rc != SQLITE_OK ){ + fprintf(stderr, "error exit, could not open db file\n"); + sqlite3_close(db); + return SUBU_ERR_DB_FILE; + } + + // then arg[1] holds a number to set the max to + if(argc == 2){ + long int i = strtol(argv[1], NULL, 10); + if( i < 0 ){ + fprintf(stderr, "n must be positive\n"); + sqlite3_close(db); + return SUBU_ERR_N; + } + if( i > INT_MAX ){ + fprintf(stderr, "n is too big, max supported by this program is %d\n", INT_MAX); + sqlite3_close(db); + return SUBU_ERR_N; + } + rc = subudb_number_set(db, i); + if( rc != SQLITE_OK ){ + fprintf(stderr, "couldn't set Max_Subunumber: %s\n", sqlite3_errmsg(db)); + return SUBU_ERR_N; + } + } + + // read and print the current max + int n; + rc = subudb_number_get(db, &n); + if( rc == SQLITE_OK ){ + printf("%d\n", n); + }else{ + fprintf(stderr, "couldn't get Max_Subunumber: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return SUBU_ERR_DB_FILE; + } + rc = sqlite3_close(db); + if( rc != SQLITE_OK ){ + fprintf(stderr, "when closing db, %s\n", sqlite3_errmsg(db)); + return SUBU_ERR_DB_FILE; + } + return 0; + +} diff --git a/module/subu-0/trc/subudb-rel-get.cli.c b/module/subu-0/trc/subudb-rel-get.cli.c new file mode 100644 index 0000000..9828b15 --- /dev/null +++ b/module/subu-0/trc/subudb-rel-get.cli.c @@ -0,0 +1,42 @@ +/* +get the username from the db file +for testing subudb_Masteru_Subu_get_subu_username + +*/ +#include "subudb-rel-get.cli.h" +#include +#include + +int main(int argc, char **argv){ + + if(argc != 3){ + fprintf(stderr, "usage: %s masteru_name subuname\n", argv[0]); + return SUBU_ERR_ARG_CNT; + } + + int rc; + sqlite3 *db; + rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); + if( rc != SQLITE_OK ){ + fprintf(stderr, "could not open db file \"%s\"\n", DB_File); + return SUBU_ERR_DB_FILE; + } + + char *masteru_name = argv[1]; + char *subuname = argv[2]; + char *subu_username; + + int ret = subudb_Masteru_Subu_get_subu_username(db, masteru_name, subuname, &subu_username); + if( ret != SQLITE_DONE ){ + fprintf(stderr, "subudb_Masteru_Subu_get_subu_username indicates failure by returning %d\n",ret); + fprintf(stderr, "sqlite3 issues message, %s\n", sqlite3_errmsg(db)); + return SUBU_ERR_DB_FILE; + } + ret = sqlite3_close(db); + if( ret != SQLITE_OK ){ + fprintf(stderr, "sqlite3_close(db) indicates failure by returning %d\n",ret); + fprintf(stderr, "sqlite3 issues message: %s\n", sqlite3_errmsg(db)); + return SUBU_ERR_DB_FILE; + } + return 0; +} diff --git a/module/subu-0/trc/subudb-rel-put.cli.c b/module/subu-0/trc/subudb-rel-put.cli.c new file mode 100644 index 0000000..b19896e --- /dev/null +++ b/module/subu-0/trc/subudb-rel-put.cli.c @@ -0,0 +1,40 @@ +/* +puts a relation in the masteru/subu table + +*/ +#include "subudb-rel-put.cli.h" +#include +#include + +int main(int argc, char **argv){ + + if(argc != 4){ + fprintf(stderr, "expected: %s masteru_name subuname subu_username\n", argv[0]); + return 1; + } + char *masteru_name = argv[1]; + char *subuname = argv[2]; + char *subu_username = argv[3]; + + sqlite3 *db; + { + int ret = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); + if( ret != SQLITE_OK ){ + fprintf(stderr, "could not open db file \"%s\"\n", DB_File); + return SUBU_ERR_DB_FILE; + }} + + int ret = subudb_Masteru_Subu_put(db, masteru_name, subuname, subu_username); + if( ret != SQLITE_OK ){ + fprintf(stderr, "subudb_Masteru_Subu_put indicates failure by returning %d\n",ret); + fprintf(stderr, "sqlite3 issues message, %s\n", sqlite3_errmsg(db)); + return SUBU_ERR_DB_FILE; + } + ret = sqlite3_close(db); + if( ret != SQLITE_OK ){ + fprintf(stderr, "sqlite3_close(db) indicates failure by returning %d\n",ret); + fprintf(stderr, "sqlite3 issues message: %s\n", sqlite3_errmsg(db)); + return SUBU_ERR_DB_FILE; + } + return 0; +} diff --git a/module/subu-0/trc/subudb-rel-rm.cli.c b/module/subu-0/trc/subudb-rel-rm.cli.c new file mode 100644 index 0000000..3d15ca9 --- /dev/null +++ b/module/subu-0/trc/subudb-rel-rm.cli.c @@ -0,0 +1,41 @@ +/* +puts a relation in the masteru/subu table + +*/ +#include "subudb-rel-rm.cli.h" +#include +#include + +int main(int argc, char **argv){ + + if(argc != 4){ + fprintf(stderr, "expected: %s masteru_name subuname subu_username\n", argv[0]); + return 1; + } + char *masteru_name = argv[1]; + char *subuname = argv[2]; + char *subu_username = argv[3]; + + sqlite3 *db; + { + int ret = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); + if( ret != SQLITE_OK ){ + fprintf(stderr, "could not open db file \"%s\"\n", DB_File); + return SUBU_ERR_DB_FILE; + }} + + int ret = subudb_Masteru_Subu_rm(db, masteru_name, subuname, subu_username); + if( ret != SQLITE_DONE ){ + fprintf(stderr, "subudb_Masteru_Subu_rm indicates failure by returning %d\n",ret); + fprintf(stderr, "sqlite3 issues message, %s\n", sqlite3_errmsg(db)); + printf("put failed\n"); + return 2; + } + ret = sqlite3_close(db); + if( ret != SQLITE_OK ){ + fprintf(stderr, "sqlite3_close(db) indicates failure by returning %d\n",ret); + fprintf(stderr, "sqlite3 issues message: %s\n", sqlite3_errmsg(db)); + return SUBU_ERR_DB_FILE; + } + return 0; +} diff --git a/module/subu-0/trc/subudb-subus.cli.c b/module/subu-0/trc/subudb-subus.cli.c new file mode 100644 index 0000000..be3af20 --- /dev/null +++ b/module/subu-0/trc/subudb-subus.cli.c @@ -0,0 +1,47 @@ +/* +Set or get a new maximum subu number. Currently doesn't do the setting part. + +*/ +#include "subudb-subus.cli.h" +#include +#include +#include + +int main(int argc, char **argv){ + + if( argc != 2){ + fprintf(stderr, "usage: %s masteru_name\n",argv[0]); + return SUBU_ERR_ARG_CNT; + } + char *masteru_name = argv[1]; + + int rc; + sqlite3 *db; + rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL); + if( rc != SQLITE_OK ){ + fprintf(stderr, "error exit, could not open db file\n"); + sqlite3_close(db); + return SUBU_ERR_DB_FILE; + } + + subudb_subu_element *sa; + subudb_subu_element *sa_end; + rc = subudb_Masteru_Subu_get_subus(db, masteru_name, &sa, &sa_end); + if( rc == SQLITE_OK ){ + subudb_subu_element *pt = sa; + while( pt != sa_end ){ + printf("%s %s\n", pt->subuname, pt->subu_username); + pt++; + } + rc = sqlite3_close(db); + if( rc != SQLITE_OK ){ + fprintf(stderr, "when closing db, %s\n", sqlite3_errmsg(db)); + return SUBU_ERR_DB_FILE; + } + return 0; + } + fprintf(stderr, "lookup failed %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return SUBU_ERR_DB_FILE; + +} diff --git a/module/subu-0/try/split.c b/module/subu-0/try/split.c new file mode 100644 index 0000000..6d4c6ac --- /dev/null +++ b/module/subu-0/try/split.c @@ -0,0 +1,20 @@ +/* +Using preprocessor to make header file? + +gcc -E split.c -DPROTOTYPE + +Outputs source code source comment lines starting with a hash. Resolves all macro commands, +hence the resulting header can not have macro commands. + + */ + +#if PROTOTYPE +##define GREATNESS 21 +int f(int x); +#endif + +#if IMPLEMENTATION +int f(int x){ + return x; +} +#endif diff --git a/module/subu-0/try/split_arg.c b/module/subu-0/try/split_arg.c new file mode 100644 index 0000000..6d4c6ac --- /dev/null +++ b/module/subu-0/try/split_arg.c @@ -0,0 +1,20 @@ +/* +Using preprocessor to make header file? + +gcc -E split.c -DPROTOTYPE + +Outputs source code source comment lines starting with a hash. Resolves all macro commands, +hence the resulting header can not have macro commands. + + */ + +#if PROTOTYPE +##define GREATNESS 21 +int f(int x); +#endif + +#if IMPLEMENTATION +int f(int x){ + return x; +} +#endif diff --git a/module/subu-0/try/subudb b/module/subu-0/try/subudb new file mode 100644 index 0000000..e69de29 diff --git a/module/subu-0/try/voidptr.c b/module/subu-0/try/voidptr.c new file mode 100644 index 0000000..bd9c3e5 --- /dev/null +++ b/module/subu-0/try/voidptr.c @@ -0,0 +1,48 @@ +/* +They say a cast is not required passing a typed pointer to a void * argument, +but What about void **? + +gcc -std=gnu11 -o voidptr voidptr.c +voidptr.c: In function ‘main’: +voidptr.c:28:5: warning: passing argument 1 of ‘g’ from incompatible pointer type [-Wincompatible-pointer-types] + g(&pt, y); + ^~~ +voidptr.c:13:15: note: expected ‘void **’ but argument is of type ‘int **’ + void g(void **pt0, void *pt1){ + ~~~~~~~^~~ + +*/ +#include + +int f(void *pt){ + return *(int *)pt; +} + +/* fails +void g(void **pt0, int *pt1){ + *pt0 = pt1; +} +*/ + +// passes +void g(void *pt0, int *pt1){ + *(int **)pt0 = pt1; +} + +int main(){ + int x = 5; + int *xp = &x; + printf("%d\n",f(xp)); + + int y[3]; + y[0] = 10; + y[1] = 11; + y[2] = 12; + + int *pt; + g(&pt, y); + printf("%d\n",*pt); + + printf("that's all folks\n"); + return 0; +} diff --git a/module/temp b/module/temp deleted file mode 100644 index 7b6ed6e..0000000 --- a/module/temp +++ /dev/null @@ -1,10 +0,0 @@ -sed -i -e 's/makefile_cc/makefile-cc/g' ./db/0_makefile -sed -i -e 's/makefile_cc/makefile-cc/g' ./subu-0/1_tests/0_makefile -sed -i -e 's/makefile_cc/makefile-cc/g' ./subu-0/0_makefile -sed -i -e 's/makefile_cc/makefile-cc/g' ./tranche/deprecated/0_makefile -sed -i -e 's/makefile_cc/makefile-cc/g' ./tranche/makefile-flags -sed -i -e 's/makefile_cc/makefile-cc/g' ./tranche/makefile-flags -sed -i -e 's/makefile_cc/makefile-cc/g' ./da/test/makefile-flags -sed -i -e 's/makefile_cc/makefile-cc/g' ./da/test/makefile-flags -sed -i -e 's/makefile_cc/makefile-cc/g' ./da/makefile-flags -sed -i -e 's/makefile_cc/makefile-cc/g' ./da/makefile-flags diff --git a/module/tranche/makefile b/module/tranche/makefile index 24e7cfa..2c21909 100644 --- a/module/tranche/makefile +++ b/module/tranche/makefile @@ -17,7 +17,7 @@ dep: .PHONY: lib lib: $(MAKE) $@ - cp src/tranche.lib.h include/tranche.h + cp $(SRCDIR)/tranche.lib.h include/tranche.h .PHONY: exec exec: diff --git a/module/tranche/src/tranche.lib.c b/module/tranche/src/tranche.lib.c index 787ff4f..65e66c1 100644 --- a/module/tranche/src/tranche.lib.c +++ b/module/tranche/src/tranche.lib.c @@ -203,7 +203,13 @@ void tranche_make(FILE *src_file, char *src_name, int mfile_fd, char *tdir){ da_free_elements(tap); da_free(tap); - // output acction line ---------------------------------------- + // output action lines ---------------------------------------- + da_rewind(dlap); // reuse the line buffer + da_push(dlap, &tab); + da_string_push(dlap, "for i in $@; do rm $$i || true; done"); + da_push(dlap, &newline); + write(mfile_fd, dlap->base, dlap->end - dlap->base); + da_rewind(dlap); // reuse the line buffer da_push(dlap, &tab); da_string_push(dlap, "tranche $<"); @@ -214,7 +220,7 @@ void tranche_make(FILE *src_file, char *src_name, int mfile_fd, char *tdir){ da_push(dlap, &newline); da_push(dlap, &newline); write(mfile_fd, dlap->base, dlap->end - dlap->base); - da_free(dlap); + da_free(dlap); return; } diff --git a/tool/bin/tranche b/tool/bin/tranche index 79da91b..31fdc5d 100755 Binary files a/tool/bin/tranche and b/tool/bin/tranche differ diff --git a/tool/bin/tranche-make b/tool/bin/tranche-make index 655e088..ae00d98 100755 Binary files a/tool/bin/tranche-make and b/tool/bin/tranche-make differ diff --git a/tool/bin/tranche-target b/tool/bin/tranche-target index 29765df..4415c1a 100755 Binary files a/tool/bin/tranche-target and b/tool/bin/tranche-target differ diff --git a/tool/lib/dot_emacs b/tool/lib/dot_emacs index 27132b6..d6d5245 100755 --- a/tool/lib/dot_emacs +++ b/tool/lib/dot_emacs @@ -1,36 +1,5 @@ - -(defun undedicate-window (&optional window) - (interactive) - (set-window-dedicated-p (or window (get-buffer-window)) nil)) - -;; Removing annoying dedicated buffer nonsense -(defun switch-to-buffer! (buffer-or-name &optional norecord force-same-window) - "Like switch-to-buffer but works for dedicated buffers \(though -it will ask first)." - (interactive - (list (read-buffer-to-switch "Switch to buffer: ") nil 'force-same-window)) - (when (and (window-dedicated-p (get-buffer-window)) - (yes-or-no-p "This window is dedicated, undedicate it? ")) - (undedicate-window)) - (switch-to-buffer buffer-or-name norecord force-same-window)) - -(defun toggle-window-dedication (&optional window) - (interactive) - (let ((window (or window (get-buffer-window)))) - (set-window-dedicated-p window (not (window-dedicated-p window))))) - -(global-set-key (kbd "C-x d") 'toggle-window-dedication) - -;; fix 'feature' of broken gdb where it takes control of an +;; inspired by dumb 'feature' of gdb where it takes control of an ;; emacs window, and locks the user out from switching from it -;; -;; yes and this fix breaks file name completion... -;; -;; (defun set-window-undedicated-p (window flag) -;; "Never set window dedicated." -;; flag) -;; (advice-add 'set-window-dedicated-p :override #'set-window-undedicated-p) -;; ;; Toggle window dedication (defun toggle-window-dedicated () @@ -44,7 +13,7 @@ it will ask first)." "Window '%s' is normal") (current-buffer))) - (global-set-key "\C-q" 'toggle-window-dedicated) + (global-set-key (kbd "C-x d") 'toggle-window-dedication) ;; (setq ring-bell-function (lambda () ;; (call-process-shell-command