The branch main has been updated by kevans:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=98edcbcce0a4650084bd86e704cfa38bf590250c

commit 98edcbcce0a4650084bd86e704cfa38bf590250c
Author:     Kyle Evans <[email protected]>
AuthorDate: 2025-10-29 02:37:21 +0000
Commit:     Kyle Evans <[email protected]>
CommitDate: 2025-10-29 02:37:21 +0000

    libutil: defer setting the MAC label until after the login class
    
    MAC policies, like mac_biba(4), may forbid changing the login class once
    a label has been applied.  For setting up the initial login context,
    this isn't really expected and in-fact may break some class-based
    configuration.
    
    Defer setting the MAC label until after the login class is set, and
    remove the requirement that we have a pwd entry since the label is
    pulled from the login class -- we only use pwd for syslog in this path.
    
    Patch is largely by Kevin Barry, with some modifications and this commit
    message by kevans@.
    
    PR:             177698
    Reviewed by:    des, olce
    MFC after:      3 days
    Co-authored-by: Kevin Barry <ta0kira gmail com>
    Differential Revision:  https://reviews.freebsd.org/D53362
---
 lib/libutil/login_class.c | 55 ++++++++++++++++++++++++++---------------------
 1 file changed, 30 insertions(+), 25 deletions(-)

diff --git a/lib/libutil/login_class.c b/lib/libutil/login_class.c
index c3c1b0ddda27..9478b4dc98ca 100644
--- a/lib/libutil/login_class.c
+++ b/lib/libutil/login_class.c
@@ -543,7 +543,7 @@ setusercontext(login_cap_t *lc, const struct passwd *pwd, 
uid_t uid, unsigned in
 
     /* we need a passwd entry to set these */
     if (pwd == NULL)
-       flags &= ~(LOGIN_SETGROUP | LOGIN_SETLOGIN | LOGIN_SETMAC);
+       flags &= ~(LOGIN_SETGROUP | LOGIN_SETLOGIN);
 
     /* Set the process priority */
     if (flags & LOGIN_SETPRIORITY)
@@ -564,6 +564,27 @@ setusercontext(login_cap_t *lc, const struct passwd *pwd, 
uid_t uid, unsigned in
        }
     }
 
+    /* Set the sessions login */
+    if ((flags & LOGIN_SETLOGIN) && setlogin(pwd->pw_name) != 0) {
+       syslog(LOG_ERR, "setlogin(%s): %m", pwd->pw_name);
+       login_close(llc);
+       return (-1);
+    }
+
+    /* Inform the kernel about current login class */
+    if (lc != NULL && lc->lc_class != NULL && (flags & LOGIN_SETLOGINCLASS)) {
+       error = setloginclass(lc->lc_class);
+       if (error != 0) {
+           syslog(LOG_ERR, "setloginclass(%s): %m", lc->lc_class);
+#ifdef notyet
+           login_close(llc);
+           return (-1);
+#endif
+       }
+    }
+
+    setlogincontext(lc, pwd, flags);
+
     /* Set up the user's MAC label. */
     if ((flags & LOGIN_SETMAC) && mac_is_present(NULL) == 1) {
        const char *label_string;
@@ -572,8 +593,10 @@ setusercontext(login_cap_t *lc, const struct passwd *pwd, 
uid_t uid, unsigned in
        label_string = login_getcapstr(lc, "label", NULL, NULL);
        if (label_string != NULL) {
            if (mac_from_text(&label, label_string) == -1) {
-               syslog(LOG_ERR, "mac_from_text('%s') for %s: %m",
-                   pwd->pw_name, label_string);
+               syslog(LOG_ERR, "mac_from_text('%s') for %s %s: %m",
+                   label_string, pwd != NULL ? "user" : "class",
+                   pwd != NULL ? pwd->pw_name : lc->lc_class);
+               login_close(llc);
                return (-1);
            }
            if (mac_set_proc(label) == -1)
@@ -582,33 +605,15 @@ setusercontext(login_cap_t *lc, const struct passwd *pwd, 
uid_t uid, unsigned in
                error = 0;
            mac_free(label);
            if (error != 0) {
-               syslog(LOG_ERR, "mac_set_proc('%s') for %s: %s",
-                   label_string, pwd->pw_name, strerror(error));
+               syslog(LOG_ERR, "mac_set_proc('%s') for %s %s: %s",
+                   label_string, pwd != NULL ? "user" : "class",
+                   pwd != NULL ? pwd->pw_name : lc->lc_class, strerror(error));
+               login_close(llc);
                return (-1);
            }
        }
     }
 
-    /* Set the sessions login */
-    if ((flags & LOGIN_SETLOGIN) && setlogin(pwd->pw_name) != 0) {
-       syslog(LOG_ERR, "setlogin(%s): %m", pwd->pw_name);
-       login_close(llc);
-       return (-1);
-    }
-
-    /* Inform the kernel about current login class */
-    if (lc != NULL && lc->lc_class != NULL && (flags & LOGIN_SETLOGINCLASS)) {
-       error = setloginclass(lc->lc_class);
-       if (error != 0) {
-           syslog(LOG_ERR, "setloginclass(%s): %m", lc->lc_class);
-#ifdef notyet
-           login_close(llc);
-           return (-1);
-#endif
-       }
-    }
-
-    setlogincontext(lc, pwd, flags);
     login_close(llc);
 
     /* This needs to be done after anything that needs root privs */

Reply via email to