C Obtaining User Credentials through a unix domain socket.

Colleagues, tell me, please, how can I get the user's credentials through the unix domain socket correctly?

Most likely, I'm doing something wrong. I want to call a function
C:
getsockopt(sd, SOL_SOCKET, SO_PEERCRED, ........)
but I can't compile and run the code.

Is there anywhere I can see the code for FreeBSD, that get the user's credentials through the unix domain socket?

With thanks,
Ogogon.
 
look at

/usr/src/tools/regression/sockets/unix_cmsg/t_peercred.c
Code:
static int
t_peercred_client(int fd)
{
        struct xucred xucred;
        socklen_t len;

        if (uc_sync_recv() < 0)
                return (-1);

        if (uc_socket_connect(fd) < 0)
                return (-1);

        len = sizeof(xucred);
        if (getsockopt(fd, 0, LOCAL_PEERCRED, &xucred, &len) < 0) {
                uc_logmsg("getsockopt(LOCAL_PEERCRED)");
                return (-1);
        }

        if (check_xucred(&xucred, len) < 0)
                return (-1);

        return (0);
}
 
LOCAL_PEERCRED is for FreeBSD. And level must be 0 because SOL_SOCKET returns nothing. (Why?)

C:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/ucred.h>

#define S_PATH "/tmp/test_socket"

void error_if (int const cond, char const *const call)
{
    if (!cond)
        return;
    perror (call);
    exit (EXIT_FAILURE);
}

int main (int const argc, char const *const *const argv)
{
    int ss, cs;
    struct sockaddr_un sa;
    struct xucred cred;
    socklen_t cred_len;

    memset (&sa, 0, sizeof (sa));
    sa.sun_family = AF_UNIX;
    strncpy ( sa.sun_path, S_PATH, sizeof (sa.sun_path) - 1 );

    unlink (S_PATH);
    error_if ( (ss = socket (AF_UNIX, SOCK_STREAM, 0)) == -1, "socket" );
    error_if ( bind (ss, (void *) &sa, sizeof (sa) ), "bind" );
    error_if ( chmod (S_PATH, 0777), "chmod" );
    error_if ( listen (ss, 1), "listen" );
    printf ("Waiting for client\n");
    error_if ( (cs = accept (ss, NULL, NULL)) == -1, "accept" );

    memset (&cred, 0, sizeof (cred));
    cred_len = sizeof (cred);
    error_if ( getsockopt (cs, 0, LOCAL_PEERCRED, &cred, &cred_len),
         "getsockopt" );
    printf ("\nUID: %u\nPID: %u\n", cred.cr_uid, cred.cr_pid);

    return EXIT_SUCCESS;
}

Code:
$ cc -Wall -o cred cred.c
$ ./cred
Waiting for client

UID: 977
PID: 2926
 
Back
Top