ti_opts.c revision ae347574c7f17d33bb822cb146d7f67c88ab1f68
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Portions of this source code were derived from Berkeley
* 4.3 BSD under license from the Regents of the University of
* California.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "mt.h"
#include <stdio.h>
#include <inttypes.h>
#include <tiuser.h>
#include <errno.h>
#include <libintl.h>
#include <string.h>
#include <strings.h>
#include <syslog.h>
#include <unistd.h>
#include <ucred.h>
#include <alloca.h>
#include <stdlib.h>
#include <zone.h>
/*
* This routine is typically called on the server side if the server
* wants to know the caller ucred. Called typically by rpcbind. It
* depends upon the t_optmgmt call to local transport driver so that
* return the uid value in options in T_CONN_IND, T_CONN_CON and
* T_UNITDATA_IND.
* With the advent of the credential in the mblk, this is simply
* extended to all transports when the packet travels over the
* loopback network; for UDP we use a special socket option and for
* tcp we don't need to do any setup, we just call getpeerucred()
* later.
*/
/*
* Version for Solaris with new local transport code and ucred.
*/
int
__rpc_negotiate_uid(int fd)
{
unsigned int set = 1;
/* For tcp we use getpeerucred and it needs no initialization. */
return (0);
"ioctl:I_STR:TL_IOC_UCREDOPT/SO_RECVUCRED");
return (-1);
}
return (0);
}
void
svc_fd_negotiate_ucred(int fd)
{
(void) __rpc_negotiate_uid(fd);
}
/*
* This returns the ucred of the caller. It assumes that the optbuf
* information is stored at xprt->xp_p2.
* There are three distinct cases: the option buffer is headed
* with a "struct opthdr" and the credential option is the only
* one, or it's a T_opthdr and our option may follow others; or there
* are no options and we attempt getpeerucred().
*/
static int
{
/* LINTED pointer alignment */
goto verifyzone;
return (-1);
}
#ifdef RPC_DEBUG
#endif
/* LINTED pointer cast */
#ifdef RPC_DEBUG
#endif
/*
* Always from inside our zone because zones use a separate name
* space for loopback; at this time, the kernel may send a
* packet pretending to be from the global zone when it's
* really from our zone so we skip the zone check.
*/
return (0);
}
/* LINTED pointer cast */
#ifdef RPC_DEBUG
#endif
return (-1);
#ifdef RPC_DEBUG
#endif
goto verifyzone;
}
}
return (-1);
if (!checkzone)
return (0);
/* Return 0 only for the local zone */
}
/*
* Version for Solaris with new local transport code
*/
int
{
int err;
/* LINTED - pointer alignment */
else
if (err != 0)
return (-1);
return (0);
}
/*
* Return local credentials.
*/
{
int err;
/* LINTED - pointer alignment */
else
if (err != 0)
return (FALSE);
return (TRUE);
}
/*
* Return local ucred.
*/
int
{
int err;
return (-1);
}
/* LINTED - pointer alignment */
else
if (err != 0) {
return (-1);
}
return (0);
}
/*
* get local ip address
*/
int
{
unsigned int total_optlen;
struct sockaddr_in *ipv4sa;
struct sockaddr_in6 *ipv6sa;
int s;
struct sioc_addrreq areq;
return (-1);
}
if (total_optlen == 0)
return (1);
/* LINTED pointer alignment */
return (-1);
}
/* Make sure the start of the buffer is aligned */
if (!(__TPI_TOPT_ISALIGNED(opt_start))) {
return (-1);
}
/* LINTED pointer alignment */
/*
* Look for the desired option header
*/
do {
return (-1);
}
return (-1);
}
return (-1);
}
case IPPROTO_IP:
struct sockaddr_in v4tmp;
opt++;
return (-1);
}
#ifdef RPC_DEBUG
{
char str[INET_ADDRSTRLEN];
"__rpc_get_ltaddr for IP_RECVDSTADDR: %s",
str);
}
#endif
#ifdef RPC_DEBUG
"dev udp open failed");
#endif
return (1);
}
sizeof (v4tmp));
"get_ltaddr:ioctl for udp failed");
(void) close(s);
return (1);
}
(void) close(s);
/* LINTED pointer cast */
return (0);
} else
return (1);
}
break;
case IPPROTO_IPV6:
struct sockaddr_in6 v6tmp;
opt++;
sizeof (struct in6_pktinfo)) >
return (-1);
}
#ifdef RPC_DEBUG
{
struct in6_pktinfo *in6_pkt;
char str[INET6_ADDRSTRLEN];
"__rpc_get_ltaddr for IPV6_PKTINFO: %s",
str);
}
#endif
#ifdef RPC_DEBUG
"dev udp6 open failed");
#endif
return (1);
}
sizeof (v6tmp));
"get_ltaddr:ioctl for udp6 failed");
(void) close(s);
return (1);
}
(void) close(s);
/* LINTED pointer cast */
return (0);
} else
return (1);
}
break;
default:
break;
}
/* LINTED improper alignment */
return (1);
}
#define __TRANSPORT_INDSZ 128
int
{
int *ip;
int optsz;
char buf[__TRANSPORT_INDSZ];
switch (optname) {
case SO_DONTLINGER: {
/* LINTED */
break;
}
case SO_LINGER: {
/* LINTED */
break;
}
case IP_RECVDSTADDR:
case IPV6_RECVPKTINFO:
case SO_DEBUG:
case SO_KEEPALIVE:
case SO_DONTROUTE:
case SO_USELOOPBACK:
case SO_REUSEADDR:
case SO_DGRAM_ERRIND:
case SO_RECVUCRED:
case SO_ANON_MLP:
case SO_MAC_EXEMPT:
case SO_EXCLBIND:
case TCP_EXCLBIND:
case UDP_EXCLBIND:
/* LINTED */
optsz = sizeof (int);
break;
default:
return (-1);
}
/* LINTED */
return (-1);
}
return (0);
}
/*
* Format an error message corresponding to the given TLI and system error
* codes.
*/
void
{
char *errorstr;
"Unknown system error %d"),
sys_err);
else
} else {
}
}
/*
* Depending on the specified RPC number, attempt to set mac_exempt
* option on the opened socket; these requests need to be able to do MAC
* MAC read-down operations. Privilege is needed to set this option.
*/
void
{
int ret = 0;
if (!is_system_labeled())
return;
return;
if (is_multilevel(prognum)) {
if (ret < 0) {
char errorstr[100];
errorstr);
}
}
}