The branch stable/13 has been updated by rmacklem:

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

commit afb6f83074944e3843bb171656af9f52ac9d4d98
Author:     Rick Macklem <rmack...@freebsd.org>
AuthorDate: 2021-11-18 21:35:25 +0000
Commit:     Rick Macklem <rmack...@freebsd.org>
CommitDate: 2021-12-02 01:08:35 +0000

    mountd: Fix handling of usernames that start with a digit
    
    yocalebo_gmail.com submitted a patch for mountd.c that
    fixes the case where a username starts with a digit.
    Without this patch, the username that starts with a
    digit is misinterpreted as a numeric uid.
    With this patch, any string that does not entirely
    convert to a decimal number via strtoul() is considered
    a user/group name.
    
    (cherry picked from commit f4bf849bb894f4934b8df6c04a820dfa52e9576c)
---
 usr.sbin/mountd/mountd.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c
index c66ac13b3016..0c077b857d7e 100644
--- a/usr.sbin/mountd/mountd.c
+++ b/usr.sbin/mountd/mountd.c
@@ -3534,6 +3534,8 @@ parsecred(char *namelist, struct expcred *cr)
        struct group *gr;
        gid_t groups[NGROUPS_MAX + 1];
        int ngroups;
+       unsigned long name_ul;
+       char *end = NULL;
 
        /*
         * Set up the unprivileged user.
@@ -3548,10 +3550,11 @@ parsecred(char *namelist, struct expcred *cr)
        names = namelist;
        name = strsep_quote(&names, ":");
        /* Bug?  name could be NULL here */
-       if (isdigit(*name) || *name == '-')
-               pw = getpwuid(atoi(name));
-       else
+       name_ul = strtoul(name, &end, 10);
+       if (*end != '\0' || end == name)
                pw = getpwnam(name);
+       else
+               pw = getpwuid((uid_t)name_ul);
        /*
         * Credentials specified as those of a user.
         */
@@ -3573,8 +3576,9 @@ parsecred(char *namelist, struct expcred *cr)
                if (ngroups > 1 && groups[0] == groups[1]) {
                        ngroups--;
                        inpos = 2;
-               } else
+               } else {
                        inpos = 1;
+               }
                if (ngroups > NGROUPS_MAX)
                        ngroups = NGROUPS_MAX;
                if (ngroups > SMALLNGROUPS)
@@ -3589,25 +3593,26 @@ parsecred(char *namelist, struct expcred *cr)
         * Explicit credential specified as a colon separated list:
         *      uid:gid:gid:...
         */
-       if (pw != NULL)
+       if (pw != NULL) {
                cr->cr_uid = pw->pw_uid;
-       else if (isdigit(*name) || *name == '-')
-               cr->cr_uid = atoi(name);
-       else {
+       } else if (*end != '\0' || end == name) {
                syslog(LOG_ERR, "unknown user: %s", name);
                return;
+       } else {
+               cr->cr_uid = name_ul;
        }
        cr->cr_ngroups = 0;
        while (names != NULL && *names != '\0' && cr->cr_ngroups < NGROUPS_MAX) 
{
                name = strsep_quote(&names, ":");
-               if (isdigit(*name) || *name == '-') {
-                       groups[cr->cr_ngroups++] = atoi(name);
-               } else {
+               name_ul = strtoul(name, &end, 10);
+               if (*end != '\0' || end == name) {
                        if ((gr = getgrnam(name)) == NULL) {
                                syslog(LOG_ERR, "unknown group: %s", name);
                                continue;
                        }
                        groups[cr->cr_ngroups++] = gr->gr_gid;
+               } else {
+                       groups[cr->cr_ngroups++] = name_ul;
                }
        }
        if (names != NULL && *names != '\0' && cr->cr_ngroups == NGROUPS_MAX)

Reply via email to