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