views:

211

answers:

3

I've done some research and I'm still struggling with the passwd structure.

http://www.opengroup.org/onlinepubs/000095399/basedefs/pwd.h.html

I need to obtain the user ID however I dont think I'm using understanding it at all.

int getpwuid_r(uid_t, struct passwd *, char *, size_t, struct passwd **);

This method call returns a point to a structure that will contain all the data I need. I'm fairly confused on the parameters.

struct passwd. Do I need to declare this first? struct passwd passwd?

I'm just totally lost on how to use this.

Lastly, once I fill my pointer. What calls will I use to get the data? Thanks for any help.

+1  A: 

In the getpwuid_r signature:

int getpwuid_r(uid_t uid, struct passwd *pwbuf, char *buf, 
    size_t buflen, struct passwd **pwbufp);

uid is an input parameter - it is the UID of the user that you want to look up. The rest are essentially output parameters: the structure pointed to by pwbuf will be filled with the password information, and the pointer pointed to by pwbufp will be set to the value of pwbuf if the call was successful (and NULL if it was not). The buf and buflen pair of parameters specify a user-supplied buffer that will be used to store the strings pointed to by members of the struct passwd structure that is returned.

You would use it like so (this looks up the user with UID 101):

    struct passwd pwent;
    struct passwd *pwentp;
    char buf[1024];

    if (getpwuid_r(101, &pwent, buf, sizeof buf, &pwentp))
    {
            perror("getpwuid_r");
    }
    else
    {
            printf("Username: %s\n", pwent.pw_name);
            printf("Real Name: %s\n", pwent.pw_gecos);
            printf("Home Directory: %s\n", pwent.pw_dir);
    }

If instread you want to look up a user by name to find their ID, use getpwnam_r and examine the pw_uid field of the returned struct.

caf
Nice, I used getpwuid, and you used getpwuid_r. Hopefully the answer the OP's looking for is one of these!
Jefromi
+1  A: 

Okay, first of all, I'm not too sure what you're trying to accomplish - you said you need to obtain the uid, but getpwuid is for looking up other information based on uid. Did you maybe want getpwnam, which looks up based on username? And then you need to use the uid for another function?

In any case, everything I say below applies to both getpwnam and getpwuid - just swap out the uid argument for the username argument.

You've mixed up your documentation a little bit. An almost-quote from the man page:

struct passwd *getpwuid(uid_t uid);

int getpwuid_r(uid_t uid, struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp);

The getpwuid() function returns a pointer to a structure containing the broken-out fields of the record in the password database that matches the user ID uid.

The getpwuid_r() function obtains the same information, but stores the retrieved passwd structure in the space pointed to by pwbuf.

It sounds like you're simply a bit fuzzy on pointers in general. However, you don't have to worry too much for this job it sounds like for your purposes the simpler version might be fine:

struct passwd * my_passwd;
my_passwd = getpwuid(uid);
// or:
// my_passwd = getpwnam(username);

if (my_passwd == NULL) {
    // the lookup failed - handle the error!
} else {
    // the lookup succeeded - do your thing 
    printf("User name: %s\n", my_passwd->pw_name);
    printf("User password: %s\n", my_passwd->pw_passwd);
    ...
}

Note that in this case you don't need to allocate memory for the pointer, because getpwuid returns a pointer to the structure with the memory allocated and information stored.

The full definition of the structure (names of other members) is in the man page.

The second form, getpwuid_r, is better for more careful error-handling and memory management, but if all you need to do is a quick lookup, this should be fine.

Jefromi
I appreciate all of the help everyone has offered. I should be ok now. Someone explained it to me differently and I originally was on the correct path to begin with.In case you were wondering I have a unix programming project that needs to display all the user permission for all the files in his directory.
Bryan Harrington
+1  A: 

Firstly, if you want to get the UID, then presumably you have the username at hand, in which case you should be using getpwnam_r() instead. This function is used exactly like getpwuid_r(), except that you pass it a name (char *) as a first parameter.

Secondly, you do not need to declare `struct passwd'. It is declared when you include pwd.h.

Thirdly, the function's exact signature is:

int getpwnam_r(const char *name, struct passwd *pwd,
               char *buf, size_t buflen, struct passwd **result);

In the above, pwd is an output parameter. That is where the function returns your password entry, if it is found.

Lastly, there is a full example of how to use getpwnam_r in the Linux getpwnam_r manpage, accessible here.

[1]: http://manpages.ubuntu.com/manpages/jaunty/en/man3/getpwnam.3.html here

Brian G. Marete