[BusyBox] can't add root user: passwd: unknown uid 0

Chris Kottaridis chriskot at quietwind.net
Fri Jul 29 07:36:57 UTC 2005


I am kind of new to busybox, but a quick perusal of the source I have
the following comments on the subject.

> The code snippet that's barfing is this, from loginutils/passwd.c:
> 
>    pw = getpwnam(name);
>     if (!pw) {
>         bb_error_msg_and_die("Unknown user %s\n", name);
>     }
>     if (!amroot && pw->pw_uid != getuid()) {
>         syslog(LOG_WARNING, "can't change pwd for `%s'", name);
>         bb_error_msg_and_die("Permission denied.\n");
>     }

I think the eror message says:

> #   adduser -h /root root
> passwd: unknown uid 0

I think that it is my_getug() that is where the failure is:

/* internal function for my_getpwuid and my_getgrgid */
char * my_getug(char *buffer, char *idname, long id, int bufsize, char
prefix)
{
    if(bufsize > 0 ) {
        assert(buffer!=NULL);
        if(idname) {
            return safe_strncpy(buffer, idname, bufsize);
        }
        snprintf(buffer, bufsize, "%ld", id);
    } else if(bufsize < 0 && !idname) {
        bb_error_msg_and_die("unknown %cid %ld", prefix, id);
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    }
    return idname;
}

It is getting called by my_getpwuid() here:

/* gets a username given a uid */
char * my_getpwuid(char *name, long uid, int bufsize)
{
    struct passwd *myuser = getpwuid(uid);

    return  my_getug(name, (myuser) ? myuser->pw_name : (char *)myuser ,
uid, bufsize, 'u');
}

Where getpwuid is failing with uid of zero. So, idname is zero since
there is no user with uid of zero. and bufsize is being passed with a -1
from passwd_main() here:

    myname = (char *) bb_xstrdup(my_getpwuid(NULL, getuid(), -1));

This all makes perfect sense, that there is no root entry with uid of
zero because adduser restricts it's uids to the minimum below:


static int passwd_study(const char *filename, struct passwd *p)
{
    struct passwd *pw;
    FILE *passwd;

    const int min = 500;
    const int max = 65000;

    passwd = bb_wfopen(filename, "r");
    if (!passwd)
        return 4;

    /* EDR if uid is out of bounds, set to min */
    if ((p->pw_uid > max) || (p->pw_uid < min))
        p->pw_uid = min;


So, the moral of the story is that it is wrong to expect adduser to
create a root user and since you are running as root already my_getpwuid
is doomed to failure. Because things are setup fully expecting that
whatever uid you are running as having a valid passwd entry or at least
one for root.

I'd expect that if you check the passwd file there is a root entry with
uid of 500, but that's a guess. Personally, I'd be curious if a standard
Linux commands didn't have a similar problem. A totally empty passwd
file may not be expected in the code. In partricualr no uid of zero
entry could screw up a lot of things using getpw* routines.

Anyway, sysadmin of "special" uid values is not handled by adduser, it
seems that's not what it's for.

I'd do a little more work on this, but I am off on vacation for a week
and won;t be near a computer.
-- 
Chris Kottaridis <chriskot at quietwind.net>



More information about the busybox mailing list