From: Thomas Walker Lynch Date: Wed, 13 Feb 2019 16:05:33 +0000 (+0100) Subject: error return on user-mk appears today, ran before see example.txt X-Git-Url: https://git.reasoningtechnology.com/style/rt_dark_doc.css?a=commitdiff_plain;h=f764db2c8ec6d8f230048f83cdb59e9bc11bef5f;p=subu error return on user-mk appears today, ran before see example.txt --- diff --git a/try/sss_cache_probs/dbprintf.aux.c b/try/sss_cache_probs/dbprintf.aux.c new file mode 100644 index 0000000..edea747 --- /dev/null +++ b/try/sss_cache_probs/dbprintf.aux.c @@ -0,0 +1,13 @@ + +#include +#include +#include "dbprintf.aux.h" + +int dbprintf(const char *format, ...){ + va_list args; + va_start(args,format); + int ret = vfprintf(stdout, format, args); + fflush(stdout); + va_end(args); + return ret; +} diff --git a/try/sss_cache_probs/dbprintf.aux.h b/try/sss_cache_probs/dbprintf.aux.h new file mode 100644 index 0000000..967fdae --- /dev/null +++ b/try/sss_cache_probs/dbprintf.aux.h @@ -0,0 +1,6 @@ +#ifndef DBPRINTF_AUX_H +#define DBPRINTF_AUX_H + +int dbprintf(const char *format, ...); + +#endif diff --git a/try/sss_cache_probs/dbprintf.aux.o b/try/sss_cache_probs/dbprintf.aux.o new file mode 100644 index 0000000..0b30dab Binary files /dev/null and b/try/sss_cache_probs/dbprintf.aux.o differ diff --git a/try/sss_cache_probs/dispatch.lib.c b/try/sss_cache_probs/dispatch.lib.c new file mode 100644 index 0000000..fcad514 --- /dev/null +++ b/try/sss_cache_probs/dispatch.lib.c @@ -0,0 +1,69 @@ +/* +fork/exec/wait a command + +if the error values returned by the exec'd program +are less than 1 << 16, then + +*/ + +// without this #define execvpe is undefined +#define _GNU_SOURCE +#include +#include + +#include +#include +#include +#include +#include "local_common.h" +#include "dispatch.lib.h" + + + +/* + Execs the command passed in argv[0]; + Returns -1 upon failure. + + The wstatus returned from wait() might be either the error we returned when + exec 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. +*/ +int dispatch(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:\n"); + char **arg = argv; + while( *arg ){ + dbprintf("arg: %p", arg); + dbprintf(" %s\n",*arg); + arg++; + } + 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/try/sss_cache_probs/dispatch.lib.h b/try/sss_cache_probs/dispatch.lib.h new file mode 100644 index 0000000..620c6f9 --- /dev/null +++ b/try/sss_cache_probs/dispatch.lib.h @@ -0,0 +1,9 @@ +#ifndef DISPATCH_LIB_H +#define DISPATCH_LIB_H +#include "local_common.h" + +int dispatch(char **argv, char **envp); + +#endif + + diff --git a/try/sss_cache_probs/dispatch.lib.o b/try/sss_cache_probs/dispatch.lib.o new file mode 100644 index 0000000..a6a471a Binary files /dev/null and b/try/sss_cache_probs/dispatch.lib.o differ diff --git a/try/sss_cache_probs/local_common.h b/try/sss_cache_probs/local_common.h new file mode 100644 index 0000000..4df5bcf --- /dev/null +++ b/try/sss_cache_probs/local_common.h @@ -0,0 +1,12 @@ +#ifndef LOCAL_COMMON_H +#define LOCAL_COMMON_H + +#include +#include +#include +#include "dbprintf.aux.h" + +#define DEBUG +typedef unsigned int uint; + +#endif diff --git a/try/sss_cache_probs/makefile b/try/sss_cache_probs/makefile new file mode 100644 index 0000000..233007a --- /dev/null +++ b/try/sss_cache_probs/makefile @@ -0,0 +1,17 @@ + +src = $(wildcard *.c) +obj = $(src:.c=.o) +CC=gcc + +all: sss_cache + +sss_cache: $(obj) + $(CC) -o $@ $^ + +.PHONY: clean +clean: + rm -rf $(obj) sss_cache + + + + diff --git a/try/sss_cache_probs/setuid_root.sh b/try/sss_cache_probs/setuid_root.sh new file mode 100755 index 0000000..436fa79 --- /dev/null +++ b/try/sss_cache_probs/setuid_root.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# type these things from a sudo prompt: +# + +chown root sss_cache +chmod u+rsx,u-w,go+rx-s-w sss_cache + + diff --git a/try/sss_cache_probs/sss_cache.cli.c b/try/sss_cache_probs/sss_cache.cli.c new file mode 100644 index 0000000..6d0e934 --- /dev/null +++ b/try/sss_cache_probs/sss_cache.cli.c @@ -0,0 +1,15 @@ +/* + +*/ + +#include +#include "sss_cache.lib.h" + +int main(int argc, char **argv, char **env){ + char *command = argv[0]; + if( argc != 2 ){ + fprintf(stderr, "usage: %s subu", command); + return 1; + } + return user_mk(argv[1]); +} diff --git a/try/sss_cache_probs/sss_cache.lib.c b/try/sss_cache_probs/sss_cache.lib.c new file mode 100644 index 0000000..109a99f --- /dev/null +++ b/try/sss_cache_probs/sss_cache.lib.c @@ -0,0 +1,126 @@ +/* + Makes a new subu user. + + According to the man page, we are not alloed to free the memory allocated by getpwid(). + + +setfacl -m d:u:masteru:rwX,u:masteru:rwX subuname + +*/ +// without this #define we get the warning: implicit declaration of function ‘seteuid’/‘setegid’ +#define _GNU_SOURCE +#include +#include + +#include +#include +#include +#include +#include +#include +#include "dispatch.lib.h" +#include "sss_cache.lib.h" + +typedef unsigned int uint; + +int user_mk(char *username){ + + //-------------------------------------------------------------------------------- + #ifdef DEBUG + dbprintf("Checking we are running from a user and are setuid root.\n"); + #endif + uid_t uid = getuid(); + uid_t euid = geteuid(); + gid_t gid = getgid(); + gid_t egid = getegid(); + #ifdef DEBUG + dbprintf("uid %u, gid %u, euid %u egid %u\n", uid, gid, euid, egid); + #endif + if( uid == 0 || euid != 0 ){ + fprintf(stderr, "this program must be run setuid root from a user account\n"); + return -1; + } + #ifdef DEBUG + dbprintf("yes, uid is not zero, and euid is zero, so we are setuid to the root user.\n"); + #endif + + //-------------------------------------------------------------------------------- + char *home; + size_t home_len; + { + #ifdef DEBUG + dbprintf("making the home dir path\n"); + #endif + char *prefix = "/home/"; + home_len = strlen(prefix) + strlen(username); + home = (char *)malloc(home_len + 1); + if( !home ){ + perror("sss_cache"); + return -1; + } + strcpy (home, prefix); + strcpy (home + strlen(prefix), username); + } + #ifdef DEBUG + dbprintf("home dir path: \"%s\"\n", home); + #endif + + /*-------------------------------------------------------------------------------- + note this from the man page: + + -d, --home-dir HOME_DIR The new user will be created using HOME_DIR + as the value for the user's login directory. ... The directory HOME_DIR + does not have to exist but will not be created if it is missing. + */ + uid_t useruid; + gid_t usergid; + { + #ifdef DEBUG + dbprintf("dispatching useradd to create the user\n"); + #endif + char *command = "/usr/sbin/useradd"; + char *argv[5]; + argv[0] = command; + argv[1] = username; + argv[2] = "-d"; + argv[3] = home; + argv[4] = (char *) NULL; + char *envp[1]; + envp[0] = (char *) NULL; + int ret = dispatch(argv, envp); + if(ret == -1){ + fprintf(stderr, "useradd failed\n"); + return -1; + } + struct passwd *pw_record = getpwnam(username); + if( pw_record == NULL ){ + fprintf(stderr,"getpwnam failed after useradd for username, %s\n", username); + } + useruid = pw_record->pw_uid; + usergid = pw_record->pw_gid; + } + + //-------------------------------------------------------------------------------- + // create home directory + // we have our reasons for doing this second (setting facls in different places) + { + #ifdef DEBUG + dbprintf("mkdir(%s, 0x0700)\n", home); + #endif + int ret = mkdir(home, 0x0700); + if( ret == -1 ){ + perror("sss_cache"); + return -1; + } + ret = chown(home, useruid, usergid); + if( ret == -1 ){ + perror("sss_cache"); + return -1; + } + } + + #ifdef DEBUG + dbprintf("finished sss_cache without errors\n", username); + #endif + return 0; +} diff --git a/try/sss_cache_probs/sss_cache.lib.h b/try/sss_cache_probs/sss_cache.lib.h new file mode 100644 index 0000000..11ab8ee --- /dev/null +++ b/try/sss_cache_probs/sss_cache.lib.h @@ -0,0 +1,6 @@ +#ifndef SUBU_MK_0_LIB_H +#define SUBU_MK_0_LIB_H + +int user_mk(char *subuname); + +#endif diff --git a/try/sss_cache_probs/sss_cache.lib.o b/try/sss_cache_probs/sss_cache.lib.o new file mode 100644 index 0000000..edb0d0f Binary files /dev/null and b/try/sss_cache_probs/sss_cache.lib.o differ diff --git a/try/useradd_probs/user-mk.cli.c b/try/useradd_probs/user-mk.cli.c index a2748f3..ff595f5 100644 --- a/try/useradd_probs/user-mk.cli.c +++ b/try/useradd_probs/user-mk.cli.c @@ -9,7 +9,7 @@ int main(int argc, char **argv, char **env){ char *command = argv[0]; if( argc != 2 ){ fprintf(stderr, "usage: %s subu", command); - return ERR_ARG_CNT; + return 1; } return user_mk(argv[1]); }