ibcs2_socksys.c revision 93593
1/* 2 * Copyright (c) 1994, 1995 Scott Bartram 3 * Copyright (c) 1994 Arne H Juul 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. The name of the author may not be used to endorse or promote products 12 * derived from this software without specific prior written permission 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * $FreeBSD: head/sys/i386/ibcs2/ibcs2_socksys.c 93593 2002-04-01 21:31:13Z jhb $ 26 */ 27 28#include <sys/param.h> 29#include <sys/systm.h> 30#include <sys/sysproto.h> 31#include <sys/jail.h> 32#include <sys/kernel.h> 33#include <sys/sysctl.h> 34 35#include <i386/ibcs2/ibcs2_socksys.h> 36#include <i386/ibcs2/ibcs2_util.h> 37 38/* Local structures */ 39struct getipdomainname_args { 40 char *ipdomainname; 41 int len; 42}; 43 44struct setipdomainname_args { 45 char *ipdomainname; 46 int len; 47}; 48 49/* Local prototypes */ 50static int ibcs2_getipdomainname(struct thread *, 51 struct getipdomainname_args *); 52static int ibcs2_setipdomainname(struct thread *, 53 struct setipdomainname_args *); 54 55/* 56 * iBCS2 socksys calls. 57 */ 58 59int 60ibcs2_socksys(td, uap) 61 register struct thread *td; 62 register struct ibcs2_socksys_args *uap; 63{ 64 int error; 65 int realargs[7]; /* 1 for command, 6 for recvfrom */ 66 void *passargs; 67 68 /* 69 * SOCKET should only be legal on /dev/socksys. 70 * GETIPDOMAINNAME should only be legal on /dev/socksys ? 71 * The others are (and should be) only legal on sockets. 72 */ 73 74 if ((error = copyin(uap->argsp, (caddr_t)realargs, sizeof(realargs))) != 0) 75 return error; 76 DPRINTF(("ibcs2_socksys: %08x %08x %08x %08x %08x %08x %08x\n", 77 realargs[0], realargs[1], realargs[2], realargs[3], 78 realargs[4], realargs[5], realargs[6])); 79 80 passargs = (void *)(realargs + 1); 81 switch (realargs[0]) { 82 case SOCKSYS_ACCEPT: 83 return accept(td, passargs); 84 case SOCKSYS_BIND: 85 return bind(td, passargs); 86 case SOCKSYS_CONNECT: 87 return connect(td, passargs); 88 case SOCKSYS_GETPEERNAME: 89 return getpeername(td, passargs); 90 case SOCKSYS_GETSOCKNAME: 91 return getsockname(td, passargs); 92 case SOCKSYS_GETSOCKOPT: 93 return getsockopt(td, passargs); 94 case SOCKSYS_LISTEN: 95 return listen(td, passargs); 96 case SOCKSYS_RECV: 97 realargs[5] = realargs[6] = 0; 98 /* FALLTHROUGH */ 99 case SOCKSYS_RECVFROM: 100 return recvfrom(td, passargs); 101 case SOCKSYS_SEND: 102 realargs[5] = realargs[6] = 0; 103 /* FALLTHROUGH */ 104 case SOCKSYS_SENDTO: 105 return sendto(td, passargs); 106 case SOCKSYS_SETSOCKOPT: 107 return setsockopt(td, passargs); 108 case SOCKSYS_SHUTDOWN: 109 return shutdown(td, passargs); 110 case SOCKSYS_SOCKET: 111 return socket(td, passargs); 112 case SOCKSYS_SELECT: 113 return select(td, passargs); 114 case SOCKSYS_GETIPDOMAIN: 115 return ibcs2_getipdomainname(td, passargs); 116 case SOCKSYS_SETIPDOMAIN: 117 return ibcs2_setipdomainname(td, passargs); 118 case SOCKSYS_ADJTIME: 119 return adjtime(td, passargs); 120 case SOCKSYS_SETREUID: 121 return setreuid(td, passargs); 122 case SOCKSYS_SETREGID: 123 return setregid(td, passargs); 124 case SOCKSYS_GETTIME: 125 return gettimeofday(td, passargs); 126 case SOCKSYS_SETTIME: 127 return settimeofday(td, passargs); 128 case SOCKSYS_GETITIMER: 129 return getitimer(td, passargs); 130 case SOCKSYS_SETITIMER: 131 return setitimer(td, passargs); 132 133 default: 134 printf("socksys unknown %08x %08x %08x %08x %08x %08x %08x\n", 135 realargs[0], realargs[1], realargs[2], realargs[3], 136 realargs[4], realargs[5], realargs[6]); 137 return EINVAL; 138 } 139 /* NOTREACHED */ 140} 141 142/* ARGSUSED */ 143static int 144ibcs2_getipdomainname(td, uap) 145 struct thread *td; 146 struct getipdomainname_args *uap; 147{ 148 char hname[MAXHOSTNAMELEN], *dptr; 149 int len; 150 151 /* Get the domain name */ 152 getcredhostname(td->td_ucred, hname, sizeof(hname)); 153 154 dptr = index(hname, '.'); 155 if ( dptr ) 156 dptr++; 157 else 158 /* Make it effectively an empty string */ 159 dptr = hname + strlen(hname); 160 161 len = strlen(dptr) + 1; 162 if ((u_int)uap->len > len + 1) 163 uap->len = len + 1; 164 return (copyout((caddr_t)dptr, (caddr_t)uap->ipdomainname, uap->len)); 165} 166 167/* ARGSUSED */ 168static int 169ibcs2_setipdomainname(td, uap) 170 struct thread *td; 171 struct setipdomainname_args *uap; 172{ 173 char hname[MAXHOSTNAMELEN], *ptr; 174 int error, sctl[2], hlen; 175 176 if ((error = suser(td))) 177 return (error); 178 179 /* W/out a hostname a domain-name is nonsense */ 180 if ( strlen(hostname) == 0 ) 181 return EINVAL; 182 183 /* Get the host's unqualified name (strip off the domain) */ 184 snprintf(hname, sizeof(hname), "%s", hostname); 185 ptr = index(hname, '.'); 186 if ( ptr != NULL ) { 187 ptr++; 188 *ptr = '\0'; 189 } else 190 strcat(hname, "."); 191 192 /* Set ptr to the end of the string so we can append to it */ 193 hlen = strlen(hname); 194 ptr = hname + hlen; 195 if ((u_int)uap->len > (sizeof (hname) - hlen - 1)) 196 return EINVAL; 197 198 /* Append the ipdomain to the end */ 199 error = copyin((caddr_t)uap->ipdomainname, ptr, uap->len); 200 if (error) 201 return (error); 202 203 /* 'sethostname' with the new information */ 204 sctl[0] = CTL_KERN; 205 sctl[1] = KERN_HOSTNAME; 206 hlen = strlen(hname) + 1; 207 return (kernel_sysctl(td, sctl, 2, 0, 0, hname, hlen, 0)); 208} 209