Thread: getpwnam_r returns wrong uid.

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    17

    getpwnam_r returns wrong uid.

    I have a function I call runas which is used to switch a program to another user. It is having trouble because it needs to be thread safe and reentrant but the reentrant version of getpwnam "getpwnam_r" is giving me trouble. It returns a user id but it is always wrong and I am not sure why.

    I appreciate any help you can give me.

    Thank you.

    Code:
    int runas ( char *user )
    {
        uid_t uid = 0;
        if(user == NULL)
        {
            return EINVAL;
        }
        if(isdigit((int) *user))
        {
            uid = myatoi(user);
            if (uid < 0 || uid >= INT_MAX)
            {
            return ERANGE;
            }
        }
        else
        {
            struct passwd pwd,*result;
            char pwdbuffer[200];
            int pwdlinelen = 200;
            if((getpwnam_r(user,&pwd,pwdbuffer,pwdlinelen,&result)) != 0)
                {
                syslog(LOG_ERR,"Error with getpwnam_r(%s)",user);
                return EINVAL;
                }
            uid = pwd.pw_uid;
        fprintf(stderr,"uid=%i\n",uid);
        }
        if(uid == 0)
        {
            return EACCES;
        }
        if(setgroups ( 0,NULL ) == -1)
        {
            return errno;
        }
        if(setuid(uid) < 0 || seteuid(uid) < 0)
        {
            return errno;
        }
        return 0;
    }

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Usage looks correct to me. How do you know it's incorrect? What OS/system?

    gg

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Google'ing around shows that some implementations can return 0 but result may still be set to NULL to indicate "user not found". So you may want to add "&& result != 0" to your if.

    gg

  4. #4
    Registered User
    Join Date
    Oct 2008
    Posts
    17
    I know it is incorrect since the username I pass in is root which is only being used as the username for testing purposes, in production it would be switched to a non privileged user after binding to the correct ports. but the id I get back is for a user called arpwatch.

    When the program runs it switches to run as arpwatch, it should just switch from root to root but it is not doing that, it returns a seemingly random user id number to switch to.

    This is running on an ubuntu system. The output from uname -a is:
    Linux test 2.6.24-19-386 #1 Wed Aug 20 21:59:50 UTC 2008 i686 GNU/Linux

    Thanks for the help.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Well, just for fun -- check whether user and pwd.pw_name are the same. (Or perhaps even better, print them both out.)

  6. #6
    Registered User
    Join Date
    Oct 2008
    Posts
    17
    Thanks for all the suggestions. I just figured out the problem. It seems I introduced an error into the configuration file parser which caused the username being passed to be empty.

    Things seem to work now except it still hasn't solved my memory leak problem which I thought was due to reentrancy problems.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. recv() returns 0 the second time
    By Overlord in forum Networking/Device Communication
    Replies: 7
    Last Post: 07-10-2009, 04:09 AM
  2. custom doublylinkedlist class returns wrong data
    By r0flc0pter in forum C++ Programming
    Replies: 0
    Last Post: 06-13-2009, 05:18 AM
  3. recv returns with 0
    By napsy in forum Networking/Device Communication
    Replies: 12
    Last Post: 07-28-2008, 07:15 PM
  4. what I'm I doing wrong?
    By Unregistered in forum C Programming
    Replies: 6
    Last Post: 02-03-2002, 02:46 AM
  5. whats wrong with my code?
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 10-31-2001, 08:44 PM