1*dcb0790bSMark Johnston /*- 2*dcb0790bSMark Johnston * Copyright (c) 2018 Christian S.J. Peron 3*dcb0790bSMark Johnston * All rights reserved. 4*dcb0790bSMark Johnston * 5*dcb0790bSMark Johnston * Redistribution and use in source and binary forms, with or without 6*dcb0790bSMark Johnston * modification, are permitted provided that the following conditions 7*dcb0790bSMark Johnston * are met: 8*dcb0790bSMark Johnston * 1. Redistributions of source code must retain the above copyright 9*dcb0790bSMark Johnston * notice, this list of conditions and the following disclaimer. 10*dcb0790bSMark Johnston * 2. Redistributions in binary form must reproduce the above copyright 11*dcb0790bSMark Johnston * notice, this list of conditions and the following disclaimer in the 12*dcb0790bSMark Johnston * documentation and/or other materials provided with the distribution. 13*dcb0790bSMark Johnston * 14*dcb0790bSMark Johnston * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*dcb0790bSMark Johnston * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*dcb0790bSMark Johnston * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*dcb0790bSMark Johnston * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*dcb0790bSMark Johnston * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*dcb0790bSMark Johnston * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*dcb0790bSMark Johnston * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*dcb0790bSMark Johnston * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*dcb0790bSMark Johnston * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*dcb0790bSMark Johnston * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*dcb0790bSMark Johnston * SUCH DAMAGE. 25*dcb0790bSMark Johnston */ 26*dcb0790bSMark Johnston #include <sys/types.h> 27*dcb0790bSMark Johnston #include <sys/socket.h> 28*dcb0790bSMark Johnston 29*dcb0790bSMark Johnston #include <bsm/audit.h> 30*dcb0790bSMark Johnston #include <bsm/libbsm.h> 31*dcb0790bSMark Johnston 32*dcb0790bSMark Johnston #include <netinet/in.h> 33*dcb0790bSMark Johnston 34*dcb0790bSMark Johnston #include <stdio.h> 35*dcb0790bSMark Johnston #include <pwd.h> 36*dcb0790bSMark Johnston #include <string.h> 37*dcb0790bSMark Johnston #include <unistd.h> 38*dcb0790bSMark Johnston #include <netdb.h> 39*dcb0790bSMark Johnston #include <stdlib.h> 40*dcb0790bSMark Johnston #include <err.h> 41*dcb0790bSMark Johnston 42*dcb0790bSMark Johnston static char *aflag; 43*dcb0790bSMark Johnston static char *mflag; 44*dcb0790bSMark Johnston static char *sflag; 45*dcb0790bSMark Johnston 46*dcb0790bSMark Johnston static void 47*dcb0790bSMark Johnston usage(char *prog) 48*dcb0790bSMark Johnston { 49*dcb0790bSMark Johnston 50*dcb0790bSMark Johnston (void) fprintf(stderr, 51*dcb0790bSMark Johnston "usage: %s [-46] [-a auid] [-m mask] [-s source] [-p port] command ...\n", 52*dcb0790bSMark Johnston prog); 53*dcb0790bSMark Johnston exit(1); 54*dcb0790bSMark Johnston } 55*dcb0790bSMark Johnston 56*dcb0790bSMark Johnston int 57*dcb0790bSMark Johnston main(int argc, char *argv []) 58*dcb0790bSMark Johnston { 59*dcb0790bSMark Johnston struct sockaddr_in6 *sin6; 60*dcb0790bSMark Johnston struct sockaddr_in *sin; 61*dcb0790bSMark Johnston struct addrinfo hints; 62*dcb0790bSMark Johnston auditinfo_addr_t aia; 63*dcb0790bSMark Johnston struct addrinfo *res; 64*dcb0790bSMark Johnston struct passwd *pwd; 65*dcb0790bSMark Johnston char *r, *prog; 66*dcb0790bSMark Johnston int ch, error; 67*dcb0790bSMark Johnston 68*dcb0790bSMark Johnston prog = argv[0]; 69*dcb0790bSMark Johnston bzero(&aia, sizeof(aia)); 70*dcb0790bSMark Johnston bzero(&hints, sizeof(hints)); 71*dcb0790bSMark Johnston aia.ai_termid.at_type = AU_IPv4; 72*dcb0790bSMark Johnston hints.ai_family = PF_UNSPEC; 73*dcb0790bSMark Johnston while ((ch = getopt(argc, argv, "46a:m:s:p:")) != -1) 74*dcb0790bSMark Johnston switch (ch) { 75*dcb0790bSMark Johnston case '4': 76*dcb0790bSMark Johnston hints.ai_family = PF_INET; 77*dcb0790bSMark Johnston break; 78*dcb0790bSMark Johnston case '6': 79*dcb0790bSMark Johnston hints.ai_family = PF_INET6; 80*dcb0790bSMark Johnston break; 81*dcb0790bSMark Johnston case 'a': 82*dcb0790bSMark Johnston aflag = optarg; 83*dcb0790bSMark Johnston break; 84*dcb0790bSMark Johnston case 'm': 85*dcb0790bSMark Johnston mflag = optarg; 86*dcb0790bSMark Johnston break; 87*dcb0790bSMark Johnston case 's': 88*dcb0790bSMark Johnston sflag = optarg; 89*dcb0790bSMark Johnston break; 90*dcb0790bSMark Johnston case 'p': 91*dcb0790bSMark Johnston aia.ai_termid.at_port = htons(atoi(optarg)); 92*dcb0790bSMark Johnston break; 93*dcb0790bSMark Johnston default: 94*dcb0790bSMark Johnston usage(prog); 95*dcb0790bSMark Johnston /* NOT REACHED */ 96*dcb0790bSMark Johnston } 97*dcb0790bSMark Johnston argc -= optind; 98*dcb0790bSMark Johnston argv += optind; 99*dcb0790bSMark Johnston if (argc == 0) 100*dcb0790bSMark Johnston usage(prog); 101*dcb0790bSMark Johnston if (aflag) { 102*dcb0790bSMark Johnston pwd = getpwnam(aflag); 103*dcb0790bSMark Johnston if (pwd == NULL) { 104*dcb0790bSMark Johnston aia.ai_auid = strtoul(aflag, &r, 10); 105*dcb0790bSMark Johnston if (r != NULL) 106*dcb0790bSMark Johnston errx(1, "%s: invalid user", aflag); 107*dcb0790bSMark Johnston } else 108*dcb0790bSMark Johnston aia.ai_auid = pwd->pw_uid; 109*dcb0790bSMark Johnston } 110*dcb0790bSMark Johnston if (mflag) { 111*dcb0790bSMark Johnston if (getauditflagsbin(mflag, &aia.ai_mask) < 0) 112*dcb0790bSMark Johnston err(1, "getauditflagsbin"); 113*dcb0790bSMark Johnston } 114*dcb0790bSMark Johnston if (sflag) { 115*dcb0790bSMark Johnston error = getaddrinfo(sflag, NULL, &hints, &res); 116*dcb0790bSMark Johnston if (error) 117*dcb0790bSMark Johnston errx(1, "%s", gai_strerror(error)); 118*dcb0790bSMark Johnston switch (res->ai_family) { 119*dcb0790bSMark Johnston case PF_INET6: 120*dcb0790bSMark Johnston sin6 = (struct sockaddr_in6 *) res->ai_addr; 121*dcb0790bSMark Johnston bcopy(&sin6->sin6_addr.s6_addr, 122*dcb0790bSMark Johnston &aia.ai_termid.at_addr[0], 123*dcb0790bSMark Johnston sizeof(struct in6_addr)); 124*dcb0790bSMark Johnston aia.ai_termid.at_type = AU_IPv6; 125*dcb0790bSMark Johnston break; 126*dcb0790bSMark Johnston case PF_INET: 127*dcb0790bSMark Johnston sin = (struct sockaddr_in *) res->ai_addr; 128*dcb0790bSMark Johnston bcopy(&sin->sin_addr.s_addr, 129*dcb0790bSMark Johnston &aia.ai_termid.at_addr[0], 130*dcb0790bSMark Johnston sizeof(struct in_addr)); 131*dcb0790bSMark Johnston aia.ai_termid.at_type = AU_IPv4; 132*dcb0790bSMark Johnston break; 133*dcb0790bSMark Johnston } 134*dcb0790bSMark Johnston } 135*dcb0790bSMark Johnston if (setaudit_addr(&aia, sizeof(aia)) < 0) { 136*dcb0790bSMark Johnston err(1, "setaudit_addr"); 137*dcb0790bSMark Johnston } 138*dcb0790bSMark Johnston (void) execvp(*argv, argv); 139*dcb0790bSMark Johnston err(1, "%s", *argv); 140*dcb0790bSMark Johnston } 141