Blame tests/test_getpeercred.c

Packit 6bd9ab
/*
Packit 6bd9ab
   test_getpeercred.c - simple test for the peercred module
Packit 6bd9ab
   This file is part of the nss-pam-ldapd library.
Packit 6bd9ab
Packit 6bd9ab
   Copyright (C) 2008, 2011, 2012 Arthur de Jong
Packit 6bd9ab
Packit 6bd9ab
   This library is free software; you can redistribute it and/or
Packit 6bd9ab
   modify it under the terms of the GNU Lesser General Public
Packit 6bd9ab
   License as published by the Free Software Foundation; either
Packit 6bd9ab
   version 2.1 of the License, or (at your option) any later version.
Packit 6bd9ab
Packit 6bd9ab
   This library is distributed in the hope that it will be useful,
Packit 6bd9ab
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6bd9ab
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6bd9ab
   Lesser General Public License for more details.
Packit 6bd9ab
Packit 6bd9ab
   You should have received a copy of the GNU Lesser General Public
Packit 6bd9ab
   License along with this library; if not, write to the Free Software
Packit 6bd9ab
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit 6bd9ab
   02110-1301 USA
Packit 6bd9ab
*/
Packit 6bd9ab
Packit 6bd9ab
#include "config.h"
Packit 6bd9ab
Packit 6bd9ab
#include <stdio.h>
Packit 6bd9ab
#include <string.h>
Packit 6bd9ab
#include <assert.h>
Packit 6bd9ab
#include <unistd.h>
Packit 6bd9ab
#include <fcntl.h>
Packit 6bd9ab
#include <sys/types.h>
Packit 6bd9ab
#include <sys/socket.h>
Packit 6bd9ab
#include <sys/un.h>
Packit 6bd9ab
#ifdef HAVE_GRP_H
Packit 6bd9ab
#include <grp.h>
Packit 6bd9ab
#endif /* HAVE_GRP_H */
Packit 6bd9ab
#include <errno.h>
Packit 6bd9ab
Packit 6bd9ab
#include "common.h"
Packit 6bd9ab
Packit 6bd9ab
#include "compat/attrs.h"
Packit 6bd9ab
#include "compat/getpeercred.h"
Packit 6bd9ab
Packit 6bd9ab
/* create a named socket */
Packit 6bd9ab
static int create_socket(const char *name)
Packit 6bd9ab
{
Packit 6bd9ab
  int sock;
Packit 6bd9ab
  struct sockaddr_un addr;
Packit 6bd9ab
  /* create a socket */
Packit 6bd9ab
  assertok((sock = socket(PF_UNIX, SOCK_STREAM, 0)) >= 0);
Packit 6bd9ab
  /* remove existing named socket */
Packit 6bd9ab
  unlink(name);
Packit 6bd9ab
  /* create socket address structure */
Packit 6bd9ab
  memset(&addr, 0, sizeof(struct sockaddr_un));
Packit 6bd9ab
  addr.sun_family = AF_UNIX;
Packit 6bd9ab
  strncpy(addr.sun_path, name, sizeof(addr.sun_path));
Packit 6bd9ab
  addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
Packit 6bd9ab
  /* bind to the named socket */
Packit 6bd9ab
  assertok(bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == 0);
Packit 6bd9ab
  /* close the file descriptor on exit */
Packit 6bd9ab
  assertok(fcntl(sock, F_SETFD, FD_CLOEXEC) >= 0);
Packit 6bd9ab
  /* start listening for connections */
Packit 6bd9ab
  assertok(listen(sock, SOMAXCONN) >= 0);
Packit 6bd9ab
  /* we're done */
Packit 6bd9ab
  return sock;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* accept a connection on the socket */
Packit 6bd9ab
static int acceptconnection(int sock)
Packit 6bd9ab
{
Packit 6bd9ab
  int csock;
Packit 6bd9ab
  int j;
Packit 6bd9ab
  struct sockaddr_storage addr;
Packit 6bd9ab
  socklen_t alen;
Packit 6bd9ab
  /* accept a new connection */
Packit 6bd9ab
  alen = (socklen_t)sizeof(struct sockaddr_storage);
Packit 6bd9ab
  assertok((csock = accept(sock, (struct sockaddr *)&addr, &alen)) >= 0);
Packit 6bd9ab
  /* make sure O_NONBLOCK is not inherited */
Packit 6bd9ab
  assertok((j = fcntl(csock, F_GETFL, 0)) >= 0);
Packit 6bd9ab
  assertok(fcntl(csock, F_SETFL, j & ~O_NONBLOCK) >= 0);
Packit 6bd9ab
  /* return socket */
Packit 6bd9ab
  return csock;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* open a connection to the named socket */
Packit 6bd9ab
static int open_socket(const char *name)
Packit 6bd9ab
{
Packit 6bd9ab
  int sock;
Packit 6bd9ab
  struct sockaddr_un addr;
Packit 6bd9ab
  /* create a socket */
Packit 6bd9ab
  assertok((sock = socket(PF_UNIX, SOCK_STREAM, 0)) >= 0);
Packit 6bd9ab
  /* create socket address structure */
Packit 6bd9ab
  memset(&addr, 0, sizeof(struct sockaddr_un));
Packit 6bd9ab
  addr.sun_family = AF_UNIX;
Packit 6bd9ab
  strncpy(addr.sun_path, name, sizeof(addr.sun_path));
Packit 6bd9ab
  addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
Packit 6bd9ab
  /* connect to the socket */
Packit 6bd9ab
  assertok(connect(sock, (struct sockaddr *)&addr, (socklen_t)sizeof(struct sockaddr_un)) >= 0);
Packit 6bd9ab
  /* return the socket */
Packit 6bd9ab
  return sock;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
#define SOCKETNAME "/tmp/test_getpeercred.sock"
Packit 6bd9ab
Packit 6bd9ab
#define assertwarn(assertion)                                               \
Packit 6bd9ab
  if (!(assertion))                                                         \
Packit 6bd9ab
    fprintf(stderr, "test_getpeercred: %s:%d: %s: Assertion `%s' failed\n", \
Packit 6bd9ab
            __FILE__, __LINE__, __ASSERT_FUNCTION, __STRING(assertion));
Packit 6bd9ab
Packit 6bd9ab
/* the main program... */
Packit 6bd9ab
int main(int UNUSED(argc), char UNUSED(*argv[]))
Packit 6bd9ab
{
Packit 6bd9ab
  int ssock;
Packit 6bd9ab
  int csock;
Packit 6bd9ab
  int fsock;
Packit 6bd9ab
  uid_t uid;
Packit 6bd9ab
  gid_t gid;
Packit 6bd9ab
  pid_t pid;
Packit 6bd9ab
  /* create a socket to listen on */
Packit 6bd9ab
  ssock = create_socket(SOCKETNAME);
Packit 6bd9ab
  /* open a connection to the socket */
Packit 6bd9ab
  csock = open_socket(SOCKETNAME);
Packit 6bd9ab
  /* get a connection from the server socket */
Packit 6bd9ab
  fsock = acceptconnection(ssock);
Packit 6bd9ab
  /* look up client information */
Packit 6bd9ab
  assert(getpeercred(fsock, &uid, &gid, &pid) == 0);
Packit 6bd9ab
  assert(uid == geteuid());
Packit 6bd9ab
  assertwarn(gid == getegid());
Packit 6bd9ab
  assertwarn(pid == getpid());
Packit 6bd9ab
  /* remove the socket */
Packit 6bd9ab
  unlink(SOCKETNAME);
Packit 6bd9ab
  return 0;
Packit 6bd9ab
}