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