Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27 
     28 #include <sys/socket.h>
     29 #include <netinet/in.h>
     30 #include <strings.h>
     31 #include <sys/socket.h>
     32 
     33 #include <bsm/audit.h>
     34 #include <bsm/libbsm.h>
     35 #include <bsm/audit_private.h>
     36 #include <generic.h>
     37 
     38 static int do_ipv6_address(struct sockaddr_in6 *, struct sockaddr_in6 *);
     39 static int do_ipv4_address(struct sockaddr_in *, struct sockaddr_in *);
     40 
     41 int
     42 audit_settid(int fd)
     43 {
     44 	struct sockaddr_in6 peer;
     45 	struct sockaddr_in6 sock;
     46 	int peerlen = sizeof (peer);
     47 	int socklen = sizeof (sock);
     48 	int rv;
     49 
     50 	if (cannot_audit(0)) {
     51 		return (0);
     52 	}
     53 
     54 	/* get peer name */
     55 	if (getpeername(fd, (struct sockaddr *)&peer, (socklen_t *)&peerlen)
     56 		< 0) {
     57 		return (1);
     58 	}
     59 
     60 	/* get sock name */
     61 	if (getsockname(fd, (struct sockaddr *)&sock, (socklen_t *)&socklen)
     62 		< 0) {
     63 		return (1);
     64 	}
     65 
     66 	if (peer.sin6_family == AF_INET6)
     67 		rv = do_ipv6_address(&peer, &sock);
     68 	else
     69 		rv = do_ipv4_address((struct sockaddr_in *)&peer,
     70 			(struct sockaddr_in *)&sock);
     71 
     72 	return (rv);
     73 }
     74 
     75 static int
     76 do_ipv6_address(struct sockaddr_in6 *peer, struct sockaddr_in6 *sock)
     77 {
     78 	auditinfo_addr_t ai;
     79 
     80 	/* get audit characteristics of process */
     81 	if (getaudit_addr(&ai, sizeof (ai)) < 0) {
     82 		return (errno);
     83 	}
     84 
     85 	/*
     86 	 * if terminal ID already set, i.e. non-zero, then just return
     87 	 */
     88 	if (ai.ai_termid.at_port ||
     89 	    ai.ai_termid.at_addr[0] ||
     90 	    ai.ai_termid.at_addr[1] ||
     91 	    ai.ai_termid.at_addr[2] ||
     92 	    ai.ai_termid.at_addr[3]) {
     93 		return (0);
     94 	}
     95 
     96 	ai.ai_termid.at_port = ((peer->sin6_port<<16) | (sock->sin6_port));
     97 	ai.ai_termid.at_type = AU_IPv6;
     98 	bcopy(&peer->sin6_addr, ai.ai_termid.at_addr, 16);
     99 
    100 	if (setaudit_addr(&ai, sizeof (ai)) < 0) {
    101 		return (errno);
    102 	}
    103 
    104 	return (0);
    105 }
    106 
    107 static int
    108 do_ipv4_address(struct sockaddr_in *peer, struct sockaddr_in *sock)
    109 {
    110 	auditinfo_t ai;
    111 
    112 	/* get audit characteristics of process */
    113 	if (getaudit(&ai) < 0) {
    114 		return (errno);
    115 	}
    116 
    117 	/*
    118 	 * if terminal ID already set, i.e. non-zero, then just return
    119 	 */
    120 	if (ai.ai_termid.port || ai.ai_termid.machine) {
    121 		return (0);
    122 	}
    123 
    124 	ai.ai_termid.port = (peer->sin_port<<16 | sock->sin_port);
    125 	ai.ai_termid.machine = (uint32_t)peer->sin_addr.s_addr;
    126 
    127 	if (setaudit(&ai) < 0) {
    128 		return (errno);
    129 	}
    130 
    131 	return (0);
    132 }
    133