checkpoint subu-mk-0
authorThomas Walker Lynch <thomas.lynch@reasoningtechnology.com>
Mon, 11 Feb 2019 00:30:50 +0000 (01:30 +0100)
committerThomas Walker Lynch <thomas.lynch@reasoningtechnology.com>
Mon, 11 Feb 2019 00:30:50 +0000 (01:30 +0100)
13 files changed:
src/.deps/subu-mk-0.Tpo [new file with mode: 0644]
src/local_common.h
src/run.c [new file with mode: 0644]
src/run.h [new file with mode: 0644]
src/subu-mk-0.c
src/subu-mk-0.def.c [deleted file]
src/subu-mk-0.fi.c [new file with mode: 0644]
src/subu-mk-0.fi.h [new file with mode: 0644]
src/subu_mk_0_def.h [deleted file]
src/useradd.fi.c [new file with mode: 0644]
src/useradd.fi.h [new file with mode: 0644]
src/useradd_fun.c [deleted file]
src/useradd_fun.h [deleted file]

diff --git a/src/.deps/subu-mk-0.Tpo b/src/.deps/subu-mk-0.Tpo
new file mode 100644 (file)
index 0000000..cb4e27f
--- /dev/null
@@ -0,0 +1,125 @@
+subu-mk-0.o: subu-mk-0.c /usr/include/stdc-predef.h /usr/include/stdio.h \
+ /usr/include/bits/libc-header-start.h /usr/include/features.h \
+ /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \
+ /usr/include/bits/long-double.h /usr/include/gnu/stubs.h \
+ /usr/include/gnu/stubs-64.h \
+ /usr/lib/gcc/x86_64-redhat-linux/8/include/stddef.h \
+ /usr/lib/gcc/x86_64-redhat-linux/8/include/stdarg.h \
+ /usr/include/bits/types.h /usr/include/bits/typesizes.h \
+ /usr/include/bits/types/__fpos_t.h /usr/include/bits/types/__mbstate_t.h \
+ /usr/include/bits/types/__fpos64_t.h /usr/include/bits/types/__FILE.h \
+ /usr/include/bits/types/FILE.h /usr/include/bits/types/struct_FILE.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \
+ /usr/include/bits/stdio.h subu-mk-0.fi.h useradd.fi.h \
+ /usr/include/unistd.h /usr/include/bits/posix_opt.h \
+ /usr/include/bits/environments.h /usr/include/bits/confname.h \
+ /usr/include/bits/getopt_posix.h /usr/include/bits/getopt_core.h \
+ /usr/include/sys/types.h /usr/include/bits/types/clock_t.h \
+ /usr/include/bits/types/clockid_t.h /usr/include/bits/types/time_t.h \
+ /usr/include/bits/types/timer_t.h /usr/include/bits/stdint-intn.h \
+ /usr/include/endian.h /usr/include/bits/endian.h \
+ /usr/include/bits/byteswap.h /usr/include/bits/uintn-identity.h \
+ /usr/include/sys/select.h /usr/include/bits/select.h \
+ /usr/include/bits/types/sigset_t.h /usr/include/bits/types/__sigset_t.h \
+ /usr/include/bits/types/struct_timeval.h \
+ /usr/include/bits/types/struct_timespec.h \
+ /usr/include/bits/pthreadtypes.h /usr/include/bits/thread-shared-types.h \
+ /usr/include/bits/pthreadtypes-arch.h
+
+/usr/include/stdc-predef.h:
+
+/usr/include/stdio.h:
+
+/usr/include/bits/libc-header-start.h:
+
+/usr/include/features.h:
+
+/usr/include/sys/cdefs.h:
+
+/usr/include/bits/wordsize.h:
+
+/usr/include/bits/long-double.h:
+
+/usr/include/gnu/stubs.h:
+
+/usr/include/gnu/stubs-64.h:
+
+/usr/lib/gcc/x86_64-redhat-linux/8/include/stddef.h:
+
+/usr/lib/gcc/x86_64-redhat-linux/8/include/stdarg.h:
+
+/usr/include/bits/types.h:
+
+/usr/include/bits/typesizes.h:
+
+/usr/include/bits/types/__fpos_t.h:
+
+/usr/include/bits/types/__mbstate_t.h:
+
+/usr/include/bits/types/__fpos64_t.h:
+
+/usr/include/bits/types/__FILE.h:
+
+/usr/include/bits/types/FILE.h:
+
+/usr/include/bits/types/struct_FILE.h:
+
+/usr/include/bits/stdio_lim.h:
+
+/usr/include/bits/sys_errlist.h:
+
+/usr/include/bits/stdio.h:
+
+subu-mk-0.fi.h:
+
+useradd.fi.h:
+
+/usr/include/unistd.h:
+
+/usr/include/bits/posix_opt.h:
+
+/usr/include/bits/environments.h:
+
+/usr/include/bits/confname.h:
+
+/usr/include/bits/getopt_posix.h:
+
+/usr/include/bits/getopt_core.h:
+
+/usr/include/sys/types.h:
+
+/usr/include/bits/types/clock_t.h:
+
+/usr/include/bits/types/clockid_t.h:
+
+/usr/include/bits/types/time_t.h:
+
+/usr/include/bits/types/timer_t.h:
+
+/usr/include/bits/stdint-intn.h:
+
+/usr/include/endian.h:
+
+/usr/include/bits/endian.h:
+
+/usr/include/bits/byteswap.h:
+
+/usr/include/bits/uintn-identity.h:
+
+/usr/include/sys/select.h:
+
+/usr/include/bits/select.h:
+
+/usr/include/bits/types/sigset_t.h:
+
+/usr/include/bits/types/__sigset_t.h:
+
+/usr/include/bits/types/struct_timeval.h:
+
+/usr/include/bits/types/struct_timespec.h:
+
+/usr/include/bits/pthreadtypes.h:
+
+/usr/include/bits/thread-shared-types.h:
+
+/usr/include/bits/pthreadtypes-arch.h:
index 5c17b7b..50ac521 100644 (file)
@@ -1,6 +1,14 @@
 #ifndef LOCAL_COMMON_H
 #define LOCAL_COMMON_H
 
+#include <stdbool.h>
+
+#define DEBUG
+
+// wstatus is the exec'ed program return code, which we only allow 16 bits
+// so as to also have exec routine error codes
+#define WSTATUS_MASK ((1 << 16) - 1)
+
 typedef unsigned int uint;
 
 
diff --git a/src/run.c b/src/run.c
new file mode 100644 (file)
index 0000000..6823a06
--- /dev/null
+++ b/src/run.c
@@ -0,0 +1,46 @@
+/*
+fork/exec/wait a command
+
+if the error values returned by the exec'd program
+are less than 1 << 16, then 
+
+*/
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include "local_common.h"
+
+struct run_err_struct run_err;
+
+int run(char **argv, char **envp){
+  run_err_init(run_err);
+  if( !argv || !argv[0] ){
+    fprintf(stderr, "argv[0] null on call to run().\n");
+    run_err.admin = ADMIN_ERR_NO_COMMAND;
+    return;
+  }
+  pid_t pid = fork(void);
+  if( pid == -1 ){
+    fprintf(stderr, "fork() failed in run().\n");
+    run_err.admin = ADMIN_ERR_FORK;
+    return;
+  }
+  if( pid == 0 ){ // we are the child
+    int run_err = execvpe(argv[0], argv, envp);
+    // exec will only return if it has an error ..
+    perror(command);
+    run_err.exec = errno;
+    return errno;
+  }else{ // we are the parent
+    int wstatus;
+    wait(1, &wstatus, 0);
+    if(wstatus != 0) run_err.process = wstatus;
+    if( run_err_has(run_err) )
+      return -1;
+    else
+      return 0;
+  }
+}
diff --git a/src/run.h b/src/run.h
new file mode 100644 (file)
index 0000000..8dbff3c
--- /dev/null
+++ b/src/run.h
@@ -0,0 +1,29 @@
+#ifndef RUN_FI_H
+#define RUN_FI_H
+
+#include "local_common.h"
+
+#define ADMIN_ERR_NO_COMMAND 1
+#define ADMIN_ERR_FORK 2
+#define ADMIN_ERR_ARGC 3
+
+struct run_err_struct{
+  int admin; // admin error
+  int exec;  // errno from failed exec call 
+  int process; // err code returned from process as reported by wait()
+};
+inline run_err_init(struct run_err_struct re){
+  re.admin = 0;
+  re.exec = 0;
+  re.process = 0;
+}
+inline run_err_has(struct run_err_struct re){
+  return re.admin || re.exec || re.process 
+}
+
+extern struct run_err_struct run_err;
+uint run(char **argv, char **envp);
+
+#endif
+
+
index 8649d10..7764191 100644 (file)
@@ -3,7 +3,8 @@
 
 */
 
-#include "subu-mk-0_fun.h"
+#include <stdio.h>
+#include "subu-mk-0.fi.h"
 
 int main(int argc, char **argv, char **env){
   char *command = argv[0];
diff --git a/src/subu-mk-0.def.c b/src/subu-mk-0.def.c
deleted file mode 100644 (file)
index 0adc76f..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
-  Makes a new subu user.
-
-  According to the man page, we are not alloed to free the buffers made by getpwid().
-
-  1. We have to make the subu first so that we will have subu_uid and subu_gid
-     to work with.
-
-  2. Then we add user access via setfacl to masteru's home directory and to
-     subu_land, so that we have permissions to make the home directory.
-
-  3. Then as subu we create the home directory. .. I wonder where the system
-     gets the umask for this?  Perhaps we should create the dir, and then change
-     the ownership instead?
-     
-  4. Still as subu, we add facls to our directory to give masteru access.
-
-  ... then finished, good part is that we never need to move back to root.
-
-setfacl -m u:subu:x masteru
-setfacl -m u:subu:x masteru/subu_land
-setfacl -m d:u:masteru:rwX,u:masteru:rwX subu
-
-*/
-// without #define get warning: implicit declaration of function ‘seteuid’/‘setegid’
-#define _GNU_SOURCE   
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <string.h>
-#include <sys/stat.h>
-#include "config.h"
-#include "subu_mk_0_fun.h"
-
-#define DEBUG
-typedef unsigned int uint;
-
-#define ERR_ARG_CNT 1
-#define ERR_SETUID_ROOT 2
-#define ERR_BAD_MASTERU_HOME 3
-#define ERR_NOT_EXIST_MASTERU_HOME 4
-#define ERR_FAILED_MKDIR_SUBU 5
-#define ERR_FAILED_RESTORATION 6
-
-uid_gid subu_mk_0(char *subu_name){
-
-  //--------------------------------------------------------------------------------
-  // help message
-  char *command = argv[0];
-  if( argc != 2 ){
-    fprintf(stderr, "usage: %s subu", command);
-    return ERR_ARG_CNT;
-  }
-
-  //--------------------------------------------------------------------------------
-  // we must be invoked from a user account and be running as root
-  uint uid = getuid();
-  uint euid = geteuid();
-  uint gid = getgid();
-  uint egid = getegid();
-  #ifdef DEBUG
-    printf("uid %u, gid %u, euid %u\n", uid, gid, euid);
-  #endif
-  if( uid == 0 || euid != 0 ){
-    fprintf(stderr, "this program must be run setuid root from a user account\n");
-    return ERR_SETUID_ROOT;
-  }
-
-  //--------------------------------------------------------------------------------
-  // who are these people anyway?
-  char *subu_name = argv[1];
-  struct passwd *passwd_record_pt = getpwuid(uid);
-  char *masteru_name = passwd_record_pt->pw_name;
-  // verify that subu_name is legal!  --> code goes here ...  
-
-  //--------------------------------------------------------------------------------
-  // build the subu_land path
-  char *masteru_home_dir = passwd_record_pt->pw_dir;
-  size_t masteru_home_dir_len = strlen(masteru_home_dir);
-  if( masteru_home_dir_len == 0 || masteru_home_dir[0] == '(' ){
-    fprintf(stderr,"strange, %s has no home directory\n", masteru_name);
-    return ERR_BAD_MASTERU_HOME;
-  }
-  char *subu_land_extension = "/subu_land/";
-  size_t subu_land_extension_len = strlen(subu_land_extension);
-  size_t subu_name_len = strlen(subu_name); // we leave room in the buffer to latter add the subu_name
-  char *subu_land = (char *)malloc( masteru_home_dir_len + subu_land_extension_len + subu_name_len + 1 );
-  strcpy(subu_land, masteru_home_dir);
-  strcpy(subu_land + masteru_home_dir_len, subu_land_extension);
-  #ifdef DEBUG
-  printf("The path to subu_land: %s\n", subu_land);
-  #endif
-
-  //--------------------------------------------------------------------------------
-  // Just because masteru_home_dir is referenced in /etc/passwd does not mean it exists.
-  // If it does, and the subu_land doesn't, then we make subu_land.
-  struct stat st;
-  if( stat(masteru_home_dir, &st) == -1) {
-    fprintf(stderr, "Strange, masteru home does not exist, %s.", masteru_home_dir);
-    return ERR_NOT_EXIST_MASTERU_HOME;
-  }
-
-  //--------------------------------------------------------------------------------
-  // the name for the subu home directory, which is subu_land/subu_name
-  size_t subu_land_len = masteru_home_dir_len + subu_land_extension_len + subu_name_len;
-  strcpy (subu_land + subu_land_len, subu_name); // we had left room in the subu_land buffer for subu_name
-  char *subu_home_path = subu_land; // the buffer now holds the subu_home_path, so we call it as such
-  #ifdef DEBUG
-  printf("subu home: %s\n", subu_home_path);
-  #endif
-
-  //--------------------------------------------------------------------------------
-  // we now make the subu 
-  char *useradd_argv[4];
-  useradd_argv[0] = command;
-  useradd_argv[1] = "-d";
-  useradd_argv[2] = subu_home_path;
-  useradd_argv[3] = (char *) NULL;
-  char *useradd_envp[1];
-  useradd_envp[0] (char *) NULL;
-  useradd_0(subu_name, useradd_argv, envp);
-  
-  // change to subu space
-  if( seteuid(uid) == -1 || setegid(gid) == -1 ){ // we are root so this should never happen
-    fprintf(stderr,"Strangely, root could not seteuid/setegid to %s\n", masteru_name);
-    return ERR_FAILED_MKDIR_SUBU;
-  }
-  if( stat(subu_land, &st) == -1) { // then make the directory
-    if( mkdir(subu_land, 0700) == -1 || stat(subu_land, &st) == -1 ){
-      fprintf(stderr,"Failed to make subu directory %s\n", subu_land);
-      return ERR_FAILED_MKDIR_SUBU;
-    }
-  }
-  //change back to set the acls
-  if( seteuid(euid) == -1 || setegid(egid) == -1 ){ 
-    fprintf(stderr,"Could not restore privledges, having to bail.\n");
-    return ERR_FAILED_RESTORATION;
-  }
-  return 0;
-}
diff --git a/src/subu-mk-0.fi.c b/src/subu-mk-0.fi.c
new file mode 100644 (file)
index 0000000..af64072
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+  Makes a new subu user.
+
+  According to the man page, we are not alloed to free the buffers made by getpwid().
+
+  1. We have to make the subu first so that we will have subu_uid and subu_gid
+     to work with.
+
+  2. Then we add user access via setfacl to masteru's home directory and to
+     subu_land, so that we have permissions to make the home directory.
+
+  3. Then we create the subu home directory. .. I wonder where the system
+     gets the umask for this?  Perhaps we should create the dir, and then change
+     the ownership instead?
+     
+  4. Still as subu, we add facls to our directory to give masteru access.
+
+  ... then finished, good part is that we never need to move back to root.
+
+setfacl -m u:subu:x masteru
+setfacl -m u:subu:x masteru/subu_land
+setfacl -m d:u:masteru:rwX,u:masteru:rwX subu
+
+*/
+// without #define get warning: implicit declaration of function ‘seteuid’/‘setegid’
+#define _GNU_SOURCE   
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <string.h>
+#include <sys/stat.h>
+#include "config.h"
+#include "subu_mk_0.fi.h"
+
+typedef unsigned int uint;
+
+uid_gid subu_mk_0(char *subu_name){
+
+  //--------------------------------------------------------------------------------
+  // we must be invoked from a user account and be running as root
+  uid_t uid = getuid();
+  uid_t euid = geteuid();
+  gid_t gid = getgid();
+  gid_t egid = getegid();
+  #ifdef DEBUG
+    printf("uid %u, gid %u, euid %u\n", uid, gid, euid);
+  #endif
+  if( uid == 0 || euid != 0 ){
+    fprintf(stderr, "this program must be run setuid root from a user account\n");
+    return ERR_SETUID_ROOT;
+  }
+
+  //--------------------------------------------------------------------------------
+  // who are these people anyway?
+  size_t subu_name_len;
+  char *masteru_name;
+  {
+    // subu_name is the first argument passed in
+    // verify that subu_name is legal!  --> code goes here ...  
+    subu_name_len = strlen(subu_name);
+    struct passwd *masteru_pw_record_pt = getpwuid(uid);
+    masteru_name = materu_pw_record_pt->pw_name;
+  }
+  #ifdef DEBUG
+  printf("masteru_name: %s\n", masteru_name);
+  #endif
+
+  //--------------------------------------------------------------------------------
+  // build the subu_land path
+  char *subu_land;
+  size_t subu_land_len;
+  {
+    char *masteru_home_dir = passwd_record_pt->pw_dir;
+    size_t masteru_home_dir_len = strlen(masteru_home_dir);
+    if( masteru_home_dir_len == 0 || masteru_home_dir[0] == '(' ){
+      fprintf(stderr,"strange, %s has no home directory\n", masteru_name);
+      return ERR_BAD_MASTERU_HOME;
+    }
+    char *subu_land_extension = "/subu_land/";
+    size_t subu_land_extension_len = strlen(subu_land_extension);
+    // add space in the subu_land buffer to append the subu_name later
+    subu_land = (char *)malloc( masteru_home_dir_len + subu_land_extension_len + subu_name_len + 1 );
+    strcpy(subu_land, masteru_home_dir);
+    strcpy(subu_land + masteru_home_dir_len, subu_land_extension);
+    subu_land_len = masteru_home_dir_len + subu_land_extension_len + subu_name_len;
+  }
+  #ifdef DEBUG
+  printf("The path to subu_land: \"%s\"\n", subu_land);
+  #endif
+
+  //--------------------------------------------------------------------------------
+  // Just because masteru_home_dir is referenced in /etc/passwd does not mean it exists.
+  // We also require that the subu_land sub directory exists.
+  {
+    struct stat st;
+    if( stat(masteru_home_dir, &st) == -1) {
+      fprintf(stderr, "Strange, masteru home does not exist, \"%s\".", masteru_home_dir);
+      return ERR_NOT_EXIST_MASTERU_HOME;
+    }
+    if( stat(subu_land, &st) == -1) {
+      fprintf(stderr, "$masteru_home/subu_land not exist");
+      return ERR_NOT_EXIST_SUBU_LAND;
+    }
+  }
+
+  //--------------------------------------------------------------------------------
+  // the name for the subu home directory, which is subu_land/subu_name
+  strcpy (subu_land + subu_land_len, subu_name); // we had left room in the subu_land buffer for subu_name
+  char *subu_home_path = subu_land; // the buffer now holds the subu_home_path, so we call it as such
+  #ifdef DEBUG
+  printf("subu home: %s\n", subu_home_path);
+  #endif
+
+  //--------------------------------------------------------------------------------
+  // make the subservient user account
+  uid_t subu_uid;
+  tid_t subu_gid;
+  {
+    char *argv[5];
+    argv[0] = command;
+    argv[1] = subu_name;
+    argv[2] = "-d";
+    argv[3] = subu_home_path;
+    argv[4] = (char *) NULL;
+    char *envp[1];
+    envp[0] (char *) NULL;
+    struct ret u_ret = useradd(argv, envp);
+    if(ret.error){
+      fprintf(stderr, "%u useradd failed\n", ret.error)
+      return ERR_FAILED_USERADD;
+    }
+    subu_uid = user_ret.pw_record->pw_uid;
+    subu_gid = user_ret.pw_record->pw_gid;
+  }  
+  
+  //--------------------------------------------------------------------------------
+  // Set acls on the subu home directory
+  
+
+  // subu sets acls to allow masteru access
+  
+  return 0;
+}
+
+/*
+  // change to subu space
+  if( seteuid(subu_uid) == -1 || setegid(subu_gid) == -1 ){ // we are root so this should never happen
+    fprintf(stderr,"Strangely, root could not seteuid/setegid to %s\n", subu_name);
+    return ERR_FAILED_MKDIR_SUBU;
+  }
+
+*/
diff --git a/src/subu-mk-0.fi.h b/src/subu-mk-0.fi.h
new file mode 100644 (file)
index 0000000..cf2828d
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef SUBU_MK_0_H
+#define SUBU_MK_0_H
+
+#include "useradd.fi.h"
+
+#define ERR_ARG_CNT 1
+#define ERR_SETUID_ROOT 2
+#define ERR_BAD_MASTERU_HOME 3
+#define ERR_NOT_EXIST_MASTERU_HOME 4
+#define ERR_NOT_EXIST_SUBU_LAND 5
+#define ERR_FAILED_MKDIR_SUBU 6
+#define ERR_FAILED_RESTORATION 7
+#define ERR_FAILED_USERADD 8
+
+
+struct uid_gid subu_mk_0(char *subu_name);
+
+#endif
diff --git a/src/subu_mk_0_def.h b/src/subu_mk_0_def.h
deleted file mode 100644 (file)
index 1749c43..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef SUBU_MK_0_H
-#define SUBU_MK_0_H
-
-#include "useradd-fun.h"
-uid_gid subu_mk_0(char *subu_name);
-
-#endif
diff --git a/src/useradd.fi.c b/src/useradd.fi.c
new file mode 100644 (file)
index 0000000..ff91646
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+There is no C library interface to useradd(8), but if there were, these functions
+would be found there instead.
+
+*/
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include "local_common.h"
+#include "run.h"
+
+// we have a contract with the caller that argv[1] is always the subuname
+useradd_ret useradd(char **argv, char **envp){
+  run_err_init(run_err);
+  if( !argv || !argv[0] || !argv[1]){
+    fprintf(stderr,"useradd() needs a first argument as the name of the user to be made");
+    return useradd_ret(USERADD_ERR_ARGC, NULL);
+  }
+  char *subu_name = argv[1];
+  if( run(argv, envp) == -1 ){
+    fprintf(stderr,"%s failed\n", argv[0]);
+    return useradd_ret(USER_ERR_RUN);
+  }
+  struct password *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 ){
+    return struct useradd_ret(USERADD_ERR_PWREC, NULL);
+  }
+  return struct useradd_ret(0, pw_record);
+}
+
diff --git a/src/useradd.fi.h b/src/useradd.fi.h
new file mode 100644 (file)
index 0000000..0042f1d
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef USERADD_FI_H
+#define USERADD_FI_H
+
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/types.h>
+
+// some value larger than any wstatus value
+#define USERADD_ERR_UNDEFINED (1 << 16);
+#define USERADD_ERR_ARGCNT (2 << 16);
+#define USERADD_ERR_PWREC (3 << 16);
+
+// only use pw_record if error is zero
+struct useradd_ret{
+  useradd_ret(error=USERADD_ERR_UNDEFINED,pwd=NULL):error(error),pwd(pwd){}
+  int error;
+  struct password *pw_record;// as per getpwnam man page do not free() this.
+};
+struct useradd_ret useradd(char **argv, char **envp);
+
+#endif
+
+
diff --git a/src/useradd_fun.c b/src/useradd_fun.c
deleted file mode 100644 (file)
index 8fe6d13..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-There is no C library interface to useradd(8), but if there were, these functions
-would be found there instead. I'm also wondering about the wisdom of using
-useradd(8) from shadow.  Wondering if the locks are in place for multiple users hitting it
-simultaneously via different methods, and if it handles signals cleanly.
-
-We pass argv[1:..] and envp through to useradd.  We return the uid of the newly
-created user, or the negative value of the return code from useradd(8)
-
-*/
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-
-// better to change this to vargs for the option list
-// this currently works because I know there is only one option
-int useradd_0(char *user, char **argv, char **envp){
-  char *subu_name;
-  if( argv && argv[0] && argv[1] ){
-    
-  }
-  pid_t pid = fork(void);
-  if( pid == -1 ) return 1;
-  if( pid == 0 ){ // we are the child
-    char *command = "/usr/bin/useradd";
-    argv[0] = command; // we can do this because we made the argv in the caller
-    int err = execvpe( command, argv, envp);
-    fprintf(stderr, "subu execvpe call to /usr/bin/useradd issued error %d, but it is too difficult to tell the parent process about this.", errno);
-  } else {
-    int wstatus;
-    wait(1, &wstatus, 0);
-    if(wstatus != 0) return -abs(wstatus);
-    // useradd did not tell us the uid of the newly created user, so now we have go get it.
-    struct passwd *getpwname(
-  }
-
-}
diff --git a/src/useradd_fun.h b/src/useradd_fun.h
deleted file mode 100644 (file)
index a2d6e2f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-
-#ifndef USERADD_H
-#define USERADD_H
-#include local_common.h
-
-struct uid_gid{
-  uint error;
-  pid_t uid;
-  pid_t gid;
-};
-
-uit_gid useradd_0(char *user, char **argv, char **envp);
-
-#endif