From 7ef80af2dd4ff8ced14423d5bc7819b5b1eed16e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Gro=C3=9Fmann?= Date: Mon, 16 Mar 2026 21:40:40 +0100 Subject: [PATCH 1/2] feat: set UFS session owner on FTP login, log RC on fopen failure Call ufs_setuser() after successful FTP authentication so the UFSD session carries the FTP user identity for write permission checks on owner-restricted mount points. Log the UFSD return code in the ftpfopen error message to aid diagnosis of fopen failures. --- src/ftpdpass.c | 1 + src/ftpfopen.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ftpdpass.c b/src/ftpdpass.c index 7addab8..df364e2 100644 --- a/src/ftpdpass.c +++ b/src/ftpdpass.c @@ -42,6 +42,7 @@ ftpdpass(FTPC *ftpc) if (ftpc->ufs) { /* wtof("%s setting acee %08X", __func__, ftpc->acee); */ ufs_set_acee(ftpc->ufs, ftpc->acee); + ufs_setuser(ftpc->ufs, ftpc->cwd); /* try to change dir to user name */ /* wtof("%s ufs_chgdir(%s)", __func__, ftpc->cwd); */ if (ufs_chgdir(ftpc->ufs, ftpc->cwd)!=0) { diff --git a/src/ftpfopen.c b/src/ftpfopen.c index 6efc6fd..e0f9241 100644 --- a/src/ftpfopen.c +++ b/src/ftpfopen.c @@ -52,7 +52,8 @@ ftp_ufs_open(FTPC *ftpc, const char *fn, const char *fm, void **ret) ftpc->fflags = FTPC_FFLAG_UFS; /* fp is a UFS file */ } else { - wtof("ftpfopen: ufs_fopen(\"%s\",\"%s\") failed", fn, fm); + wtof("ftpfopen: ufs_fopen(\"%s\",\"%s\") failed rc=%d", + fn, fm, ufs_last_rc(ftpc->ufs)); } quit: From c051b9fb816bec02ec0f7458d319addc05d2b237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Gro=C3=9Fmann?= Date: Tue, 17 Mar 2026 13:13:37 +0100 Subject: [PATCH 2/2] feat: pass group to ufs_setuser, free UFS session on terminate - ftpdpass: extract ACEE group name and pass to ufs_setuser() - httpd: free server UFS session in terminate() before ufs_sys_term() - Update mbt submodule to latest - Add UFS/UFSD integration TODOs to doc/todos.md --- doc/todos.md | 26 ++++++++++++++++++++++++++ mbt | 2 +- src/ftpdpass.c | 5 ++++- src/httpd.c | 4 ++++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/doc/todos.md b/doc/todos.md index 509e4c5..c9b5a60 100644 --- a/doc/todos.md +++ b/doc/todos.md @@ -163,6 +163,32 @@ into the httpd distribution zip at `make dist` time. - [ ] Document FTP daemon configuration and capabilities - [ ] Document console commands (`/F HTTPD,...`) with examples +## UFS / UFSD Integration + +- [ ] **Replace `httpd->ufssys` with `int httpd->ufs_enabled`** + The UFSSYS handle from `ufs_sys_new()` is a stub — a `calloc` + + eyecatcher used purely as a boolean "UFS is available" flag. + Replace with a plain `int ufs_enabled` in the HTTPD struct and + change `ftpd->sys` to `int ftpd->ufs_enabled` accordingly. + All checks like `if (httpd->ufssys)` become `if (httpd->ufs_enabled)`. + Priority: none — purely cosmetic cleanup. + +- [ ] **Memory leak in `ufs_sys_term()`** + `ufs_sys_new()` allocates a UFSSYS via `calloc()`, but + `ufs_sys_term()` is a no-op and never frees it. Either + `ufs_sys_term()` should accept a `UFSSYS**` and free it, or + the caller (`terminate()` in httpd.c) should `free()` the handle + after `ufs_sys_term()`. Not critical at STC shutdown (address space + goes away), but should be fixed for correctness. + +- [ ] **Per-connection UFSD sessions instead of global session** + Currently HTTPD opens one server-level UFS session (`httpd->ufs`) + at startup, and each HTTP client gets its own session via `ufsnew()` + in `socket_thread()`. Evaluate whether per-connection sessions are + worth the overhead vs. sharing the server session with per-request + `ufs_setuser()` calls for identity switching. Consider implications + for concurrent access, permission checks, and session state (cwd). + ## Future Work - [ ] Hot-reload for CGI modules (currently requires STC restart) diff --git a/mbt b/mbt index a0475c1..920acc6 160000 --- a/mbt +++ b/mbt @@ -1 +1 @@ -Subproject commit a0475c188877e44e8bd6fe23026f6d3a3fe666f4 +Subproject commit 920acc6e5226938e05705aceceaaa1bfc5dd098b diff --git a/src/ftpdpass.c b/src/ftpdpass.c index df364e2..8b60d7a 100644 --- a/src/ftpdpass.c +++ b/src/ftpdpass.c @@ -40,9 +40,12 @@ ftpdpass(FTPC *ftpc) ftpc->flags = 0; if (ftpc->ufs) { + char group[9]; /* wtof("%s setting acee %08X", __func__, ftpc->acee); */ ufs_set_acee(ftpc->ufs, ftpc->acee); - ufs_setuser(ftpc->ufs, ftpc->cwd); + memcpyp(group, sizeof(group), + &acee->aceegrp[1], acee->aceegrp[0], 0); + ufs_setuser(ftpc->ufs, ftpc->cwd, group); /* try to change dir to user name */ /* wtof("%s ufs_chgdir(%s)", __func__, ftpc->cwd); */ if (ufs_chgdir(ftpc->ufs, ftpc->cwd)!=0) { diff --git a/src/httpd.c b/src/httpd.c index 2953ed6..ec9dffd 100644 --- a/src/httpd.c +++ b/src/httpd.c @@ -318,6 +318,10 @@ terminate(void) array_free(&httpd->httpcgi); } + if (httpd->ufs) { + ufsfree(&httpd->ufs); + } + if (httpd->ufssys) { wtof("HTTPD047I Terminating File System"); ufs_sys_term();