error return on user-mk appears today, ran before see example.txt
authorThomas Walker Lynch <thomas.lynch@reasoningtechnology.com>
Wed, 13 Feb 2019 16:05:33 +0000 (17:05 +0100)
committerThomas Walker Lynch <thomas.lynch@reasoningtechnology.com>
Wed, 13 Feb 2019 16:05:33 +0000 (17:05 +0100)
14 files changed:
try/sss_cache_probs/dbprintf.aux.c [new file with mode: 0644]
try/sss_cache_probs/dbprintf.aux.h [new file with mode: 0644]
try/sss_cache_probs/dbprintf.aux.o [new file with mode: 0644]
try/sss_cache_probs/dispatch.lib.c [new file with mode: 0644]
try/sss_cache_probs/dispatch.lib.h [new file with mode: 0644]
try/sss_cache_probs/dispatch.lib.o [new file with mode: 0644]
try/sss_cache_probs/local_common.h [new file with mode: 0644]
try/sss_cache_probs/makefile [new file with mode: 0644]
try/sss_cache_probs/setuid_root.sh [new file with mode: 0755]
try/sss_cache_probs/sss_cache.cli.c [new file with mode: 0644]
try/sss_cache_probs/sss_cache.lib.c [new file with mode: 0644]
try/sss_cache_probs/sss_cache.lib.h [new file with mode: 0644]
try/sss_cache_probs/sss_cache.lib.o [new file with mode: 0644]
try/useradd_probs/user-mk.cli.c

diff --git a/try/sss_cache_probs/dbprintf.aux.c b/try/sss_cache_probs/dbprintf.aux.c
new file mode 100644 (file)
index 0000000..edea747
--- /dev/null
@@ -0,0 +1,13 @@
+
+#include <stdarg.h>
+#include <stdio.h>
+#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 (file)
index 0000000..967fdae
--- /dev/null
@@ -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 (file)
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 (file)
index 0000000..fcad514
--- /dev/null
@@ -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 <sys/types.h>
+#include <unistd.h>
+
+#include <wait.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#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 (file)
index 0000000..620c6f9
--- /dev/null
@@ -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 (file)
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 (file)
index 0000000..4df5bcf
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef LOCAL_COMMON_H
+#define LOCAL_COMMON_H
+
+#include <stdbool.h>
+#include <stdarg.h>
+#include <stdio.h>
+#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 (file)
index 0000000..233007a
--- /dev/null
@@ -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 (executable)
index 0000000..436fa79
--- /dev/null
@@ -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 (file)
index 0000000..6d0e934
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+
+*/
+
+#include <stdio.h>
+#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 (file)
index 0000000..109a99f
--- /dev/null
@@ -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 <sys/types.h>
+#include <unistd.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <string.h>
+#include <sys/stat.h>
+#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 (file)
index 0000000..11ab8ee
--- /dev/null
@@ -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 (file)
index 0000000..edb0d0f
Binary files /dev/null and b/try/sss_cache_probs/sss_cache.lib.o differ
index a2748f3..ff595f5 100644 (file)
@@ -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]);
 }