From bb4a3722f25b589b91341ca554def4cfb0a3c0f1 Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Sun, 10 Dec 2023 19:06:56 +1100
Subject: [PATCH] force to use service/user directory for user frontend file

---
 src/include/66/service.h                  |  2 +-
 src/lib66/exec/ssexec_parse.c             |  5 ++-
 src/lib66/module/parse_module.c           |  8 ++--
 src/lib66/parse/parse_compute_list.c      |  5 ++-
 src/lib66/parse/parse_frontend.c          |  3 +-
 src/lib66/parse/parse_interdependences.c  |  6 +--
 src/lib66/sanitize/sanitize_system.c      |  2 +
 src/lib66/service/service_frontend_path.c | 55 +++++++++++++++++++----
 8 files changed, 66 insertions(+), 20 deletions(-)

diff --git a/src/include/66/service.h b/src/include/66/service.h
index fc9a57e7..2131469c 100644
--- a/src/include/66/service.h
+++ b/src/include/66/service.h
@@ -306,7 +306,7 @@ extern resolve_field_table_t resolve_service_field_table[] ;
 
 extern int service_cmp_basedir(char const *dir) ;
 extern int service_endof_dir(char const *dir, char const *name) ;
-extern int service_frontend_path(stralloc *sasrc,char const *sv, uid_t owner,char const *directory_forced, char const **exclude) ;
+extern int service_frontend_path(stralloc *sasrc,char const *sv, uid_t owner,char const *directory_forced, char const **exclude, uint8_t exlen) ;
 extern int service_frontend_src(stralloc *sasrc, char const *name, char const *src, char const **exclude) ;
 extern int service_is_g(char const *name, uint32_t flag) ;
 extern int service_get_treename(char *atree, char const *name, uint32_t flag) ;
diff --git a/src/lib66/exec/ssexec_parse.c b/src/lib66/exec/ssexec_parse.c
index 218a3ec1..316268e9 100644
--- a/src/lib66/exec/ssexec_parse.c
+++ b/src/lib66/exec/ssexec_parse.c
@@ -87,7 +87,8 @@ int ssexec_parse(int argc, char const *const *argv, ssexec_t *info)
         char bname[namelen + 1] ;
         char dname[namelen + 1] ;
         char const *directory_forced = 0 ;
-        char const *exclude[3] = { SS_MODULE_ACTIVATED + 1, SS_MODULE_FRONTEND + 1, 0 } ;
+        uint8_t exlen = 2 ;
+        char const *exclude[2] = { SS_MODULE_ACTIVATED + 1, SS_MODULE_FRONTEND + 1 } ;
 
         if (argv[0][0] == '/') {
 
@@ -105,7 +106,7 @@ int ssexec_parse(int argc, char const *const *argv, ssexec_t *info)
 
         name_isvalid(sv) ;
 
-        if (!service_frontend_path(&sa, sv, info->owner, directory_forced, exclude))
+        if (!service_frontend_path(&sa, sv, info->owner, directory_forced, exclude, exlen))
             log_dieu(LOG_EXIT_USER, "find service frontend file of: ", sv) ;
 
         /** need to check all the contents of the stralloc.
diff --git a/src/lib66/module/parse_module.c b/src/lib66/module/parse_module.c
index 394d81e4..9c5deade 100644
--- a/src/lib66/module/parse_module.c
+++ b/src/lib66/module/parse_module.c
@@ -54,7 +54,8 @@ static void parse_module_dependencies(stralloc *list, resolve_service_t *res, ui
     uint32_t *nfield = !requiredby ? &res->dependencies.ndepends : &res->dependencies.nrequiredby ;
     resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
     stralloc sa = STRALLOC_ZERO ;
-    char const *exclude[4] = { SS_MODULE_ACTIVATED + 1, SS_MODULE_FRONTEND + 1, SS_MODULE_CONFIG_DIR + 1, 0 } ;
+    uint8_t exlen = 3 ;
+    char const *exclude[3] = { SS_MODULE_ACTIVATED + 1, SS_MODULE_FRONTEND + 1, SS_MODULE_CONFIG_DIR + 1 } ;
 
     info->opt_tree = 0 ;
 
@@ -70,7 +71,7 @@ static void parse_module_dependencies(stralloc *list, resolve_service_t *res, ui
         if (!strcmp(name, fname))
             log_die(LOG_EXIT_SYS, "cyclic call detected -- ", name, " call ", fname) ;
 
-        if (!service_frontend_path(&sa, fname, info->owner, 0, exclude))
+        if (!service_frontend_path(&sa, fname, info->owner, 0, exclude, exlen))
             log_dieu(LOG_EXIT_USER, "find service frontend file of: ", fname) ;
 
         if (!stack_add_g(&stk, fname))
@@ -275,6 +276,7 @@ void parse_module(resolve_service_t *res, resolve_service_t *ares, unsigned int
 
             list.len = 0 ;
             char fname[strlen(l + pos)] ;
+            uint8_t exlen = 0 ; // see service_frontend_path file and compute_exclude()
             char const *exclude[1] = { 0 } ;
 
             if (!ob_basename(fname, l + pos))
@@ -286,7 +288,7 @@ void parse_module(resolve_service_t *res, resolve_service_t *ares, unsigned int
 
             /** Search first inside the module directory.
              * If not found, warn user about what to do.*/
-            if (!service_frontend_path(&list, fname, info->owner, copy, exclude)) {
+            if (!service_frontend_path(&list, fname, info->owner, copy, exclude, exlen)) {
 
                 copy[copylen] = 0 ;
                 char deps[copylen + SS_MODULE_ACTIVATED_LEN + SS_MODULE_DEPENDS_LEN + 1 + strlen(fname) + 1] ;
diff --git a/src/lib66/parse/parse_compute_list.c b/src/lib66/parse/parse_compute_list.c
index 58503278..29b0cada 100644
--- a/src/lib66/parse/parse_compute_list.c
+++ b/src/lib66/parse/parse_compute_list.c
@@ -39,7 +39,8 @@ int parse_compute_list(resolve_wrapper_t_ref wres, stralloc *sa, uint32_t *res,
     size_t len = sa->len, pos = 0 ;
     size_t nelement = sastr_nelement(sa) ;
     stralloc tmp = STRALLOC_ZERO ;
-    char const *exclude[3] = { SS_MODULE_ACTIVATED + 1, SS_MODULE_FRONTEND + 1, 0 } ;
+    uint8_t exlen = 2 ;
+    char const *exclude[2] = { SS_MODULE_ACTIVATED + 1, SS_MODULE_FRONTEND + 1 } ;
 
     char f[len + nelement + 2] ;
 
@@ -54,7 +55,7 @@ int parse_compute_list(resolve_wrapper_t_ref wres, stralloc *sa, uint32_t *res,
 
             tmp.len = 0 ;
 
-            r = service_frontend_path(&tmp, sa->s + pos, getuid(), 0, exclude) ;
+            r = service_frontend_path(&tmp, sa->s + pos, getuid(), 0, exclude, exlen) ;
             if (r == -1)
                 log_dieu(LOG_EXIT_SYS, "get frontend service file of: ", sa->s + pos) ;
 
diff --git a/src/lib66/parse/parse_frontend.c b/src/lib66/parse/parse_frontend.c
index d80056a9..02dc6ba5 100644
--- a/src/lib66/parse/parse_frontend.c
+++ b/src/lib66/parse/parse_frontend.c
@@ -45,6 +45,7 @@ static void parse_service_instance(stralloc *frontend, char const *svsrc, char c
     log_flow() ;
 
     stralloc sa = STRALLOC_ZERO ;
+    uint8_t exlen = 0 ; // see service_frontend_path file and compute_exclude()
     char const *exclude[1] = { 0 } ;
 
     if (!instance_splitname(&sa, sv, insta, SS_INSTANCE_TEMPLATE))
@@ -60,7 +61,7 @@ static void parse_service_instance(stralloc *frontend, char const *svsrc, char c
         /** in module the template service may not exist e.g.
          * module which call another module. In this case
          * follow the classic way */
-        int r = service_frontend_path(&sa, sv, getuid(), 0, exclude) ;
+        int r = service_frontend_path(&sa, sv, getuid(), 0, exclude, exlen) ;
         if (r < 1)
             log_dieu(LOG_EXIT_SYS, "get frontend service file of: ", sv) ;
 
diff --git a/src/lib66/parse/parse_interdependences.c b/src/lib66/parse/parse_interdependences.c
index 890642c7..5e70e87a 100644
--- a/src/lib66/parse/parse_interdependences.c
+++ b/src/lib66/parse/parse_interdependences.c
@@ -37,8 +37,8 @@ int parse_interdependences(char const *service, char const *list, unsigned int l
     int r, e = 0 ;
     size_t pos = 0, len = 0 ;
     stralloc sa = STRALLOC_ZERO ;
-
-    char const *exclude[4] = { SS_MODULE_ACTIVATED + 1, SS_MODULE_FRONTEND + 1, SS_MODULE_CONFIG_DIR, 0 } ;
+    uint8_t exlen = 3 ;
+    char const *exclude[3] = { SS_MODULE_ACTIVATED + 1, SS_MODULE_FRONTEND + 1, SS_MODULE_CONFIG_DIR } ;
 
     if (listlen) {
 
@@ -76,7 +76,7 @@ int parse_interdependences(char const *service, char const *list, unsigned int l
             if (!strcmp(main, name))
                 log_die(LOG_EXIT_USER, "direct cyclic interdependences detected -- ", main, " depends on: ", service, " which depends on: ", main) ;
 
-            r = service_frontend_path(&sa, name, getuid(), forced_directory, exclude) ;
+            r = service_frontend_path(&sa, name, getuid(), forced_directory, exclude, exlen) ;
             if (r < 1) {
                 log_warnu( "get frontend service file of: ", name) ;
                 goto freed ;
diff --git a/src/lib66/sanitize/sanitize_system.c b/src/lib66/sanitize/sanitize_system.c
index 13358301..686bc4b4 100644
--- a/src/lib66/sanitize/sanitize_system.c
+++ b/src/lib66/sanitize/sanitize_system.c
@@ -86,7 +86,9 @@ int sanitize_system(ssexec_t *info)
         }
 
         auto_check(SS_SERVICE_SYSDIR) ;
+        auto_check(SS_SERVICE_SYSDIR_USER) ;
         auto_check(SS_SERVICE_ADMDIR) ;
+        auto_check(SS_SERVICE_ADMDIR_USER) ;
         auto_check(SS_SERVICE_ADMCONFDIR) ;
         auto_check(SS_SCRIPT_SYSDIR) ;
         auto_check(SS_SEED_ADMDIR) ;
diff --git a/src/lib66/service/service_frontend_path.c b/src/lib66/service/service_frontend_path.c
index 9f7b18ce..944ee16b 100644
--- a/src/lib66/service/service_frontend_path.c
+++ b/src/lib66/service/service_frontend_path.c
@@ -12,6 +12,7 @@
  * except according to the terms contained in the LICENSE file./
  */
 
+#include <stdint.h>
 #include <sys/types.h>
 
 #include <oblibs/log.h>
@@ -24,13 +25,40 @@
 #include <66/constants.h>
 #include <66/service.h>
 
-int service_frontend_path(stralloc *sasrc, char const *sv, uid_t owner, char const *directory_forced, char const **exclude)
+static void compute_exclude(char const **nexclude, char const **oexclude, uint8_t exlen, uid_t owner)
+{
+    uint8_t pos = 0 ;
+
+    if (exlen) {
+        for (; pos < exlen ; pos++)
+            nexclude[pos] = oexclude[pos] ;
+
+        if (owner)
+            nexclude[pos] = 0 ;
+    } else
+        nexclude[0] = 0 ;
+
+    if (!owner) {
+        if (!exlen) {
+            nexclude[0] = "user" ;
+            nexclude[1] = 0 ;
+        } else {
+            nexclude[pos++] = "user" ;
+            nexclude[pos] = 0 ;
+        }
+    }
+}
+
+int service_frontend_path(stralloc *sasrc, char const *sv, uid_t owner, char const *directory_forced, char const **exclude, uint8_t exlen)
 {
     log_flow() ;
 
     int r, e = 0 ;
     char const *src = 0 ;
     char home[SS_MAX_PATH_LEN + 1 + strlen(SS_SERVICE_USERDIR) + 1] ;
+    char const *ex[exlen + 2] ;
+
+    compute_exclude(ex, exclude, exlen, owner) ;
 
     if (directory_forced) {
 
@@ -49,9 +77,9 @@ int service_frontend_path(stralloc *sasrc, char const *sv, uid_t owner, char con
 
     } else {
 
-        if (!owner)
+        if (!owner) {
             src = SS_SERVICE_ADMDIR ;
-        else {
+        } else {
 
             if (!set_ownerhome_stack(home))
                 log_dieusys(LOG_EXIT_SYS, "set home directory") ;
@@ -61,21 +89,32 @@ int service_frontend_path(stralloc *sasrc, char const *sv, uid_t owner, char con
             src = home ;
         }
 
-        r = service_frontend_src(sasrc, sv, src, exclude) ;
+        r = service_frontend_src(sasrc, sv, src, ex) ;
         if (r == -1)
             log_dieusys(LOG_EXIT_SYS, "parse source directory: ", src) ;
 
         if (!r) {
 
-            src = SS_SERVICE_ADMDIR ;
-            r = service_frontend_src(sasrc, sv, src, exclude) ;
+            if (!owner) {
+                goto next ;
+            } else {
+                src = SS_SERVICE_ADMDIR_USER ;
+            }
+
+            r = service_frontend_src(sasrc, sv, src, ex) ;
             if (r == -1)
                 log_dieusys(LOG_EXIT_SYS, "parse source directory: ", src) ;
 
+            next:
             if (!r) {
 
-                src = SS_SERVICE_SYSDIR ;
-                r = service_frontend_src(sasrc, sv, src, exclude) ;
+                if (!owner) {
+                    src = SS_SERVICE_SYSDIR ;
+                } else {
+                    src = SS_SERVICE_SYSDIR_USER ;
+                }
+
+                r = service_frontend_src(sasrc, sv, src, ex) ;
                 if (r == -1)
                     log_dieusys(LOG_EXIT_SYS, "parse source directory: ", src) ;
 
-- 
GitLab