subu-mk-0 working
authorThomas Walker Lynch <thomas.lynch@reasoningtechnology.com>
Tue, 5 Mar 2019 21:04:10 +0000 (22:04 +0100)
committerThomas Walker Lynch <thomas.lynch@reasoningtechnology.com>
Tue, 5 Mar 2019 21:04:10 +0000 (22:04 +0100)
14 files changed:
src/5_scratch/common.lib.h
src/5_scratch/dispatch_f.lib.h
src/5_scratch/subu-config.lib.h
src/5_scratch/subu-mk-0.cli.h
src/5_scratch/subu-mk-0.lib.h
src/5_scratch/subu-number.cli.h
src/5_scratch/subu-put.cli.h [new file with mode: 0644]
src/common.lib.c
src/dispatch_f.lib.c
src/subu-config.lib.c
src/subu-mk-0.cli.c
src/subu-mk-0.lib.c
src/subu-number.cli.c
src/subu-put.cli.c [new file with mode: 0644]

index f3c3c8f..217c0f7 100644 (file)
@@ -1,5 +1,7 @@
 /* \aThis file was automatically generated.  Do not edit! */
 #undef INTERFACE
-extern char config_file[];
 typedef unsigned int uint;
+extern uint subuhome_perms;
+extern char config_file[];
+#define BUG_SSS_CACHE_RUID 1
 #define INTERFACE 0
index 85eaf80..6b3653f 100644 (file)
@@ -2,10 +2,21 @@
 #undef INTERFACE
 #include <sys/types.h>
 #include <unistd.h>
-int dispatch_f_euid_egid(char *fname,int(*f)(void *arg),void *f_arg,uid_t euid,gid_t egid);
+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,...);
-int dispatch_f(char *fname,int(*f)(void *arg),void *f_arg);
-#define ERR_DISPATCH_F_SETEGID 3
-#define ERR_DISPATCH_F_SETEUID 2
-#define ERR_DISPATCH_F_FORK 1
+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
index bed36a7..a692fbd 100644 (file)
@@ -1,8 +1,9 @@
 /* \aThis file was automatically generated.  Do not edit! */
 #undef INTERFACE
 #include <sqlite3.h>
+int subu_put_masteru_subu(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
+int subu_number_get(sqlite3 *db,char **nsp,char **errmsg);
 typedef unsigned int uint;
-int subu_number_get(sqlite3 *db,uint *subu_number);
 int schema(sqlite3 *db,uint max_subu_number);
 #define ERR_CONFIG_FILE -1
 #define INTERFACE 0
index 6aaecca..b9bfff1 100644 (file)
@@ -1,6 +1,20 @@
 /* \aThis file was automatically generated.  Do not edit! */
 #undef INTERFACE
-extern char config_file[];
+#include <stdbool.h>
+#include <errno.h>
 #include <sqlite3.h>
-int subu_mk_0(char *subuname,char *config_file);
-#define ERR_SUBU_MK_0_ARG_CNT 1
+typedef struct subu_mk_0_ctx subu_mk_0_ctx;
+void subu_mk_0_ctx_free(struct subu_mk_0_ctx *ctxp);
+void subu_mk_0_mess(struct subu_mk_0_ctx *ctxp);
+struct subu_mk_0_ctx *subu_mk_0(sqlite3 *db,char *subuname);
+typedef unsigned int uint;
+struct subu_mk_0_ctx {
+  char *name;
+  char *subuland;
+  char *subuhome;
+  char *subu_username;
+  bool free_aux;
+  char *aux;
+  uint err;
+};
+extern char config_file[];
index bcc2b2c..22fb1fc 100644 (file)
@@ -1,6 +1,7 @@
 /* \aThis file was automatically generated.  Do not edit! */
 #undef INTERFACE
-int dispatch_exec(char **argv,char **envp);
+#include <sqlite3.h>
+int subu_put_masteru_subu(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
 #include <sys/types.h>
 #include <pwd.h>
 typedef struct dispatch_useradd_ret_t dispatch_useradd_ret_t;
@@ -10,22 +11,42 @@ struct dispatch_useradd_ret_t {
   struct passwd *pw_record;  
 };
 struct dispatch_useradd_ret_t dispatch_useradd(char **argv,char **envp);
+#define BUG_SSS_CACHE_RUID 1
 #include <unistd.h>
-int dispatch_f_euid_egid(char *fname,int(*f)(void *arg),void *f_arg,uid_t euid,gid_t egid);
+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);
+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
+};
+int subu_number_get(sqlite3 *db,char **nsp,char **errmsg);
 int dbprintf(const char *format,...);
-extern char config_file[];
-#include <sqlite3.h>
-int subu_mk_0(char *subuname,char *config_file);
-int masteru_makes_subuhome(void *arg);
-int allowed_subuname(char *subuname);
-#define ERR_SUBU_MK_0_SETFACL 10
+#include <stdbool.h>
+#include <errno.h>
+typedef struct subu_mk_0_ctx subu_mk_0_ctx;
+struct subu_mk_0_ctx *subu_mk_0(sqlite3 *db,char *subuname);
+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 9
 #define ERR_SUBU_MK_0_BUG_SSS 8
-#define ERR_SUBU_MK_0_FAILED_MKDIR_SUBU 7
-#define ERR_SUBU_MK_0_MK_SUBUHOME 6
+#define ERR_SUBU_MK_0_SUBUHOME_EXISTS 7
+#define ERR_SUBU_MK_0_CONFIG_FILE 6
 #define ERR_SUBU_MK_0_MALLOC 5
-#define ERR_SUBU_MK_0_BAD_MASTERU_HOME 4
+#define ERR_SUBU_MK_0_MASTERU_HOMELESS 4
 #define ERR_SUBU_MK_0_SETUID_ROOT 3
-#define ERR_SUBU_MK_0_CONFIG_FILE 2
-#define ERR_SUBU_MK_0_ARG_CNT 1
+#define ERR_SUBU_MK_0_SUBUNAME_MALFORMED 2
+#define ERR_SUBU_MK_0_MKDIR_SUBUHOME 1
 #define INTERFACE 0
index 9844291..35b0da0 100644 (file)
@@ -1,8 +1,6 @@
 /* \aThis file was automatically generated.  Do not edit! */
 #undef INTERFACE
 #include <sqlite3.h>
+int subu_number_get(sqlite3 *db,char **nsp,char **errmsg);
 #define ERR_CONFIG_FILE -1
 extern char config_file[];
-typedef unsigned int uint;
-int subu_number_get(sqlite3 *db,uint *subu_number);
-int print_subu_number(sqlite3 *db);
diff --git a/src/5_scratch/subu-put.cli.h b/src/5_scratch/subu-put.cli.h
new file mode 100644 (file)
index 0000000..ee08783
--- /dev/null
@@ -0,0 +1,6 @@
+/* \aThis file was automatically generated.  Do not edit! */
+#undef INTERFACE
+#include <sqlite3.h>
+int subu_put_masteru_subu(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
+#define ERR_CONFIG_FILE -1
+extern char config_file[];
index 1384e73..6da0ca2 100644 (file)
@@ -1,8 +1,18 @@
 
+#include "common.lib.h"
 
 #if INTERFACE
 typedef unsigned int uint;
+/*
+  Fedora 29's sss_cache is checking the inherited uid instead of the effective
+  uid, so setuid root scripts will fail when calling sss_cache.
+
+  Fedora 29's 'useradd' calls sss_cache, and useradd is called by our setuid root 
+  program subu-mk-0.
+*/
+#define BUG_SSS_CACHE_RUID 1
 #endif
 
 //  char *config_file = "/etc/subu.db";
 char config_file[] = "subu.db";
+uint subuhome_perms = 0700;
index eda75da..5c199f5 100644 (file)
@@ -1,8 +1,8 @@
 /*
   Forks a new process and runs the a function in that new process.  I.e. it 'spawns' a function.
 
-  f must have a specific prototype.  It accepts one void pointer, and it returns a positive
-  integer.  
+  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 INTERFACE
 #include <sys/types.h>
 #include <unistd.h>
+#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
-#endif
 
 // both name and fname are static allocations
 struct dispatch_f_ctx{
-  char *name; // name of the dispatch function (currently "dispatch_f" or "dispatch_f_euid_egid")
-  char *fname; // name of the function being dispatched
-  uint err;
+  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){
-  ctxp = malloc(sizeof(dispatch_f_ctx));
+  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(dispatchf_ctx *ctxp){
-  free(ctxp); // no dynamic variables in this context
+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;
@@ -59,9 +66,9 @@ void dispatch_f_mess(struct dispatch_f_ctx *ctxp){
   case ERR_NEGATIVE_RETURN_STATUS:
     fprintf(stderr, "%s, function \"%s\" broke contract with a negative return value.", ctxp->dispatcher, ctxp->dispatchee);
     break;
-  case ERR_DISPATCHED_F_FORK:
-  case ERR_DISPATCHED_F_SETEUID:
-  case ERR_DISPATCHED_F_SETEGID:
+  case ERR_DISPATCH_F_FORK:
+  case ERR_DISPATCH_F_SETEUID:
+  case ERR_DISPATCH_F_SETEGID:
     fprintf(stderr, "%s, ", ctxp->dispatcher);
     perror(ctxp->dispatcher);
     break;
@@ -69,6 +76,8 @@ void dispatch_f_mess(struct dispatch_f_ctx *ctxp){
   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
@@ -89,6 +98,8 @@ dispatch_f_ctx *dispatch_f(char *fname, int (*f)(void *arg), void *f_arg){
   }
 }
 
+//--------------------------------------------------------------------------------
+// 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
index fda7ed8..d10ad96 100644 (file)
@@ -65,13 +65,13 @@ static char *subu_number_sql =
   "COMMIT;";
 int subu_number_get(sqlite3 *db, char **nsp, char **errmsg){
   int ret;
-  ret = sqlite3_exec(db, sql, subu_number_extract, (void *)nsp, errmsg);
+  ret = sqlite3_exec(db, subu_number_sql, subu_number_extract, (void *)nsp, errmsg);
   return ret;
 }
 
 //--------------------------------------------------------------------------------
 int subu_put_masteru_subu(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username){
-  char *sql = "INSERT INTO Master_Subu (?1, ?2, ?3);";
+  char *sql = "INSERT INTO Master_Subu VALUES (?1, ?2, ?3);";
   size_t sql_len = strlen(sql);
   sqlite3_stmt *stmt;
   sqlite3_prepare_v2(db, sql, sql_len, &stmt, NULL);
index fb111a2..1de32f1 100644 (file)
@@ -2,9 +2,12 @@
   subu-mk-0 command
 
 */
-#include "subu-mk-0.lib.h"
+#include "subu-mk-0.cli.h"
 #include <stdio.h>
 
+#define ERR_SUBU_MK_0_ARG_CNT 1
+#define ERR_SUBU_CONFIG_FILE 2
+
 int main(int argc, char **argv){
   char *command = argv[0];
   if( argc != 2 ){
@@ -18,10 +21,10 @@ int main(int argc, char **argv){
   ret = sqlite3_open_v2(config_file, &db, SQLITE_OPEN_READWRITE, NULL);
   if( ret != SQLITE_OK ){
     fprintf(stderr, "error exit, could not open configuration file\n");
-    return ERR_CONFIG_FILE;
+    return ERR_SUBU_CONFIG_FILE;
   }
 
-  subu_mk_0_ctx *ctxp = subu_mk_0(sqlite3 *db, subuname);
+  struct subu_mk_0_ctx *ctxp = subu_mk_0(db, subuname);
   subu_mk_0_mess(ctxp);
   int err = ctxp->err;
   subu_mk_0_ctx_free(ctxp);
index 3b087fc..9efa311 100644 (file)
@@ -1,16 +1,22 @@
 /*
-  Makes a new subu user. This routine creates the bindfs mount point under
-  subuland, creates the _s<number>  user, and adds the master / subu relation
-  to configuration file.
+  subu-mk-0 makes a new subu user. The '-0' signifies it is a low level program,
+  and probably will not be called directly.
 
-  masteru is the user who ran this script. subu is a subservient user.  subuname
-  is passed as an argument, we get the materu name from getuid and /etc/passwd.
+  masteru is the user who ran this script. subu is a subservient user to be
+  created.  subuname is passed as an argument. The masteru name comes from
+  getuid and /etc/passwd.
+
+  subu-mk-0 synthesizes a new user with the name s<number>, enters the
+  relationship between masteru, subu, and s<number> in the config file, and it
+  makes a bindfs mount point for the s<number> user under masteru's 'subuland'
+  directory.
 
   subu-mk-0 is a setuid root script. 
 
-  sqllite3 is used to maintain the configuration file, which is currently /etc/subu.db
+  sqllite3 is used to maintain the configuration file, which is currently compiled
+  in as /etc/subu.db, (or just subu.db for testing).
 
-  useradd is called to make the _s<number> user
+  useradd is called to make the s<number> user
 
   Note, as per the man page, we are not allowed to free the memory allocated by getpwid().
 
 #include <sys/types.h>
 #include <unistd.h>
 #include <stdio.h>
-#include <errno.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <pwd.h>
 #include <string.h>
 #include <sys/stat.h>
-#include <stdbool.h>
 
+#if INTERFACE
+#include <stdbool.h>
+#include <errno.h>
+#include <sqlite3.h>
+#endif
 
-/*
-  Fedora 29's sss_cache is checking the inherited uid instead of the effective
-  uid, so setuid root scripts will fail when calling sss_cache. Fedora 29's
-  'useradd'  calls sss_cache.
-*/
-#define BUG_SSS_CACHE_RUID 1
-  
-// a well formed subuname
-// wonder if it makes sense to add a length limit ...
-// returns the length of the subuname, or -1
-int allowed_subuname(char *subuname, size_t &subuname_len){
-  char *ch = subuname;
-  uint i = 0;
-  while(
-     *ch
-     &&
-     ( *ch >= 'a' && *ch <= 'z'
-       ||
-       *ch >= 'A' && *ch <= 'Z'
-       ||
-       *ch >= '0' && *ch <= '9'
-       ||
-       *ch == '-'
-       ||
-       *ch == '_'
-       ||
-       *ch == '.'
-       ||
-       *ch == ' '
-       )
-  ){
-    ch++;
-    i++;
-  }
-  if( !*ch ){
-    subuname_len = i;
-    return 0;
-  }else
-    return -1;
-}
+//--------------------------------------------------------------------------------
+// an instance is subu_mk_0_ctx is returned by subu_mk_0
+//
+#if INTERFACE
+#define ERR_SUBU_MK_0_MKDIR_SUBUHOME 1
+#define ERR_SUBU_MK_0_SUBUNAME_MALFORMED 2
+#define ERR_SUBU_MK_0_SETUID_ROOT 3
+#define ERR_SUBU_MK_0_MASTERU_HOMELESS 4
+#define ERR_SUBU_MK_0_MALLOC 5
+#define ERR_SUBU_MK_0_CONFIG_FILE 6
+#define ERR_SUBU_MK_0_SUBUHOME_EXISTS 7
+#define ERR_SUBU_MK_0_BUG_SSS 8
+#define ERR_SUBU_MK_0_FAILED_USERADD 9
 
 struct subu_mk_0_ctx{
   char *name;
   char *subuland;
   char *subuhome;
   char *subu_username;
+  bool free_aux;
   char *aux;
   uint err;
 };
-ctxp *subu_mk_0_ctx_mk(){
-  ctxp = malloc(sizeof(subu_mk_0_ctx));
+#endif
+struct subu_mk_0_ctx *subu_mk_0_ctx_mk(){
+  struct subu_mk_0_ctx *ctxp = malloc(sizeof(struct subu_mk_0_ctx));
   ctxp->name = "subu_mk_0";
   ctxp->subuland = 0;
   ctxp->subuhome = 0;
@@ -92,28 +75,14 @@ ctxp *subu_mk_0_ctx_mk(){
   ctxp->free_aux = false;
   ctxp->aux = 0;
 }
-void subu_mk_0_ctx_free(subu_mk_0_ctx ctxp){
+void subu_mk_0_ctx_free(struct subu_mk_0_ctx *ctxp){
   free(ctxp->subuland);
   free(ctxp->subuhome);
   free(ctxp->subu_username);
   if(ctxp->free_aux) free(ctxp->aux);
-  free ctxp;
+  free(ctxp);
 }
-
-#if INTERFACE
-#include <sqlite3.h>
-#define ERR_SUBU_MK_0_MKDIR_SUBUHOME 1
-#define ERR_SUBU_MK_0_SUBUNAME_MALFORMED 2
-#define ERR_SUBU_MK_0_SETUID_ROOT 3
-#define ERR_SUBU_MK_0_MASTERU_HOMELESS 4
-#define ERR_SUBU_MK_0_MALLOC 5
-#define ERR_SUBU_MK_0_CONFIG_FILE 6
-#define ERR_SUBU_MK_0_SUBUHOME_EXISTS 7
-#define ERR_SUBU_MK_0_BUG_SSS 8
-#define ERR_SUBU_MK_0_FAILED_USERADD 9
-#define 
-#endif
-// must be called before any system calls, or perror() will be messed up
+// must be called before any system calls, otherwise perror() will be messed up
 void subu_mk_0_mess(struct subu_mk_0_ctx *ctxp){
   switch(ctxp->err){
   case 0: return;
@@ -121,60 +90,101 @@ void subu_mk_0_mess(struct subu_mk_0_ctx *ctxp){
     fprintf(stderr, "masteru could not make subuhome, \"%s\"", ctxp->subuhome);
     break;
   case ERR_SUBU_MK_0_SUBUNAME_MALFORMED:
-    fprintf(stderr, "subuname, \"%s\" is not in [ _.\-a-zA-Z0-9]*", ctxp->aux);
+    fprintf(stderr, "subuname, \"%s\" is not in [ _.-a-zA-Z0-9]*", ctxp->aux);
     break;
   case ERR_SUBU_MK_0_SETUID_ROOT:
     fprintf(stderr, "This program must be run setuid root from a user account.");
     break;
   case ERR_SUBU_MK_0_MASTERU_HOMELESS:
-    char *masteru_name = aux; // this should not be freed
-    fprintf(stderr,"Masteru, \"%s\", has no home directory", masteru_name);
+    fprintf(stderr,"Masteru, \"%s\", has no home directory", ctxp->aux);
     break;
-  case ERR_SUBU_MK_0_MALLOC 
+  case ERR_SUBU_MK_0_MALLOC:
     perror(ctxp->name);
-    break;
-  case ERR_SUBU_MK_0_CONFIG_FILE
+  break;
+  case ERR_SUBU_MK_0_CONFIG_FILE:
     fprintf(stderr, "config file error: %s", ctxp->aux);
-    break;
-  case ERR_SUBU_MK_0_SUBUHOME_EXISTS
+  break;
+  case ERR_SUBU_MK_0_SUBUHOME_EXISTS:
     fprintf(stderr, "a file system object already exists at subuhome, \"%s\"\n", ctxp->subuhome);
-    break;
-  case ERR_SUBU_MK_0_BUG_SSS 
+  break;
+  case ERR_SUBU_MK_0_BUG_SSS:
     perror(ctxp->name);
-    break;
-  case ERR_SUBU_MK_0_FAILED_USERADD 
+  break;
+  case ERR_SUBU_MK_0_FAILED_USERADD:
     fprintf(stderr, "%u useradd failed\n", ctxp->subu_username);
-    break;
+  break;
   default:
+    fprintf(stderr, "unknown error code %d\n", ctxp->err);
   }
   fputc('\n', stderr);
 }
 
-// will be called through dispatch_f_as masteru
-static uint masteru_makes_subuhome(void *arg){
+
+//--------------------------------------------------------------------------------
+// a well formed subuname
+// returns the length of the subuname, or -1
+//
+static int allowed_subuname(char *subuname, size_t *subuname_len){
+  char *ch = subuname;
+  size_t i = 0;
+  while(
+        *ch
+        &&
+        ( *ch >= 'a' && *ch <= 'z'
+          ||
+          *ch >= 'A' && *ch <= 'Z'
+          ||
+          *ch >= '0' && *ch <= '9'
+          ||
+          *ch == '-'
+          ||
+          *ch == '_'
+          ||
+          *ch == '.'
+          ||
+          *ch == ' '
+          )
+        ){
+    ch++;
+    i++;
+  }
+  if( !*ch ){
+    *subuname_len = i;
+    return 0;
+  }else
+    return -1;
+}
+
+//--------------------------------------------------------------------------------
+// dispatched functions
+//
+// the making of subuhome is dispatched to its own process so as to give it its own uid/gid
+static int masteru_makes_subuhome(void *arg){
   char *subuhome = (char *) arg;
-  if( mkdir( subuhome, 0700 ) == -1 ){
+  if( mkdir( subuhome, subuhome_perms ) == -1 ){ // find subuhome perms in common
     perror("masteru_makes_subuhome");
     return ERR_SUBU_MK_0_MKDIR_SUBUHOME;
   }
   return 0;
 }
 
-subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
+//--------------------------------------------------------------------------------
+//  the public call point
+struct subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
 
-  subu_mk_0_ctx *ctxp = subu_mk_0_ctx_mk();
+  struct subu_mk_0_ctx *ctxp = subu_mk_0_ctx_mk();
 
   //--------------------------------------------------------------------------------
   #ifdef DEBUG
-  dbprintf("Checking that subuname is well formed, counting its length.\n");
+  dbprintf("Checking that subuname is well formed and finding its length\n");
   #endif
   size_t subuname_len;
   {
-    int ret = allowed_subuname(subuname, subuname_len);
+    int ret = allowed_subuname(subuname, &subuname_len);
     if( ret == -1 ){
-      ctxp->err = ERR_SUBU_MK_0_SUBU_MALFORMED;
+      ctxp->err = ERR_SUBU_MK_0_SUBUNAME_MALFORMED;
       ctxp->aux = subuname;
-      return ctxp
+      return ctxp;
     }}
   
   //--------------------------------------------------------------------------------
@@ -201,7 +211,7 @@ subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
 
   //--------------------------------------------------------------------------------
   #ifdef DEBUG
-  dbprintf("creation of required strings and recording their lengths\n");
+  dbprintf("strings masteru_name and masteru_home\n");
   #endif
 
   char *masteru_name;
@@ -217,6 +227,7 @@ subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
     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
@@ -243,12 +254,12 @@ subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
 
   //--------------------------------------------------------------------------------
   #ifdef DEBUG
-  dbprintf("generate the subu_username, set the subuhome\n");
+  dbprintf("strings subu_username and subuhome\n");
   #endif
   size_t subu_username_len;
   size_t subuhome_len;
   {
-    char *ns=0;
+    char *ns=0; // 'ns'  Number as String
     char *mess=0;
     if( subu_number_get( db, &ns, &mess ) != SQLITE_OK ){
       ctxp->err = ERR_SUBU_MK_0_CONFIG_FILE;
@@ -256,7 +267,7 @@ subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
       ctxp->free_aux = true;
       return ctxp;
     }
-    ns_len = strlen(ns);
+    size_t ns_len = strlen(ns);
     ctxp->subu_username = malloc(1 + ns_len + 1);
     if( !ctxp->subu_username ){
       ctxp->err = ERR_SUBU_MK_0_MALLOC;
@@ -269,15 +280,14 @@ subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
     dbprintf("subu_username \"%s\" %zu\n", ctxp->subu_username, subu_username_len);
     #endif
 
-    subuhome_len = subuland_len + subu_username_len; 
+    subuhome_len = subuland_len + subuname_len; 
     ctxp->subuhome = (char *)malloc(subuhome_len + 1);
     if( !ctxp->subuhome ){
       ctxp->err = ERR_SUBU_MK_0_MALLOC;
       return ctxp;
     }
     strcpy (ctxp->subuhome, ctxp->subuland);
-    strcpy (ctxp->subuhome + subuland_len, subu_username_len);
-    subuhome_len = subuland_land_len + subu_username_len;
+    strcpy (ctxp->subuhome + subuland_len, subuname);
     #ifdef DEBUG
     dbprintf("subuhome \"%s\" %zu\n", ctxp->subuhome, subuhome_len);
     #endif
@@ -295,7 +305,7 @@ subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
       ctxp->err = ERR_SUBU_MK_0_SUBUHOME_EXISTS;
       return ctxp;
     }
-    int ret = dispatch_f_euid_egid
+    struct dispatch_f_ctx *dfr = dispatch_f_euid_egid
       (
        "masteru_makes_subuhome", 
        masteru_makes_subuhome, 
@@ -303,7 +313,7 @@ subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
        masteru_uid, 
        masteru_gid
        );
-    if( ret < 0 || ret == ERR_SUBU_MK_0_MKDIR_SUBUHOME ){
+    if( dfr->err < 0 || dfr->err == ERR_SUBU_MK_0_MKDIR_SUBUHOME ){
       ctxp->err = ERR_SUBU_MK_0_MKDIR_SUBUHOME;
       return ctxp;
     }
@@ -312,13 +322,11 @@ subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
   dbprintf("masteru made directory \"%s\"\n", ctxp->subuhome);
   #endif
 
-  /*--------------------------------------------------------------------------------
-    Make the subservient user account, i.e. the subu
-
-  */
+  //--------------------------------------------------------------------------------
+  //  Make the subservient user account, i.e. the subu
   {
     #ifdef DEBUG
-      dbprintf("making subu \"%s\ as user \"%s\"\n", subuname, ctxp->subu_username);
+      dbprintf("making subu \"%s\" as user \"%s\"\n", subuname, ctxp->subu_username);
     #endif
     #if BUG_SSS_CACHE_RUID
       #ifdef DEBUG
@@ -332,7 +340,7 @@ subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
     char *command = "/usr/sbin/useradd";
     char *argv[3];
     argv[0] = command;
-    argv[1] = subu_username;
+    argv[1] = ctxp->subu_username;
     argv[2] = (char *) NULL;
     char *envp[1];
     envp[0] = (char *) NULL;
@@ -343,7 +351,7 @@ subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
       return ctxp;
     }
     #ifdef DEBUG
-    dbprintf("added user \"%s\"\n", subu_username);
+    dbprintf("added user \"%s\"\n", ctxp->subu_username);
     #endif
   }  
   
@@ -352,8 +360,8 @@ subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
   dbprintf("setting the masteru_name, subuname, subu_username relation\n");
   #endif
   {
-    int ret = subu_put_masteru_subu(db, masteru_name, subuname, subu_username);
-    if( rc != SQLITE_DONE ){
+    int ret = subu_put_masteru_subu(db, masteru_name, subuname, ctxp->subu_username);
+    if( ret != SQLITE_DONE ){
       ctxp->err = ERR_SUBU_MK_0_CONFIG_FILE;
       ctxp->aux = "insert of masteru subu relation failed";
       return ctxp;
@@ -363,5 +371,6 @@ subu_mk_0_ctx *subu_mk_0(sqlite3 *db, char *subuname){
   #ifdef DEBUG
   dbprintf("finished subu-mk-0(%s)\n", subuname);
   #endif
-  RETURN_SUBU_MK_0(0);
+  ctxp->err = 0;
+  return ctxp;
 }
index 52c7ae5..fc91dd3 100644 (file)
@@ -4,11 +4,7 @@ Set or get a new maximum subu number. Currently doesn't do the setting part.
 */
 #include "subu-number.cli.h"
 #include <stdio.h>
-
-
-int print_subu_number(sqlite3 *db){
-  return ret;
-}
+#include <stdlib.h>
 
 int main(){
   sqlite3 *db;
diff --git a/src/subu-put.cli.c b/src/subu-put.cli.c
new file mode 100644 (file)
index 0000000..f10007b
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+Set or get a new maximum subu number. Currently doesn't do the setting part.
+
+*/
+#include "subu-put.cli.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv){
+
+  if(argc != 4){
+    fprintf(stderr, "expected: %s masteru_name subuname subu_username\n", argv[0]);
+    return 1;
+  }
+  char *masteru_name = argv[1];
+  char *subuname = argv[2];
+  char *subu_username = argv[3];
+
+  sqlite3 *db;
+  {
+    int ret = sqlite3_open_v2(config_file, &db, SQLITE_OPEN_READWRITE, NULL);
+    if( ret != SQLITE_OK ){
+      fprintf(stderr, "error exit, could not open configuration file\n");
+      return ERR_CONFIG_FILE;
+    }}
+
+  int ret = subu_put_masteru_subu(db, masteru_name, subuname, subu_username);
+  if( ret != SQLITE_DONE ){
+    printf("put failed\n");
+    return 2;
+  }
+  if( sqlite3_close(db) != SQLITE_OK ){
+    fprintf(stderr, "error exit, strange, we could not close the configuration file\n");
+    return ERR_CONFIG_FILE;
+  }    
+  return 0;
+}