From: Thomas Walker Lynch Date: Tue, 12 Mar 2019 22:25:55 +0000 (+0100) Subject: checkpoint adds get_subu_info X-Git-Url: https://git.reasoningtechnology.com/style/rt_dark_doc.css?a=commitdiff_plain;h=29d20cbe9a5f27b3915939b371cb1485e492aa8f;p=subu checkpoint adds get_subu_info --- diff --git a/src/2_bin/subudb b/src/2_bin/subudb deleted file mode 100644 index 23c3c44..0000000 Binary files a/src/2_bin/subudb and /dev/null differ diff --git a/src/subu.lib.c b/src/subu.lib.c index a9bc330..9712f42 100644 --- a/src/subu.lib.c +++ b/src/subu.lib.c @@ -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 diff --git a/src/subudb-rel-get.cli.c b/src/subudb-rel-get.cli.c index 442d61e..9828b15 100644 --- a/src/subudb-rel-get.cli.c +++ b/src/subudb-rel-get.cli.c @@ -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; } diff --git a/src/subudb.lib.c b/src/subudb.lib.c index 99ec7f0..e4e492a 100644 --- a/src/subudb.lib.c +++ b/src/subudb.lib.c @@ -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;";