checkpoint adds get_subu_info
authorThomas Walker Lynch <thomas.lynch@reasoningtechnology.com>
Tue, 12 Mar 2019 22:25:55 +0000 (23:25 +0100)
committerThomas Walker Lynch <thomas.lynch@reasoningtechnology.com>
Tue, 12 Mar 2019 22:25:55 +0000 (23:25 +0100)
src/2_bin/subudb [deleted file]
src/subu.lib.c
src/subudb-rel-get.cli.c
src/subudb.lib.c

diff --git a/src/2_bin/subudb b/src/2_bin/subudb
deleted file mode 100644 (file)
index 23c3c44..0000000
Binary files a/src/2_bin/subudb and /dev/null differ
index a9bc330..9712f42 100644 (file)
@@ -481,7 +481,7 @@ int subu_rm_0(char **mess, sqlite3 *db, char *subuname){
   db_begin(db);
 
   char *subu_username = 0;
-  rc = subudb_Masteru_Subu_get(db, masteru_name, subuname, &subu_username);
+  rc = subudb_Masteru_Subu_get_subu_username(db, masteru_name, subuname, &subu_username);
   if( rc != SQLITE_OK ){
     if(mess) *mess = strdup("subu requested for removal not found under this masteru in db file");
     rc = SUBU_ERR_SUBU_NOT_FOUND;
@@ -578,3 +578,178 @@ int subu_rm_0(char **mess, sqlite3 *db, char *subuname){
   RETURN(0);
 }
 
+#if 0
+//================================================================================
+// identifies masteru, the bindfs maps each subu_user's home to its mount point
+// in subuland.
+int subu_bind(char **mess, char *subu_user_home, char *subuhome){
+    char *command = "/usr/bin/bindfs";
+    char *argv[3];
+    argv[0] = command;
+    argv[1] = subu_username;
+    argv[2] = (char *) NULL;
+    char *envp[1];
+    envp[0] = (char *) NULL;
+    int dispatch_err = dispatch_exec(argv, envp);
+    if( dispatch_err != 0 ){
+      #ifdef DEBUG 
+      dispatch_f_mess("dispatch_exec", dispatch_err, command);
+      #endif
+      if(mess)*mess = userdel_mess(dispatch_err);
+      RETURN(SUBU_ERR_FAILED_USERDEL);
+    }
+    #ifdef DEBUG
+    dbprintf("deleted user \"%s\"\n", subu_username);
+    #endif
+}
+int subu_bind_all(char **mess, sqlite3 *db, char *subuname){
+
+  int rc;
+  if(mess)*mess = 0;
+
+  //--------------------------------------------------------------------------------
+  size_t subuname_len;
+  rc = allowed_subuname(mess, subuname, &subuname_len);
+  if(rc) return rc;
+  #ifdef DEBUG
+  dbprintf("subuname is well formed\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 ) return SUBU_ERR_SETUID_ROOT;
+  }
+
+  //--------------------------------------------------------------------------------
+  // various strings that we will need
+  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
+  rc =
+    mk_masteru_name(masteru_uid, &masteru_name, &masteru_home)
+    ||
+    mk_subuland(masteru_home, &subuland)
+    ||
+    mk_subuhome(subuland, subuname, &subuhome)
+    ;
+  if(rc) RETURN(rc);
+  #ifdef DEBUG
+  dbprintf("masteru_home, subuhome: \"%s\", \"%s\"\n", masteru_home, subuhome);
+  #endif
+
+  //--------------------------------------------------------------------------------
+  // removal from db
+
+  db_begin(db);
+
+  char *subu_username = 0;
+  rc = subudb_Masteru_Subu_get_subu_username(db, masteru_name, subuname, &subu_username);
+  if( rc != SQLITE_OK ){
+    if(mess) *mess = strdup("subu requested for removal not found under this masteru in db file");
+    rc = SUBU_ERR_SUBU_NOT_FOUND;
+    db_rollback();
+    RETURN(rc);
+  }
+  #ifdef DEBUG
+  printf("subu_username: \"%s\"\n", subu_username);  
+  #endif
+
+  rc = subudb_Masteru_Subu_rm(db, masteru_name, subuname, subu_username);
+  if( rc != SQLITE_OK ){
+    if(mess)*mess = strdup("removal of masteru subu relation failed");
+    db_rollback();
+    RETURN(SUBU_ERR_DB_FILE);
+  }
+  #ifdef DEBUG
+  dbprintf("removed the masteru_name, subuname, subu_username relation\n");
+  #endif
+  
+  rc = db_commit(db);
+  if( rc != SQLITE_OK ){
+    if(mess)*mess = strdup("removal of masteru subu relation in unknown state, exiting");
+    RETURN(SUBU_ERR_DB_FILE);
+  }
+  
+  // even after removing the last masteru subu relation, we still do not remove
+  // the max subu count. Hence, a masteru will keep such for a life time.
+
+
+  //--------------------------------------------------------------------------------
+  // Only masteru can remove directories from masteru/subuland, so we switch to 
+  // masteru's uid to perform the rmdir.
+  //
+  {
+    #ifdef DEBUG
+    dbprintf("as masteru, removing the directory \"%s\"\n", subuhome);
+    #endif
+    int dispatch_err = dispatch_f_euid_egid
+      (
+       "masteru_rmdir_subuhome", 
+       masteru_rmdir_subuhome, 
+       (void *)subuhome,
+       masteru_uid, 
+       masteru_gid
+       );
+    if( dispatch_err <= ERR_DISPATCH || dispatch_err == SUBU_ERR_RMDIR_SUBUHOME ){
+      #ifdef DEBUG
+      dispatch_f_mess("dispatch_f_euid_egid", dispatch_err, "masteru_rmdir_subuhome");
+      #endif
+      if(mess)*mess = strdup(subuhome);
+      RETURN(SUBU_ERR_RMDIR_SUBUHOME);
+    }
+  }
+
+  //--------------------------------------------------------------------------------
+  //  Delete the subservient user account
+  {
+    #ifdef DEBUG
+    dbprintf("deleting user \"%s\"\n", 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 ){
+        rc = SUBU_ERR_BUG_SSS;
+        RETURN(rc);
+      }
+    #endif
+    char *command = "/usr/sbin/userdel";
+    char *argv[3];
+    argv[0] = command;
+    argv[1] = subu_username;
+    argv[2] = (char *) NULL;
+    char *envp[1];
+    envp[0] = (char *) NULL;
+    int dispatch_err = dispatch_exec(argv, envp);
+    if( dispatch_err != 0 ){
+      #ifdef DEBUG 
+      dispatch_f_mess("dispatch_exec", dispatch_err, command);
+      #endif
+      if(mess)*mess = userdel_mess(dispatch_err);
+      RETURN(SUBU_ERR_FAILED_USERDEL);
+    }
+    #ifdef DEBUG
+    dbprintf("deleted user \"%s\"\n", subu_username);
+    #endif
+  }  
+
+  #ifdef DEBUG
+  dbprintf("finished subu-rm-0(%s)\n", subuname);
+  #endif
+  RETURN(0);
+}
+
+#endif
index 442d61e..9828b15 100644 (file)
@@ -1,6 +1,6 @@
 /*
 get the username from the db file
-for testing subudb_Masteru_Subu_get_user
+for testing subudb_Masteru_Subu_get_subu_username
 
 */
 #include "subudb-rel-get.cli.h"
@@ -26,9 +26,9 @@ int main(int argc, char **argv){
   char *subuname = argv[2];
   char *subu_username;
 
-  int ret = subudb_Masteru_Subu_get(db, masteru_name, subuname, &subu_username);
+  int ret = subudb_Masteru_Subu_get_subu_username(db, masteru_name, subuname, &subu_username);
   if( ret != SQLITE_DONE ){
-    fprintf(stderr, "subudb_Masteru_Subu_get indicates failure by returning %d\n",ret);
+    fprintf(stderr, "subudb_Masteru_Subu_get_subu_username indicates failure by returning %d\n",ret);
     fprintf(stderr, "sqlite3 issues message, %s\n", sqlite3_errmsg(db));
     return SUBU_ERR_DB_FILE;
   }
index 99ec7f0..e4e492a 100644 (file)
@@ -118,7 +118,7 @@ int subudb_Masteru_Subu_put(sqlite3 *db, char *masteru_name, char *subuname, cha
 }
 
 //--------------------------------------------------------------------------------
-int subudb_Masteru_Subu_get(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){
   char *sql = "SELECT subu_username FROM Masteru_Subu WHERE masteru_name = ?1 AND subuname = ?2;";
   size_t sql_len = strlen(sql);
   sqlite3_stmt *stmt;
@@ -140,6 +140,81 @@ int subudb_Masteru_Subu_get(sqlite3 *db, char *masteru_name, char *subuname, cha
   return rc;
 }
 
+//--------------------------------------------------------------------------------
+
+// generic array expander
+static void 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;
+}
+static bool off_alloc(void *base, void *pt, size_t s){
+  return pt == base + s;
+}
+
+// we return and array of subudb_subu_info
+struct subudb_subu_info{
+  char *subuname;
+  char *subu_username;
+};
+static void subu_info_alloc(subudb_subu_info **base, size_t *s){
+  *s = 4 * sizeof(subudb_subu_info);
+  *base = malloc(s)
+}
+static void subu_info_free(subudb_subu_info *base, subu_db_subu_info *end_pt){
+  subudb_subu_info *pt = base;
+  while( pt != end_pt ){
+    pt->free(subuname);
+    pt->free(subu_username);
+  pt++;
+  }
+  free(base);  
+}
+
+int subudb_Masteru_Subu_get_subu_info
+(
+ sqlite3 *db,
+ char *masteru_name,
+ subudb_subu_info **si,
+ subudb_subu_info **si_end
+){
+  char *sql = "SELECT subuname, subu_username"
+              "FROM Masteru_Subu"
+              "WHERE masteru_name = ?1;";
+  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);
+
+  size_t subu_info_size;
+  subudb_subu_info *subu_info;
+  subu_info_alloc(&subu_info, &subu_info_size);
+  subudb_subu_info *pt = subu_info;
+  rc = sqlite3_step(stmt);
+  while( rc == SQLITE_ROW ){
+    if( off_alloc(subu_info, pt) ) expand(&subu_info, &pt, &subu_info_size);
+    pt->subuname = strdup(sqlite3_column_text(stmt, 0));
+    pt->subu_username = strdup(sqlite3_column_text(stmt, 1));
+  rc = sqlite3_step(stmt);
+  pt++;
+  }
+  sqlite3_finalize(stmt);
+  if( rc != SQLITE_DONE ){
+    return rc; // woops this needs to return an error!,  be sure it is not SQLITE_DONE
+  }
+  *si = subu_info;
+  *si_end = pt;
+  return SQLTIE_OK;
+}
+
+
 //--------------------------------------------------------------------------------
 int subudb_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;";