From: Thomas Walker Lynch Date: Mon, 18 Mar 2019 16:32:25 +0000 (+0100) Subject: adds subu-bind-all; rearranges src tree X-Git-Url: https://git.reasoningtechnology.com/style/static/gitweb.js?a=commitdiff_plain;h=2fcc98aa0294a4d6d1a986be0c15c767172b4aa0;p=subu adds subu-bind-all; rearranges src tree --- diff --git a/7_makefile b/7_makefile deleted file mode 100755 index f170e23..0000000 --- a/7_makefile +++ /dev/null @@ -1,28 +0,0 @@ -#subdirectories=$(shell /usr/bin/find . -maxdepth 1 -printf "%f " | sed y/\./\ /) -#subdirectories=src src/1_tests src/1_try -subdirectories=src - -all : - $(foreach dir, $(subdirectories), \ - if [ -f $(dir)/7_makefile ]; then \ - make -C $(dir) all && make -C $(dir) install; \ - fi;\ - ) - -clean : - $(foreach dir, $(subdirectories), \ - if [ -f ./$(dir)/7_makefile ]; then \ - make -C $(dir) clean; \ - fi;\ - ) - -dist-clean : - $(foreach dir, $(subdirectories), \ - if [ -f ./$(dir)/7_makefile ]; then \ - make -C $(dir) dist-clean; \ - fi;\ - ) - - - - diff --git a/makefile b/makefile new file mode 100755 index 0000000..98808e5 --- /dev/null +++ b/makefile @@ -0,0 +1,26 @@ +#subdirectories=$(shell /usr/bin/find . -maxdepth 1 -printf "%f " | sed y/\./\ /) +#subdirectories=src src/1_tests src/1_try +subdirectories=src + +all : + $(foreach dir, $(subdirectories), \ + if [ -f $(dir)/7_makefile ]; then \ + make -C $(dir) all && make -C $(dir) install; \ + fi;\ + ) + +clean : + $(foreach dir, $(subdirectories), \ + cd $(dir);\ + make clean;\ + ) + +dist-clean : + $(foreach dir, $(subdirectories), \ + cd $(dir);\ + make dist-clean;\ + ) + + + + diff --git a/src/0_makefile b/src/0_makefile new file mode 100755 index 0000000..528caae --- /dev/null +++ b/src/0_makefile @@ -0,0 +1,187 @@ + +SHELL=/bin/bash + +# 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 + +#$(PWD) is the directory that make was called from, this is already build in +TMPDIR=1_tmp +EXECSDIR=1_execs +HDIR=1_headers +LIBDIR=1_lib +TOOLSDIR=$(realpath ../tools) + +# some important files +DEPS_FILE=$(TMPDIR)/makefile_deps +LIB_FILE=$(LIBDIR)/libsubu.a + +# external tools called out in this makefile +SUID_TOOL=$(TOOLSDIR)/bin/setuid_root.sh + +# 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 + +### end of user defined variables +###-------------------------------------------------------------------------------- + +# a single space literal, for example if you wanted to subsitute commas to +# spaces: $(subst $(space),;,$(string)) we ran into this out of a need to send +# multiple separate command arguments to a shell script from one variable value +blank := +space :=$(blank) $(blank) + +# files used by the compiler +SOURCES_LIB= $(wildcard *.lib.c) +SOURCES_CLI= $(wildcard *.cli.c) +SOURCES= $(SOURCES_LIB) $(SOURCES_CLI) + +HFILES = $(wildcard *.lib.h) $(wildcard *.cli.h) + +OBJECTS_LIB= $(patsubst %.c, %.o, $(SOURCES_LIB)) +OBJECTS_CLI= $(patsubst %.c, %.o, $(SOURCES_CLI)) +OBJECTS= $(OBJECTS_LIB) $(OBJECTS_CLI) + +EXECS= $(sort $(patsubst %.cli.c, %, $(wildcard *.cli.c))) + +all: version deps lib execs + +version: + @echo '---- make $@:------------------------------------------------------------' + @echo makefile version 3.0 + @echo "PWD: " $(PWD) + @echo "MAKEFILE_LIST: " $(MAKEFILE_LIST) + @echo "TMPDIR: " $(TMPDIR) + @echo "EXECSDIR: " $(EXECSDIR) + @echo "HDIR: " $(HDIR) + @echo "LIBDIR: " $(LIBDIR) + @echo "DEPS_FILE: " $(DEPS_FILE) + @echo "LIB_FILE: " $(LIB_FILE) + @echo "CC: " $(CC) + @echo "CFLAGS: " $(CFLAGS) + @echo "LINKFLAGS: " $(LINKFLAGS) + @echo "SUID_TOOL: " $(SUID_TOOL) + @echo '______end make $@_____' + +lists: + @echo '---- make $@:------------------------------------------------------------' + @echo "SOURCES_LIB: " $(SOURCES_LIB) + @echo "SOURCES_CLI: " $(SOURCES_CLI) + @echo "SOURCES: " $(SOURCES) + @echo "HFILES: " $(HFILES) + @echo "OBJECTS_LIB: " $(OBJECTS_LIB) + @echo "OBJECTS_CLI: " $(OBJECTS_CLI) + @echo "OBJECTS: " $(OBJECTS) + @echo "EXECS: " $(EXECS) + @echo '______end make $@_____' + +# should be safe to run this in an already setup or partially setup directory +setup: + @echo '---- make $@:------------------------------------------------------------' + @echo `pwd`'>' + if [ ! -e $(TMPDIR) ]; then mkdir $(TMPDIR); fi + if [ ! -e 1_deprecated ]; then mkdir 1_deprecated; fi + if [ ! -e 1_doc ]; then mkdir 1_doc; fi + if [ ! -e 1_execs ]; then mkdir 1_execs; fi + if [ ! -e 1_headers ]; then mkdir 1_headers; fi + if [ ! -e 1_lib ]; then mkdir 1_lib; fi + if [ ! -e 1_tests ]; then mkdir 1_tests; fi + if [ ! -e 1_try ]; then mkdir 1_try; fi + @echo '______end make $@_____' + +deps: + @echo '---- make $@:------------------------------------------------------------' + @echo `pwd`'>' + makeheaders $(SOURCES) $(HFILES) + sed -i '/^ *int *main *(.*)/d' *.h + $(CC) $(CFLAGS) -MM $(SOURCES) 1> $(DEPS_FILE) + for i in $(EXECS) ; do\ + $(ECHO) >> $(DEPS_FILE);\ + $(ECHO) "$(EXECSDIR)/$$i : $$i.cli.o $(LIB_FILE)" >> $(DEPS_FILE);\ + $(ECHO) " $(CC) -o $(EXECSDIR)/$$i $$i.cli.o $(LINKFLAGS)" >> $(DEPS_FILE);\ + done + @echo '______end make $@_____' + +lib: + @echo '---- make $@:------------------------------------------------------------' + @echo `pwd`'>' + if [ ! -e $(DEPS_FILE) ]; then make deps; fi + make sub_lib + @echo '______end make $@_____' + +sub_lib: $(LIB_FILE) + + +execs: $(LIB_FILE) + @echo '---- make $@:------------------------------------------------------------' + @echo `pwd`'>' + if [ ! -e $(DEPS_FILE) ]; then make deps; fi + make sub_execs + @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 + @echo '______end make $@_____' + +sub_execs: $(patsubst %, $(EXECSDIR)/%, $(EXECS)) + +#not ready yet +install: all + @echo '---- make $@:------------------------------------------------------------' + @echo `pwd`'>' + @if[ ! -e 1_tests_passed ]; then echo "can't install as tests have not passed"; fi + @test -e test_passed + for i in $(EXECSDIR); do cp $$i $(RT_BASE)/bin; done + cp $(LIB_FILE) $(RT_BASE)/lib + cp $(APPLICATION).h $(RT_BASE)/include + if [ -d $(APPLICATION) ]; then cp $(APPLICATION)/*.h $(RT_BASE)/include/$(APPLICATION); fi + @echo '______end make $@_____' + +# not written yet +# copies stuff from the src dir to the stage dirs +# stage: + +clean: + @echo '---- make $@:------------------------------------------------------------' + @echo `pwd`'>' + if [ -f subudb ]; then rm subudb; fi + for i in $(wildcard *~); do mv $$i $(TMPDIR); done + for i in $(wildcard *.lib.o) $(wildcard *.cli.o); do rm $$i; done + for i in $(HFILES); do mv $$i $(TMPDIR); done # just in case someone wrote a header file + for i in $(EXECS); do if [ -e $(EXECSDIR)/$$i ]; then rm $(EXECSDIR)/$$i; fi; done + if [ -f $(LIB_FILE) ]; then rm $(LIB_FILE); fi + if [ -f $(DEPS_FILE) ]; then rm $(DEPS_FILE); fi + @echo '______end make $@_____' + + +# not ready ... +# dist_clean is used to clean thing up before doing a checkin, hg add should be safe after a dist_clean +# dist_clean will recurse into the include directory = $(APPLICATION), tests, and try if they are present +# +dist-clean: + @echo '---- make $@:------------------------------------------------------------' + @echo `pwd`'>' + make clean +# if [ -d $(APPLICATION) ]; then cd $(APPLICATION); make clean; fi +# if [ -d 1_tests ]; then cd 1_tests; make dist_clean; fi +# if [ -d 1_try ] ; then cd 1_try; make dist_clean; fi + @echo '______end make $@_____' + +# +$(LIB_FILE) : $(OBJECTS_LIB) + ar rcs $(LIB_FILE) $(OBJECTS_LIB) + +-include $(DEPS_FILE) + +# recipe for making object files: +# +%.o : %.c + $(CC) $(CFLAGS) -c $< + + diff --git a/src/1_deprecated/dispatch_exec.lib.c b/src/1_deprecated/dispatch_exec.lib.c new file mode 100644 index 0000000..024bff8 --- /dev/null +++ b/src/1_deprecated/dispatch_exec.lib.c @@ -0,0 +1,60 @@ +/* + 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/src/1_deprecated/dispatch_f.lib.c b/src/1_deprecated/dispatch_f.lib.c new file mode 100644 index 0000000..5c199f5 --- /dev/null +++ b/src/1_deprecated/dispatch_f.lib.c @@ -0,0 +1,130 @@ +/* + 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/src/1_deprecated/dispatch_useradd.lib.c b/src/1_deprecated/dispatch_useradd.lib.c new file mode 100644 index 0000000..7b75291 --- /dev/null +++ b/src/1_deprecated/dispatch_useradd.lib.c @@ -0,0 +1,68 @@ +/* +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/src/1_deprecated/subu-rm-0.lib.c b/src/1_deprecated/subu-rm-0.lib.c new file mode 100644 index 0000000..ccad437 --- /dev/null +++ b/src/1_deprecated/subu-rm-0.lib.c @@ -0,0 +1,381 @@ +/* + 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/src/1_deprecated/subudb-number-next.cli.c b/src/1_deprecated/subudb-number-next.cli.c new file mode 100644 index 0000000..3373173 --- /dev/null +++ b/src/1_deprecated/subudb-number-next.cli.c @@ -0,0 +1,45 @@ +/* +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/src/1_doc/README.txt b/src/1_doc/README.txt new file mode 100644 index 0000000..a9a2b21 --- /dev/null +++ b/src/1_doc/README.txt @@ -0,0 +1,23 @@ + + +filename.tag.extension + +extension: + .c for C source + .cc for C++ source + .h for C header file + .hh for C++ header file + .o an object file + +tag: + .lib. The resulting .o file to be placed in release library and is part of the + programming interface. + .aux. The resulting.o file not directly part of the programming interface, but + it might be called by functions that are. + .cli. The source file has a main call and is to be relased as part of the command line interface + .loc. file has a main call to be made into a local uitlity function + +We carry the source file tag and extension to the .o file. We do not put tags +nor extensions on command line executables. + +local_common.h should be included in all source files diff --git a/src/1_doc/makefile.txt b/src/1_doc/makefile.txt new file mode 100644 index 0000000..722de84 --- /dev/null +++ b/src/1_doc/makefile.txt @@ -0,0 +1,91 @@ +these are the comments from my RT makefile: + +# +# 2010 11 20 TWL Created +# 2011 05 26 TWL Modified to generalize +# 2012 02 23 NLS Add ECHO variable to use on different environnement +# corrected setup macro --> add include directory in the path to copy +# corrected install macro --> change the name of installed library : lib$(LIB)$(LIBSUFFIX) +# changed DOC_DIR directory name to 5_documents +# 2012 02 23 TWL removed LIB variable which is now set from the command line so +# so that all source dirs can use the same makefile +# 2012 02 23 TWL added target make dist_clean which also deletes the 2_makefile_deps file +# 2012 04 11 AWW added creation of temporary disk before each test is run +# 2012 06 05 TWL moved tests and try .cc files to directories. caused rtmake tests to +# dist_clean and make deps +# +# +#---------------------------------------------------------------------------- +# use this makefile to compile and test the code: +# +# for a first time run, or for regression use the following: +# +# $ make setup # makes the directories, though should already exist +# $ make regress +# +# the usual development workflow makes use of these: +# +# $ make deps # only when needed, for example if headers includes change or new files introduced +# $ cd tests; make deps # only when needed +# $ make lib # this makes the local library +# $ make tests # this updates tests and compiles +# $ make clean # deletes the .o files and library to force a recompile +# $ cd 1_tests; make clean +# +# for a release of a component +# +# $ make regress +# $ make install # this will only work if all the tests in 1_tests are passing +# +# before a checkin +# +# $ make dist_clean # will also clean the tests and try directories +# +# .lib.cc c++ files taken as source of object files for local build library +# .exl.cc c++ files taken to have main calls and are linked against local build libary +# .ex.cc c++ files taken to have main calls and are not linked against the local build library +# there are no rules for other files in this makefile +# +# about dependencies +# The makefile has no way of knowing if an edit changed the dependencies. Often they do not +# and it would be unwieldy to make the deps every time. Hence *the programmer* must delete +# the deps file if he has made any changes that change the dependencies. +# +# The makefile will make the 2_makefile_deps if the file is missing. +# +# +# about testing +# +# the name of the directory you run make in is taken to also be: the name of the library, +# the name of the main include file (with a .h added), and the name of the include directory +# where the individual headers are found. It is called LIB +# +# test programs are kept in a subdirectory called 1_tests, and are either .exl.cc, ex.cc, +# .sh files. When 'make tests' target is invoked they are all run. Test executables return 0 +# if the test fails, non-zero otherwise. +# +# to remove a test from the pool move it into the subdirectory in 1_tests, 9_broken, +# 5_more_tests of 5_scratch. broken tests are things that are known but must be fixed +# before a release. 5_more_tests are tests being worked on. 5_scratch is stuff that is +# probably going to be deleted. if there is a 5_deprecated, that is for good stuff but it +# is no longer used for some reason or other. +# +# There is a standard source code template and a +# messaging convention. Also, the names, by convention,are test_xxxx_ where xxx is a +# hexadecimal series nummber. If all the test executables pass the file 1_TESTS_PASSED is +# left in the directory. Otherwise the file 1_TESTS_FAILED is left in the directory. +# +# about release directory +# +# this is set in the ApplicationBase variable by rt_init +# +# after the tests pass stuff might be copied to the release directory using +# +# make install +# +# the release directory must have these subdirectories: +# +# bin documents include src +# +# +# diff --git a/src/1_doc/makeheaders.txt b/src/1_doc/makeheaders.txt new file mode 100644 index 0000000..5aebda9 --- /dev/null +++ b/src/1_doc/makeheaders.txt @@ -0,0 +1,16 @@ + +This worked to force the include to be part of the interface: + +#if INTERFACE +#include +#endif + +But this did not: + +#if INTERFACE + #include +#endif + +makeheaders looks to be sensitive to indentation + + diff --git a/src/1_doc/sqlite.txt b/src/1_doc/sqlite.txt new file mode 100644 index 0000000..b7f8cbb --- /dev/null +++ b/src/1_doc/sqlite.txt @@ -0,0 +1,15 @@ + +1. + This sql: + + char *sql = + "BEGIN TRANSACTION;" + "UPDATE Key_Int SET value = value + 1 WHERE key = 'max_subu_number';" + "SELECT value FROM Key_Int WHERE key = 'max_subu_number';" + "COMMIT;" + ; + + with sqlite_exec, the call back is called with the data from the select. + + with sqlite_prepare_v2, sqlite_step just returns SQLITE_DONE, and we never + get to see our data from the select. diff --git a/src/1_doc/to_do.txt b/src/1_doc/to_do.txt new file mode 100644 index 0000000..0b989cc --- /dev/null +++ b/src/1_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/src/1_tmp/da.lib.h b/src/1_tmp/da.lib.h new file mode 100644 index 0000000..0f5bb47 --- /dev/null +++ b/src/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/src/1_tmp/dbprintf.lib.h b/src/1_tmp/dbprintf.lib.h new file mode 100644 index 0000000..3056cf6 --- /dev/null +++ b/src/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/src/1_tmp/dispatch.lib.h b/src/1_tmp/dispatch.lib.h new file mode 100644 index 0000000..07e2271 --- /dev/null +++ b/src/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/src/1_tmp/subu-bind-all.cli.h b/src/1_tmp/subu-bind-all.cli.h new file mode 100644 index 0000000..7e52675 --- /dev/null +++ b/src/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/src/1_tmp/subu-bind.cli.h b/src/1_tmp/subu-bind.cli.h new file mode 100644 index 0000000..af12d61 --- /dev/null +++ b/src/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/src/1_tmp/subu-common.lib.h b/src/1_tmp/subu-common.lib.h new file mode 100644 index 0000000..cfdc520 --- /dev/null +++ b/src/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/src/1_tmp/subu-mk-0.cli.h b/src/1_tmp/subu-mk-0.cli.h new file mode 100644 index 0000000..487b509 --- /dev/null +++ b/src/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/src/1_tmp/subu-rm-0.cli.h b/src/1_tmp/subu-rm-0.cli.h new file mode 100644 index 0000000..070bfe8 --- /dev/null +++ b/src/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/src/1_tmp/subu.lib.h b/src/1_tmp/subu.lib.h new file mode 100644 index 0000000..5d072e7 --- /dev/null +++ b/src/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/src/1_tmp/subudb-init.cli.h b/src/1_tmp/subudb-init.cli.h new file mode 100644 index 0000000..4435103 --- /dev/null +++ b/src/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/src/1_tmp/subudb-number.cli.h b/src/1_tmp/subudb-number.cli.h new file mode 100644 index 0000000..c130fbb --- /dev/null +++ b/src/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/src/1_tmp/subudb-rel-get.cli.h b/src/1_tmp/subudb-rel-get.cli.h new file mode 100644 index 0000000..4f335be --- /dev/null +++ b/src/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/src/1_tmp/subudb-rel-put.cli.h b/src/1_tmp/subudb-rel-put.cli.h new file mode 100644 index 0000000..243b3a9 --- /dev/null +++ b/src/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/src/1_tmp/subudb-rel-rm.cli.h b/src/1_tmp/subudb-rel-rm.cli.h new file mode 100644 index 0000000..595427f --- /dev/null +++ b/src/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/src/1_tmp/subudb-subus.cli.h b/src/1_tmp/subudb-subus.cli.h new file mode 100644 index 0000000..16310b7 --- /dev/null +++ b/src/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/src/1_tmp/subudb.lib.h b/src/1_tmp/subudb.lib.h new file mode 100644 index 0000000..be73823 --- /dev/null +++ b/src/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/src/2_doc/README.txt b/src/2_doc/README.txt deleted file mode 100644 index a9a2b21..0000000 --- a/src/2_doc/README.txt +++ /dev/null @@ -1,23 +0,0 @@ - - -filename.tag.extension - -extension: - .c for C source - .cc for C++ source - .h for C header file - .hh for C++ header file - .o an object file - -tag: - .lib. The resulting .o file to be placed in release library and is part of the - programming interface. - .aux. The resulting.o file not directly part of the programming interface, but - it might be called by functions that are. - .cli. The source file has a main call and is to be relased as part of the command line interface - .loc. file has a main call to be made into a local uitlity function - -We carry the source file tag and extension to the .o file. We do not put tags -nor extensions on command line executables. - -local_common.h should be included in all source files diff --git a/src/2_doc/makefile.txt b/src/2_doc/makefile.txt deleted file mode 100644 index 722de84..0000000 --- a/src/2_doc/makefile.txt +++ /dev/null @@ -1,91 +0,0 @@ -these are the comments from my RT makefile: - -# -# 2010 11 20 TWL Created -# 2011 05 26 TWL Modified to generalize -# 2012 02 23 NLS Add ECHO variable to use on different environnement -# corrected setup macro --> add include directory in the path to copy -# corrected install macro --> change the name of installed library : lib$(LIB)$(LIBSUFFIX) -# changed DOC_DIR directory name to 5_documents -# 2012 02 23 TWL removed LIB variable which is now set from the command line so -# so that all source dirs can use the same makefile -# 2012 02 23 TWL added target make dist_clean which also deletes the 2_makefile_deps file -# 2012 04 11 AWW added creation of temporary disk before each test is run -# 2012 06 05 TWL moved tests and try .cc files to directories. caused rtmake tests to -# dist_clean and make deps -# -# -#---------------------------------------------------------------------------- -# use this makefile to compile and test the code: -# -# for a first time run, or for regression use the following: -# -# $ make setup # makes the directories, though should already exist -# $ make regress -# -# the usual development workflow makes use of these: -# -# $ make deps # only when needed, for example if headers includes change or new files introduced -# $ cd tests; make deps # only when needed -# $ make lib # this makes the local library -# $ make tests # this updates tests and compiles -# $ make clean # deletes the .o files and library to force a recompile -# $ cd 1_tests; make clean -# -# for a release of a component -# -# $ make regress -# $ make install # this will only work if all the tests in 1_tests are passing -# -# before a checkin -# -# $ make dist_clean # will also clean the tests and try directories -# -# .lib.cc c++ files taken as source of object files for local build library -# .exl.cc c++ files taken to have main calls and are linked against local build libary -# .ex.cc c++ files taken to have main calls and are not linked against the local build library -# there are no rules for other files in this makefile -# -# about dependencies -# The makefile has no way of knowing if an edit changed the dependencies. Often they do not -# and it would be unwieldy to make the deps every time. Hence *the programmer* must delete -# the deps file if he has made any changes that change the dependencies. -# -# The makefile will make the 2_makefile_deps if the file is missing. -# -# -# about testing -# -# the name of the directory you run make in is taken to also be: the name of the library, -# the name of the main include file (with a .h added), and the name of the include directory -# where the individual headers are found. It is called LIB -# -# test programs are kept in a subdirectory called 1_tests, and are either .exl.cc, ex.cc, -# .sh files. When 'make tests' target is invoked they are all run. Test executables return 0 -# if the test fails, non-zero otherwise. -# -# to remove a test from the pool move it into the subdirectory in 1_tests, 9_broken, -# 5_more_tests of 5_scratch. broken tests are things that are known but must be fixed -# before a release. 5_more_tests are tests being worked on. 5_scratch is stuff that is -# probably going to be deleted. if there is a 5_deprecated, that is for good stuff but it -# is no longer used for some reason or other. -# -# There is a standard source code template and a -# messaging convention. Also, the names, by convention,are test_xxxx_ where xxx is a -# hexadecimal series nummber. If all the test executables pass the file 1_TESTS_PASSED is -# left in the directory. Otherwise the file 1_TESTS_FAILED is left in the directory. -# -# about release directory -# -# this is set in the ApplicationBase variable by rt_init -# -# after the tests pass stuff might be copied to the release directory using -# -# make install -# -# the release directory must have these subdirectories: -# -# bin documents include src -# -# -# diff --git a/src/2_doc/makeheaders.txt b/src/2_doc/makeheaders.txt deleted file mode 100644 index 5aebda9..0000000 --- a/src/2_doc/makeheaders.txt +++ /dev/null @@ -1,16 +0,0 @@ - -This worked to force the include to be part of the interface: - -#if INTERFACE -#include -#endif - -But this did not: - -#if INTERFACE - #include -#endif - -makeheaders looks to be sensitive to indentation - - diff --git a/src/2_doc/sqlite.txt b/src/2_doc/sqlite.txt deleted file mode 100644 index b7f8cbb..0000000 --- a/src/2_doc/sqlite.txt +++ /dev/null @@ -1,15 +0,0 @@ - -1. - This sql: - - char *sql = - "BEGIN TRANSACTION;" - "UPDATE Key_Int SET value = value + 1 WHERE key = 'max_subu_number';" - "SELECT value FROM Key_Int WHERE key = 'max_subu_number';" - "COMMIT;" - ; - - with sqlite_exec, the call back is called with the data from the select. - - with sqlite_prepare_v2, sqlite_step just returns SQLITE_DONE, and we never - get to see our data from the select. diff --git a/src/2_doc/to_do.txt b/src/2_doc/to_do.txt deleted file mode 100644 index 0b989cc..0000000 --- a/src/2_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/src/5_deprecated/dispatch_exec.lib.c b/src/5_deprecated/dispatch_exec.lib.c deleted file mode 100644 index 024bff8..0000000 --- a/src/5_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/src/5_deprecated/dispatch_f.lib.c b/src/5_deprecated/dispatch_f.lib.c deleted file mode 100644 index 5c199f5..0000000 --- a/src/5_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/src/5_deprecated/dispatch_useradd.lib.c b/src/5_deprecated/dispatch_useradd.lib.c deleted file mode 100644 index 7b75291..0000000 --- a/src/5_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/src/5_deprecated/subu-rm-0.lib.c b/src/5_deprecated/subu-rm-0.lib.c deleted file mode 100644 index ccad437..0000000 --- a/src/5_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/src/5_deprecated/subudb-number-next.cli.c b/src/5_deprecated/subudb-number-next.cli.c deleted file mode 100644 index 3373173..0000000 --- a/src/5_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/src/5_scratch/common.lib.h b/src/5_scratch/common.lib.h deleted file mode 100644 index cfdc520..0000000 --- a/src/5_scratch/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/src/5_scratch/dbprintf.lib.h b/src/5_scratch/dbprintf.lib.h deleted file mode 100644 index 3056cf6..0000000 --- a/src/5_scratch/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/src/5_scratch/dispatch.lib.h b/src/5_scratch/dispatch.lib.h deleted file mode 100644 index 07e2271..0000000 --- a/src/5_scratch/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/src/5_scratch/dispatch_exec.lib.h b/src/5_scratch/dispatch_exec.lib.h deleted file mode 100644 index 877a38e..0000000 --- a/src/5_scratch/dispatch_exec.lib.h +++ /dev/null @@ -1,4 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -int dbprintf(const char *format,...); -int dispatch_exec(char **argv,char **envp); diff --git a/src/5_scratch/dispatch_f.lib.h b/src/5_scratch/dispatch_f.lib.h deleted file mode 100644 index 6b3653f..0000000 --- a/src/5_scratch/dispatch_f.lib.h +++ /dev/null @@ -1,22 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -#include -typedef struct dispatch_f_ctx dispatch_f_ctx; -dispatch_f_ctx *dispatch_f_euid_egid(char *fname,int(*f)(void *arg),void *f_arg,uid_t euid,gid_t egid); -int dbprintf(const char *format,...); -dispatch_f_ctx *dispatch_f(char *fname,int(*f)(void *arg),void *f_arg); -void dispatch_f_mess(struct dispatch_f_ctx *ctxp); -void dispatch_f_ctx_free(dispatch_f_ctx *ctxp); -dispatch_f_ctx *dispatch_f_ctx_mk(char *name,char *fname); -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 -}; -#define ERR_DISPATCH_F_SETEGID -4 -#define ERR_DISPATCH_F_SETEUID -3 -#define ERR_DISPATCH_F_FORK -2 -#define ERR_NEGATIVE_RETURN_STATUS -1 -#define INTERFACE 0 diff --git a/src/5_scratch/dispatch_useradd.lib.h b/src/5_scratch/dispatch_useradd.lib.h deleted file mode 100644 index 0ce7e9d..0000000 --- a/src/5_scratch/dispatch_useradd.lib.h +++ /dev/null @@ -1,16 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -int dispatch_exec(char **argv,char **envp); -#include -#include -typedef struct dispatch_useradd_ret_t dispatch_useradd_ret_t; -typedef unsigned int uint; -struct dispatch_useradd_ret_t { - uint error; - struct passwd *pw_record; -}; -struct dispatch_useradd_ret_t dispatch_useradd(char **argv,char **envp); -#define ERR_DISPATCH_USERADD_PWREC 3 -#define ERR_DISPATCH_USERADD_DISPATCH 2 -#define ERR_DISPATCH_USERADD_ARGC 1 -#define INTERFACE 0 diff --git a/src/5_scratch/subu-bind.cli.h b/src/5_scratch/subu-bind.cli.h deleted file mode 100644 index af12d61..0000000 --- a/src/5_scratch/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/src/5_scratch/subu-common.lib.h b/src/5_scratch/subu-common.lib.h deleted file mode 100644 index cfdc520..0000000 --- a/src/5_scratch/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/src/5_scratch/subu-config.lib.c.~ceea6e7d697546c47f7736b72e7fb60b15c104de~ b/src/5_scratch/subu-config.lib.c.~ceea6e7d697546c47f7736b72e7fb60b15c104de~ deleted file mode 100644 index de7bcbb..0000000 --- a/src/5_scratch/subu-config.lib.c.~ceea6e7d697546c47f7736b72e7fb60b15c104de~ +++ /dev/null @@ -1,147 +0,0 @@ -/* -The config 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. - -*/ -#include "subu-config.lib.h" - -#if INTERFACE -#include -#define ERR_CONFIG_FILE 1 -#endif - -#include -#include -#include - -//-------------------------------------------------------------------------------- -int subudb_schema(sqlite3 *db, uint max_subu_number){ - char max_subu_number_string[32]; - uint max_subu_number_string_len = snprintf(max_subu_number_string, 32, "%u", max_subu_number); - if( max_subu_number_string_len >= 32 ){ - fprintf(stderr, "error exit, max_subu_number too big to deal with\n"); - return ERR_CONFIG_FILE; - } - char sql1[] = "CREATE TABLE Masteru_Subu(masteru_name TEXT, subuname TEXT, subu_username TEXT); "; - char sql2[] = "CREATE TABLE Key_Int(key TEXT, value INT); "; - - char sql3_1[] = "INSERT INTO Key_Int VALUES( 'max_subu_number', "; - char sql3_2[] = " ); "; - char sql3_len = strlen(sql3_1) + max_subu_number_string_len + strlen(sql3_2) + 1; - char sql3[sql3_len]; - strcpy(sql3, sql3_1); - strcpy(sql3 + strlen(sql3_1), max_subu_number_string); - strcpy(sql3 + strlen(sql3_1) + max_subu_number_string_len, sql3_2); - - char sql[strlen(sql1) + strlen(sql2) + strlen(sql3) + 1]; - strcpy(sql, sql1); - strcpy(sql + strlen(sql1), sql2); - strcpy(sql + strlen(sql1) + strlen(sql2), sql3); - - return sqlite3_exec(db, sql, NULL, NULL, NULL); -} - -//-------------------------------------------------------------------------------- - -// the call back for subu_number_next, note also 3_doc/sqlite3.txt -static int subu_number_extract(void *nsp, int colcnt, char **colvals, char **colnames){ - if(colcnt >= 1){ - *(char **)nsp = strdup( colvals[0] ); - return 0; - } - return -1; -} -int subu_number_next(sqlite3 *db, char **nsp, char **mess){ - char *sql = - "BEGIN TRANSACTION;" - "UPDATE Key_Int SET value = value + 1 WHERE key = 'max_subu_number';" - "SELECT value FROM Key_Int WHERE key = 'max_subu_number';" - "COMMIT;"; - int rc = sqlite3_exec(db, sql, subu_number_extract, (void *)nsp, mess); - return rc; -} -int subu_number_get(sqlite3 *db, int *n){ - char *sql = "SELECT value FROM Key_Int WHERE key = 'max_subu_number';"; - 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); - }else{ - sqlite3_finalize(stmt); - return rc; // woops this needs to return an error!, be sure it is not SQLITE_DONE - } - rc = sqlite3_step(stmt); - sqlite3_finalize(stmt); - return rc; -} -int subu_number_set(sqlite3 *db, int n){ - char *sql = "UPDATE Key_Int SET value = ?1 WHERE key = 'max_subu_number';"; - sqlite3_stmt *stmt; - sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); - sqlite3_bind_int(stmt, 1, n); - int rc = sqlite3_step(stmt); - sqlite3_finalize(stmt); - return rc; -} - - -//-------------------------------------------------------------------------------- -// put relation into Masteru_Subu table -int subu_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); - return rc; -} - -//-------------------------------------------------------------------------------- -int subu_Masteru_Subu_get(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); - sqlite3_finalize(stmt); - return rc; -} - -//-------------------------------------------------------------------------------- -int subu_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); - return rc; -} diff --git a/src/5_scratch/subu-config.lib.h b/src/5_scratch/subu-config.lib.h deleted file mode 100644 index 482d289..0000000 --- a/src/5_scratch/subu-config.lib.h +++ /dev/null @@ -1,13 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subu_rm_masteru_subu(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -int subu_get_masteru_subu(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username); -int subu_put_masteru_subu(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -int subu_number_set(sqlite3 *db,int n); -int subu_number_get(sqlite3 *db,int *n); -int subu_number_next(sqlite3 *db,char **nsp,char **mess); -typedef unsigned int uint; -int schema(sqlite3 *db,uint max_subu_number); -#define ERR_CONFIG_FILE 1 -#define INTERFACE 0 diff --git a/src/5_scratch/subu-get.cli.h b/src/5_scratch/subu-get.cli.h deleted file mode 100644 index 163709f..0000000 --- a/src/5_scratch/subu-get.cli.h +++ /dev/null @@ -1,6 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subu_put_masteru_subu(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -#define ERR_CONFIG_FILE 1 -extern char Config_File[]; diff --git a/src/5_scratch/subu-init.cli.h b/src/5_scratch/subu-init.cli.h deleted file mode 100644 index 22281b6..0000000 --- a/src/5_scratch/subu-init.cli.h +++ /dev/null @@ -1,8 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -typedef unsigned int uint; -extern uint First_Max_Subu_number; -#include -int schema(sqlite3 *db,uint max_subu_number); -#define ERR_CONFIG_FILE 1 -extern char Config_File[]; diff --git a/src/5_scratch/subu-mk-0.cli.h b/src/5_scratch/subu-mk-0.cli.h deleted file mode 100644 index 487b509..0000000 --- a/src/5_scratch/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/src/5_scratch/subu-mk-0.lib.h b/src/5_scratch/subu-mk-0.lib.h deleted file mode 100644 index 28954ba..0000000 --- a/src/5_scratch/subu-mk-0.lib.h +++ /dev/null @@ -1,49 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subu_put_masteru_subu(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -#include -#include -typedef struct dispatch_ctx dispatch_ctx; -dispatch_ctx *dispatch_exec(char **argv,char **envp); -#define BUG_SSS_CACHE_RUID 1 -void dispatch_f_mess(struct dispatch_ctx *ctxp); -#define ERR_DISPATCH -1024 -dispatch_ctx *dispatch_f_euid_egid(char *fname,int(*f)(void *arg),void *f_arg,uid_t euid,gid_t egid); -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 -}; -int subu_number_get(sqlite3 *db,char **nsp,char **errmsg); -extern char subuland_extension[]; -int dbprintf(const char *format,...); -#include -#include -typedef struct subu_mk_0_ctx subu_mk_0_ctx; -struct subu_mk_0_ctx *subu_mk_0(sqlite3 *db,char *subuname); -typedef unsigned int uint; -extern uint subuhome_perms; -void subu_mk_0_mess(struct subu_mk_0_ctx *ctxp); -void subu_mk_0_ctx_free(struct subu_mk_0_ctx *ctxp); -struct subu_mk_0_ctx *subu_mk_0_ctx_mk(); -struct subu_mk_0_ctx { - char *name; - char *subuland; - char *subuhome; - char *subu_username; - bool free_aux; - char *aux; - uint err; -}; -#define ERR_SUBU_MK_0_FAILED_USERADD 10 -#define ERR_SUBU_MK_0_BUG_SSS 9 -#define ERR_SUBU_MK_0_SUBUHOME_EXISTS 8 -#define ERR_SUBU_MK_0_CONFIG_FILE 7 -#define ERR_SUBU_MK_0_MALLOC 6 -#define ERR_SUBU_MK_0_MASTERU_HOMELESS 5 -#define ERR_SUBU_MK_0_SETUID_ROOT 4 -#define ERR_SUBU_MK_0_SUBUNAME_MALFORMED 3 -#define ERR_SUBU_MK_0_RMDIR_SUBUHOME 2 -#define ERR_SUBU_MK_0_MKDIR_SUBUHOME 1 -#define INTERFACE 0 diff --git a/src/5_scratch/subu-number.cli.h b/src/5_scratch/subu-number.cli.h deleted file mode 100644 index ac69056..0000000 --- a/src/5_scratch/subu-number.cli.h +++ /dev/null @@ -1,11 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subu_number_get(sqlite3 *db,int *n); -int subu_number_set(sqlite3 *db,int n); -#include -#include -#define SUBU_ERR_N 14 -#define SUBU_ERR_CONFIG_FILE 8 -extern char Config_File[]; -#define SUBU_ERR_ARG_CNT 1 diff --git a/src/5_scratch/subu-put.cli.h b/src/5_scratch/subu-put.cli.h deleted file mode 100644 index 163709f..0000000 --- a/src/5_scratch/subu-put.cli.h +++ /dev/null @@ -1,6 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subu_put_masteru_subu(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -#define ERR_CONFIG_FILE 1 -extern char Config_File[]; diff --git a/src/5_scratch/subu-rel-get.cli.h b/src/5_scratch/subu-rel-get.cli.h deleted file mode 100644 index 8b51ff3..0000000 --- a/src/5_scratch/subu-rel-get.cli.h +++ /dev/null @@ -1,9 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subu_get_masteru_subu(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username); -#include -#include -#define SUBU_ERR_CONFIG_FILE 8 -extern char Config_File[]; -#define SUBU_ERR_ARG_CNT 1 diff --git a/src/5_scratch/subu-rel-put.cli.h b/src/5_scratch/subu-rel-put.cli.h deleted file mode 100644 index 6ce971b..0000000 --- a/src/5_scratch/subu-rel-put.cli.h +++ /dev/null @@ -1,8 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subu_put_masteru_subu(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -#include -#include -#define SUBU_ERR_CONFIG_FILE 8 -extern char Config_File[]; diff --git a/src/5_scratch/subu-rel-rm.cli.h b/src/5_scratch/subu-rel-rm.cli.h deleted file mode 100644 index 5973cbe..0000000 --- a/src/5_scratch/subu-rel-rm.cli.h +++ /dev/null @@ -1,8 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subu_rm_masteru_subu(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -#include -#include -#define SUBU_ERR_CONFIG_FILE 8 -extern char Config_File[]; diff --git a/src/5_scratch/subu-rm-0.cli.h b/src/5_scratch/subu-rm-0.cli.h deleted file mode 100644 index 070bfe8..0000000 --- a/src/5_scratch/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/src/5_scratch/subu-rm-0.lib.h b/src/5_scratch/subu-rm-0.lib.h deleted file mode 100644 index f63f1db..0000000 --- a/src/5_scratch/subu-rm-0.lib.h +++ /dev/null @@ -1,2 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE diff --git a/src/5_scratch/subu-rm.cli.h b/src/5_scratch/subu-rm.cli.h deleted file mode 100644 index 163709f..0000000 --- a/src/5_scratch/subu-rm.cli.h +++ /dev/null @@ -1,6 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subu_put_masteru_subu(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username); -#define ERR_CONFIG_FILE 1 -extern char Config_File[]; diff --git a/src/5_scratch/subu.lib.h b/src/5_scratch/subu.lib.h deleted file mode 100644 index da9b468..0000000 --- a/src/5_scratch/subu.lib.h +++ /dev/null @@ -1,47 +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); -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); -int dbprintf(const char *format,...); -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); -typedef unsigned int uint; -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/src/5_scratch/subudb-init.cli.h b/src/5_scratch/subudb-init.cli.h deleted file mode 100644 index 4435103..0000000 --- a/src/5_scratch/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/src/5_scratch/subudb-number-next.cli.h b/src/5_scratch/subudb-number-next.cli.h deleted file mode 100644 index 2c295dc..0000000 --- a/src/5_scratch/subudb-number-next.cli.h +++ /dev/null @@ -1,9 +0,0 @@ -/* This file was automatically generated. Do not edit! */ -#undef INTERFACE -#include -int subudb_number_next(sqlite3 *db,char *masteru_name,int *n,char **mess); -#include -#include -#define SUBU_ERR_DB_FILE 8 -extern char DB_File[]; -#define SUBU_ERR_ARG_CNT 1 diff --git a/src/5_scratch/subudb-number.cli.h b/src/5_scratch/subudb-number.cli.h deleted file mode 100644 index c130fbb..0000000 --- a/src/5_scratch/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/src/5_scratch/subudb-rel-get.cli.h b/src/5_scratch/subudb-rel-get.cli.h deleted file mode 100644 index 4f335be..0000000 --- a/src/5_scratch/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/src/5_scratch/subudb-rel-put.cli.h b/src/5_scratch/subudb-rel-put.cli.h deleted file mode 100644 index 243b3a9..0000000 --- a/src/5_scratch/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/src/5_scratch/subudb-rel-rm.cli.h b/src/5_scratch/subudb-rel-rm.cli.h deleted file mode 100644 index 595427f..0000000 --- a/src/5_scratch/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/src/5_scratch/subudb-subus.cli.h b/src/5_scratch/subudb-subus.cli.h deleted file mode 100644 index 16310b7..0000000 --- a/src/5_scratch/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/src/5_scratch/subudb.lib.h b/src/5_scratch/subudb.lib.h deleted file mode 100644 index 2a9e9b7..0000000 --- a/src/5_scratch/subudb.lib.h +++ /dev/null @@ -1,22 +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); -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); -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/src/7_makefile b/src/7_makefile deleted file mode 100755 index 5ab5990..0000000 --- a/src/7_makefile +++ /dev/null @@ -1,170 +0,0 @@ - -# a single space literal, for example if you wanted to subsitute commas to -# spaces: $(subst $(space),;,$(string)) we ran into this out of a need to send -# multiple separate command arguments to a shell script from one variable value -blank := -space :=$(blank) $(blank) - -# 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 - -SHELL=/bin/bash -SCRATCHDIR= 5_scratch # clean and others put things here -CC=gcc -CFLAGS=-std=gnu11 -fPIC -I. -ggdb -Werror -DDEBUG -DDEBUGDB -#CFLAGS=-std=gnu11 -fPIC -I. -Werror -LIBDIR=2_lib/ -LIB=$(LIBDIR)libsubu.a -LINKFLAGS=-L2_lib -lsubu -lsqlite3 - -#these are the source files that exist -SOURCES_LIB= $(wildcard *.lib.c) -SOURCES_CLI= $(wildcard *.cli.c) -SOURCES= $(SOURCES_LIB) $(SOURCES_CLI) - -#these are the object files to be made -OBJECTS_LIB= $(patsubst %.c, %.o, $(SOURCES_LIB)) -OBJECTS_CLI= $(patsubst %.c, %.o, $(SOURCES_CLI)) -OBJECTS= $(OBJECTS_LIB) $(OBJECTS_CLI) - -#these are the header files that exist, makeheaders will want to see them -HFILES = $(wildcard *.lib.h) $(wildcard *.cli.h) - -# sort causes compiles to go in lexical order by file name, this is used to order the tests e.g. -EXECS= $(sort $(patsubst %.cli.c, %, $(wildcard *.cli.c))) - -SUID=$(realpath ../tools/bin/setuid_root.sh) - - -all: version deps lib execs - -lists: - @echo '---- make $@:------------------------------------------------------------' - @echo "SOURCES_LIB: " $(SOURCES_LIB) - @echo "SOURCES_CLI: " $(SOURCES_CLI) - @echo "SOURCES: " $(SOURCES) - @echo "OBJECTS_LIB: " $(OBJECTS_LIB) - @echo "OBJECTS_CLI: " $(OBJECTS_CLI) - @echo "OBJECTS: " $(OBJECTS) - @echo "HFILES: " $(HFILES) - @echo "EXECS: " $(EXECS) - @echo '______end make $@_____' - -version: - @echo '---- make $@:------------------------------------------------------------' - @echo `pwd`'>' - @echo makefile version 2.0 - @echo "CC: " $(CC) - @echo "CFLAGS: " $(CFLAGS) - @echo "LINKFLAGS: " $(LINKFLAGS) - @echo "LIB: " $(LIB) - @echo "SUID: " $(SUID) - @echo '______end make $@_____' - -# safe to run this in an already setup or partially setup directory -setup: - @echo '---- make $@:------------------------------------------------------------' - @echo `pwd`'>' - if [ ! -e $(SCRATCHDIR) ]; then mkdir $(SCRATCHDIR); fi - if [ ! -e 1_tests ]; then mkdir 1_tests; fi - if [ ! -e 1_try ]; then mkdir 1_try; fi - if [ ! -e 2_bin ]; then mkdir 2_bin; fi - if [ ! -e 2_lib ]; then mkdir 2_lib; fi - if [ ! -e 2_doc ]; then mkdir 2_doc; fi - if [ ! -e 2_include ]; then mkdir 2_include; fi - if [ ! -e 5_deprecated ]; then mkdir 5_deprecated; fi - if [ ! -e 5_scratch ]; then mkdir 5_scratch; fi - @echo '______end make $@_____' - - -deps: - @echo '---- make $@:------------------------------------------------------------' - @echo `pwd`'>' - makeheaders $(SOURCES) $(HFILES) - sed -i '/^ *int *main *(.*)/d' *.h - $(CC) $(CFLAGS) -MM $(SOURCES) 1> 7_makefile_deps - for i in $(EXECS) ; do\ - $(ECHO) >> 7_makefile_deps;\ - $(ECHO) "2_bin/$$i : $$i.cli.o $(LIB)" >> 7_makefile_deps;\ - $(ECHO) " $(CC) -o 2_bin/$$i $$i.cli.o $(LINKFLAGS)" >> 7_makefile_deps;\ - done - @echo '______end make $@_____' - -lib: - @echo '---- make $@:------------------------------------------------------------' - @echo `pwd`'>' - if [ ! -e 7_makefile_deps ]; then make deps; fi - make sub_lib - @echo '______end make $@_____' - -sub_lib: $(LIB) - - -execs: $(LIB) - @echo '---- make $@:------------------------------------------------------------' - @echo `pwd`'>' - if [ ! -e 7_makefile_deps ]; then make deps; fi - make sub_execs - @echo "-> $(SUID) 2_bin/subu-mk-0 2_bin/subu-rm-0" - cat $(SUID) - @echo -n "Are you sure? [y/N] " && read ans && [ $${ans:-N} == y ] - sudo $(SUID) 2_bin/subu-mk-0 2_bin/subu-rm-0 - @echo '______end make $@_____' - -sub_execs: $(patsubst %, 2_bin/%, $(EXECS)) - -#not ready yet -install: all - @echo '---- make $@:------------------------------------------------------------' - @echo `pwd`'>' - @if[ ! -e 1_tests_passed ]; then echo "can't install as tests have not passed"; fi - @test -e test_passed - for i in $(BIN); do cp $$i $(RT_BASE)/bin; done - cp $(LIB) $(RT_BASE)/lib - cp $(APPLICATION).h $(RT_BASE)/include - if [ -d $(APPLICATION) ]; then cp $(APPLICATION)/*.h $(RT_BASE)/include/$(APPLICATION); fi - @echo '______end make $@_____' - -# not written yet -# copies stuff from the src dir to the stage dirs -# stage: - -clean: - @echo '---- make $@:------------------------------------------------------------' - @echo `pwd`'>' - if [ -f subudb ]; then rm subudb; fi - for i in $(wildcard *~); do mv $$i $(SCRATCHDIR); done - for i in $(wildcard *.lib.o) $(wildcard *.cli.o); do rm $$i; done - for i in $(HFILES); do mv $$i 5_scratch; done # just in case someone wrote a header file - for i in $(EXECS); do if [ -e 2_bin/$$i ]; then rm 2_bin/$$i; fi; done - if [ -f $(LIB) ]; then rm $(LIB); fi - if [ -f 7_makefile_deps ]; then rm 7_makefile_deps; fi - @echo '______end make $@_____' - - -# not ready ... -# dist_clean is used to clean thing up before doing a checkin, hg add should be safe after a dist_clean -# dist_clean will recurse into the include directory = $(APPLICATION), tests, and try if they are present -# -dist-clean: - @echo '---- make $@:------------------------------------------------------------' - @echo `pwd`'>' - make clean -# if [ -d $(APPLICATION) ]; then cd $(APPLICATION); make clean; fi -# if [ -d 1_tests ]; then cd 1_tests; make dist_clean; fi -# if [ -d 1_try ] ; then cd 1_try; make dist_clean; fi - @echo '______end make $@_____' - -# -$(LIB) : $(OBJECTS_LIB) - ar rcs $(LIB) $(OBJECTS_LIB) - --include 7_makefile_deps - -# recipe for making object files: -# -%.o : %.c - $(CC) $(CFLAGS) -c $< - - diff --git a/src/da.lib.c b/src/da.lib.c new file mode 100644 index 0000000..f2cabcb --- /dev/null +++ b/src/da.lib.c @@ -0,0 +1,95 @@ +/* +Dynamic Array + +*/ + +#include "da.lib.h" + +#if INTERFACE +#include +#include +#endif +#include + +//-------------------------------------------------------------------------------- +// generic + +// s is the size of the array in bytes +void da_alloc(void **base, size_t *s, size_t item_size){ + *s = 4 * item_size; + *base = malloc(*s); +} + +// doubles size of an array +void da_expand(void **base, void **pt, size_t *s){ + size_t offset = ((unsigned char *)*pt - (unsigned char *)*base); + size_t new_s = *s << 1; + void *new_base = malloc( new_s ); + memcpy( new_base, *base, offset + 1); + free(base); + *base = new_base; + *pt = new_base + offset; + *s = new_s; +} + +// true when pt has run off the end of the area currently allocated for the array +bool da_bound(void *base, void *pt, size_t s){ + return pt >= base + s; +} + +void da_push(void **base, void **pt, size_t *s, void *item, size_t item_size){ + while( *pt + item_size >= *base + *s ){ + da_expand(base, pt, s); + } + memcpy(*pt, item, item_size); + *pt += item_size; +} + +void da_map(void *base, void *end_pt, void f(void *), size_t item_size){ + void *pt = base; + while( pt != end_pt ){ + f(pt); + pt += item_size; + } +} + +//-------------------------------------------------------------------------------- +// dynamic array of pointers to strings + +// s is still the length of the array in bytes +void daps_alloc(char **base, size_t *s){ + da_alloc((void **)base, s, sizeof(char *)); +} + +void daps_expand(char **base, char **pt, size_t *s){ + da_expand((void **)base, (void **)pt, s); +} + +bool daps_bound(char **base, char **pt, size_t s){ + return da_bound( (void *) base, (void *)pt, s); +} + +void daps_push(char **base, char **pt, size_t *s, char *item){ + da_push((void **)base, (void **)pt, s, (void *)item, sizeof(char *)); +} + +void daps_map(char **base, char **end_pt, void f(void *)){ + da_map((void *)base, (void *)end_pt, f, sizeof(char *)); +} + +// one use for an array of string pointers is to keep list of +// strings that must be freed. I.e. 'managed' strings +#if INTERFACE + +#define MK_MRS \ + char **mrs; \ + char **mrs_end; \ + size_t mrs_size; \ + daps_alloc(mrs, &mrs_size);\ + mrs_end = mrs; + +#define RETURN(rc) \ + { daps_map(mrs, mrs_end, free); return rc; } + +#endif + diff --git a/src/darray.c b/src/darray.c deleted file mode 100644 index 02f5704..0000000 --- a/src/darray.c +++ /dev/null @@ -1,45 +0,0 @@ -/* -Dynamic Array - -*/ - -void d_alloc(subudb_subu_element **base, size_t *s, size_t item_size){ - *s = 4 * item_size; - *base = malloc(*s); -} - -// doubles size of an array -void d_expand(void **base, void **pt, size_t *s){ - size_t offset = ((unsigned char *)*pt - (unsigned char *)*base); - size_t new_s = *s << 1; - void *new_base = malloc( new_s ); - memcpy( new_base, *base, offset + 1); - free(base); - *base = new_base; - *pt = new_base + offset; - *s = new_s; -} - -// true when pt has run off the end of the area currently allocated for the array -bool d_bounds(void *base, void *pt, size_t s){ - return pt >= base + s; -} - -void d_push(void **base, void **pt, size_t *s, void *item, size_t item_size){ - while( *pt + item_size >= *base + *s ){ - expand(base, pt, s); - } - memcpy(*pt, item, item_size); - *pt += item_size; -} - -// special case when the dynamic array is holding pointers to items on the heap -void d_map(void *base, void *end_pt){ - void *pt = base; - while( pt != end_pt ){ - free(pt->subuname); - free(pt->subu_username); - pt++; - } - free(base); -} diff --git a/src/subu-bind-all.cli.c b/src/subu-bind-all.cli.c new file mode 100644 index 0000000..4754d55 --- /dev/null +++ b/src/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 != 2){ + 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/src/subu.lib.c b/src/subu.lib.c index 9950380..d0d68a0 100644 --- a/src/subu.lib.c +++ b/src/subu.lib.c @@ -268,21 +268,14 @@ static int mk_subuhome(char *subuland, char *subuname, char **subuhome){ return 0; } -#define RETURN(err)\ - {\ - free(subu_username);\ - free(masteru_name);\ - free(masteru_home);\ - free(subuland);\ - free(subuhome);\ - return err;\ - } + //=============================================================================== int subu_mk_0(char **mess, sqlite3 *db, char *subuname){ int rc; if(mess)*mess = 0; + MK_MRS; //-------------------------------------------------------------------------------- size_t subuname_len; @@ -314,6 +307,11 @@ int subu_mk_0(char **mess, sqlite3 *db, char *subuname){ char *subu_username = 0; char *subuland = 0; char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir + daps_push(mrs, mrs_end, &mrs_size, masteru_name); + daps_push(mrs, mrs_end, &mrs_size, masteru_home); + daps_push(mrs, mrs_end, &mrs_size, subu_username); + daps_push(mrs, mrs_end, &mrs_size, subuland); + daps_push(mrs, mrs_end, &mrs_size, subuhome); rc = uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home) || @@ -423,6 +421,7 @@ int subu_rm_0(char **mess, sqlite3 *db, char *subuname){ int rc; if(mess)*mess = 0; + MK_MRS; //-------------------------------------------------------------------------------- size_t subuname_len; @@ -454,7 +453,10 @@ int subu_rm_0(char **mess, sqlite3 *db, char *subuname){ char *masteru_home = 0; char *subuland = 0; char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir - char *subu_username = 0; + daps_push(mrs, mrs_end, &mrs_size, masteru_name); + daps_push(mrs, mrs_end, &mrs_size, masteru_home); + daps_push(mrs, mrs_end, &mrs_size, subuland); + daps_push(mrs, mrs_end, &mrs_size, subuhome); rc = uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home) || @@ -469,6 +471,8 @@ int subu_rm_0(char **mess, sqlite3 *db, char *subuname){ //-------------------------------------------------------------------------------- // removal from db + char *subu_username = 0; + daps_push(mrs, mrs_end, &mrs_size, subu_username); db_begin(db); @@ -539,8 +543,7 @@ int subu_rm_0(char **mess, sqlite3 *db, char *subuname){ dbprintf("setting inherited real uid to 0 to accomodate SSS_CACHE UID BUG\n"); #endif if( setuid(0) == -1 ){ - rc = SUBU_ERR_BUG_SSS; - RETURN(rc); + RETURN(SUBU_ERR_BUG_SSS); } #endif char *command = "/usr/sbin/userdel"; @@ -575,16 +578,22 @@ int subu_rm_0(char **mess, sqlite3 *db, char *subuname){ // in subuland. int subu_bind(char **mess, char *masteru_name, char *subu_username, char *subuhome){ - char *subu_user_home; int rc; + if(mess)*mess = 0; + MK_MRS; + + // lookup the subu_user_home + char *subu_user_home = 0; + daps_push(mrs, mrs_end, &mrs_size, 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 rc; + RETURN(rc); } size_t len = 0; - char *map; + char *map = 0; + daps_push(mrs, mrs_end, &mrs_size, 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); @@ -599,25 +608,24 @@ int subu_bind(char **mess, char *masteru_name, char *subu_username, char *subuho char *envp[1]; envp[0] = (char *) NULL; int dispatch_err = dispatch_exec(argv, envp); - free(map); if( dispatch_err != 0 ){ #ifdef DEBUG dispatch_f_mess(command, dispatch_err, "dispatch_exec"); #endif if(mess)*mess = strdup("bind failed"); - return SUBU_ERR_BIND; + RETURN(SUBU_ERR_BIND); } #ifdef DEBUG dbprintf("mapped \"%s\" as \"%s\"\n", subu_user_home, subuhome); #endif - return 0; + RETURN(0); } int subu_bind_all(char **mess, sqlite3 *db){ int rc; if(mess)*mess = 0; - char **free_list; + MK_MRS; //-------------------------------------------------------------------------------- uid_t masteru_uid; @@ -640,19 +648,25 @@ int subu_bind_all(char **mess, sqlite3 *db){ 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 + daps_push(mrs, mrs_end, &mrs_size, masteru_name); + daps_push(mrs, mrs_end, &mrs_size, masteru_home); + daps_push(mrs, mrs_end, &mrs_size, subuland); rc = uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home) || mk_subuland(masteru_home, &subuland) ; - if(rc){ - free(masteru_name); - free(masteru_home); - free(subuland); - } + if(rc) RETURN(rc); #ifdef DEBUG - dbprintf("masteru_home, subuhome: \"%s\", \"%s\"\n", masteru_home, subuhome); + 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 //-------------------------------------------------------------------------------- @@ -667,20 +681,29 @@ int subu_bind_all(char **mess, sqlite3 *db){ // a limitation of our error reporting approach is that we can only // return one error, but here is a loop that might generate many + char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir uint rc_count = 0; subudb_subu_element *pt = sa; while( pt != sa_end ){ 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) rc_count++; + free(subuhome); + subuhome=0; pt++; } if(rc_count==1){ - return rc; + RETURN(rc); } if(rc_count > 1){ - mess = strdup("multiple errors occured while binding subus"); + *mess = strdup("multiple errors occured while binding subus"); RETURN(SUBU_ERR_BIND); } - return RETURN(0); + RETURN(0); } diff --git a/src/subudb.lib.c b/src/subudb.lib.c index 5a1d279..cce9661 100644 --- a/src/subudb.lib.c +++ b/src/subudb.lib.c @@ -140,7 +140,7 @@ struct subudb_subu_element{ }; #endif static void subu_element_alloc(subudb_subu_element **base, size_t *s){ - dalloc((void *)base, s, sizeof(subudb_subu_element)); + da_alloc((void *)base, s, sizeof(subudb_subu_element)); } void subu_element_free(subudb_subu_element *base, subudb_subu_element *end_pt){ subudb_subu_element *pt = base; @@ -175,7 +175,8 @@ int subudb_Masteru_Subu_get_subus subudb_subu_element *pt = subu_element; rc = sqlite3_step(stmt); while( rc == SQLITE_ROW ){ - if( off_alloc(subu_element, pt, subu_element_size) ) expand((void **)&subu_element, (void **)&pt, &subu_element_size); + if( da_bound(subu_element, pt, subu_element_size) ) + da_expand((void **)&subu_element, (void **)&pt, &subu_element_size); pt->subuname = strdup(sqlite3_column_text(stmt, 0)); pt->subu_username = strdup(sqlite3_column_text(stmt, 1)); rc = sqlite3_step(stmt); diff --git a/tools/bin/make b/tools/bin/make index 3312575..d51fcb8 100755 --- a/tools/bin/make +++ b/tools/bin/make @@ -1,2 +1,11 @@ #!/bin/bash -/usr/bin/make -f 7_makefile "$@" + +mf=( ?_makefile ) +if [ -f "$mf" ]; then + /usr/bin/make -f ?_makefile "$@" +else + /usr/bin/make "$@" +fi + + +