1/* 2 * Copyright (c) 1989, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rick Macklem at The University of Guelph. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint 38static const char copyright[] = 39"@(#) Copyright (c) 1989, 1993, 1994\n\ 40 The Regents of the University of California. All rights reserved.\n"; 41#endif not lint 42 43#ifndef lint 44#if 0 45static char sccsid[] = "@(#)nfsd.c 8.9 (Berkeley) 3/29/95"; 46#endif 47static const char rcsid[] =
| 1/* 2 * Copyright (c) 1989, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rick Macklem at The University of Guelph. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint 38static const char copyright[] = 39"@(#) Copyright (c) 1989, 1993, 1994\n\ 40 The Regents of the University of California. All rights reserved.\n"; 41#endif not lint 42 43#ifndef lint 44#if 0 45static char sccsid[] = "@(#)nfsd.c 8.9 (Berkeley) 3/29/95"; 46#endif 47static const char rcsid[] =
|
48 "$FreeBSD: head/usr.sbin/nfsd/nfsd.c 65379 2000-09-02 20:52:15Z brian $";
| 48 "$FreeBSD: head/usr.sbin/nfsd/nfsd.c 74462 2001-03-19 12:50:13Z alfred $";
|
49#endif not lint 50 51#include <sys/param.h> 52#include <sys/syslog.h> 53#include <sys/wait.h> 54#include <sys/mount.h> 55 56#include <rpc/rpc.h> 57#include <rpc/pmap_clnt.h> 58 59#include <netdb.h> 60#include <arpa/inet.h>
| 49#endif not lint 50 51#include <sys/param.h> 52#include <sys/syslog.h> 53#include <sys/wait.h> 54#include <sys/mount.h> 55 56#include <rpc/rpc.h> 57#include <rpc/pmap_clnt.h> 58 59#include <netdb.h> 60#include <arpa/inet.h>
|
61#ifdef ISO 62#include <netiso/iso.h> 63#endif
| |
64#include <nfs/rpcv2.h> 65#include <nfs/nfsproto.h> 66#include <nfs/nfs.h> 67 68#ifdef NFSKERB 69#include <kerberosIV/des.h> 70#include <kerberosIV/krb.h> 71#endif 72 73#include <err.h> 74#include <errno.h> 75#include <stdio.h> 76#include <stdlib.h> 77#include <strings.h> 78#include <unistd.h>
| 61#include <nfs/rpcv2.h> 62#include <nfs/nfsproto.h> 63#include <nfs/nfs.h> 64 65#ifdef NFSKERB 66#include <kerberosIV/des.h> 67#include <kerberosIV/krb.h> 68#endif 69 70#include <err.h> 71#include <errno.h> 72#include <stdio.h> 73#include <stdlib.h> 74#include <strings.h> 75#include <unistd.h>
|
| 76#include <netdb.h>
|
79 80/* Global defs */ 81#ifdef DEBUG 82#define syslog(e, s) fprintf(stderr,(s)) 83int debug = 1; 84#else 85int debug = 0; 86#endif 87 88struct nfsd_srvargs nsd; 89#ifdef OLD_SETPROCTITLE 90char **Argv = NULL; /* pointer to argument vector */ 91char *LastArg = NULL; /* end of argv */ 92#endif 93 94#ifdef NFSKERB 95char lnam[ANAME_SZ]; 96KTEXT_ST kt; 97AUTH_DAT kauth; 98char inst[INST_SZ]; 99struct nfsrpc_fullblock kin, kout; 100struct nfsrpc_fullverf kverf; 101NFSKERBKEY_T kivec; 102struct timeval ktv; 103NFSKERBKEYSCHED_T kerb_keysched; 104#endif 105
| 77 78/* Global defs */ 79#ifdef DEBUG 80#define syslog(e, s) fprintf(stderr,(s)) 81int debug = 1; 82#else 83int debug = 0; 84#endif 85 86struct nfsd_srvargs nsd; 87#ifdef OLD_SETPROCTITLE 88char **Argv = NULL; /* pointer to argument vector */ 89char *LastArg = NULL; /* end of argv */ 90#endif 91 92#ifdef NFSKERB 93char lnam[ANAME_SZ]; 94KTEXT_ST kt; 95AUTH_DAT kauth; 96char inst[INST_SZ]; 97struct nfsrpc_fullblock kin, kout; 98struct nfsrpc_fullverf kverf; 99NFSKERBKEY_T kivec; 100struct timeval ktv; 101NFSKERBKEYSCHED_T kerb_keysched; 102#endif 103
|
106void nonfs __P((int)); 107void reapchild __P((int)); 108void setbindhost __P((struct sockaddr_in *ia, const char *bindhost));
| 104#define MAXNFSDCNT 20 105#define DEFNFSDCNT 4 106pid_t children[MAXNFSDCNT]; /* PIDs of children */ 107int nfsdcnt; /* number of children */ 108 109void cleanup(int); 110void killchildren(void); 111void nonfs (int); 112void reapchild (int); 113int setbindhost (struct addrinfo **ia, const char *bindhost, struct addrinfo hints);
|
109#ifdef OLD_SETPROCTITLE 110#ifdef __FreeBSD__
| 114#ifdef OLD_SETPROCTITLE 115#ifdef __FreeBSD__
|
111void setproctitle __P((char *));
| 116void setproctitle (char *);
|
112#endif 113#endif
| 117#endif 118#endif
|
114void usage __P((void));
| 119void unregistration (void); 120void usage (void);
|
115 116/* 117 * Nfs server daemon mostly just a user context for nfssvc() 118 * 119 * 1 - do file descriptor and signal cleanup 120 * 2 - fork the nfsd(s) 121 * 3 - create server socket(s)
| 121 122/* 123 * Nfs server daemon mostly just a user context for nfssvc() 124 * 125 * 1 - do file descriptor and signal cleanup 126 * 2 - fork the nfsd(s) 127 * 3 - create server socket(s)
|
122 * 4 - register socket with portmap
| 128 * 4 - register socket with rpcbind
|
123 * 124 * For connectionless protocols, just pass the socket into the kernel via. 125 * nfssvc(). 126 * For connection based sockets, loop doing accepts. When you get a new 127 * socket from accept, pass the msgsock into the kernel via. nfssvc(). 128 * The arguments are: 129 * -c - support iso cltp clients
| 129 * 130 * For connectionless protocols, just pass the socket into the kernel via. 131 * nfssvc(). 132 * For connection based sockets, loop doing accepts. When you get a new 133 * socket from accept, pass the msgsock into the kernel via. nfssvc(). 134 * The arguments are: 135 * -c - support iso cltp clients
|
130 * -r - reregister with portmapper
| 136 * -r - reregister with rpcbind 137 * -d - unregister with rpcbind
|
131 * -t - support tcp nfs clients 132 * -u - support udp nfs clients 133 * followed by "n" which is the number of nfsds' to fork off 134 */ 135int 136main(argc, argv, envp) 137 int argc; 138 char *argv[], *envp[]; 139{ 140 struct nfsd_args nfsdargs;
| 138 * -t - support tcp nfs clients 139 * -u - support udp nfs clients 140 * followed by "n" which is the number of nfsds' to fork off 141 */ 142int 143main(argc, argv, envp) 144 int argc; 145 char *argv[], *envp[]; 146{ 147 struct nfsd_args nfsdargs;
|
141 struct sockaddr_in inetaddr, inetpeer; 142#ifdef ISO 143 struct sockaddr_iso isoaddr, isopeer; 144 char *cp; 145#endif
| 148 struct addrinfo *ai_udp, *ai_tcp, *ai_udp6, *ai_tcp6, hints; 149 struct netconfig *nconf_udp, *nconf_tcp, *nconf_udp6, *nconf_tcp6; 150 struct netbuf nb_udp, nb_tcp, nb_udp6, nb_tcp6; 151 struct sockaddr_in inetpeer; 152 struct sockaddr_in6 inet6peer;
|
146 fd_set ready, sockbits;
| 153 fd_set ready, sockbits;
|
| 154 fd_set v4bits, v6bits;
|
147 int ch, cltpflag, connect_type_cnt, i, len, maxsock, msgsock;
| 155 int ch, cltpflag, connect_type_cnt, i, len, maxsock, msgsock;
|
148 int nfsdcnt, nfssvc_flag, on, reregister, sock, tcpflag, tcpsock; 149 int tp4cnt, tp4flag, tpipcnt, tpipflag, udpflag; 150 int bindhostc = 0, bindanyflag;
| 156 int nfssvc_flag, on = 1, unregister, reregister, sock; 157 int tcp6sock, ip6flag, tcpflag, tcpsock; 158 int udpflag, ecode, s; 159 int bindhostc = 0, bindanyflag, rpcbreg, rpcbregcnt;
|
151 char **bindhost = NULL;
| 160 char **bindhost = NULL;
|
152#ifdef notyet 153 int tp4sock, tpipsock; 154#endif
| 161 pid_t pid;
|
155#ifdef NFSKERB 156 struct group *grp; 157 struct passwd *pwd; 158 struct ucred *cr; 159 struct timeval ktv; 160 char **cpp; 161#endif 162#ifdef __FreeBSD__ 163 struct vfsconf vfc; 164 int error; 165 166 error = getvfsbyname("nfs", &vfc); 167 if (error && vfsisloadable("nfs")) { 168 if (vfsload("nfs")) 169 err(1, "vfsload(nfs)"); 170 endvfsent(); /* flush cache */ 171 error = getvfsbyname("nfs", &vfc); 172 } 173 if (error) 174 errx(1, "NFS is not available in the running kernel"); 175#endif 176 177#ifdef OLD_SETPROCTITLE 178 /* Save start and extent of argv for setproctitle. */ 179 Argv = argv; 180 if (envp == 0 || *envp == 0) 181 envp = argv; 182 while (*envp) 183 envp++; 184 LastArg = envp[-1] + strlen(envp[-1]); 185#endif 186
| 162#ifdef NFSKERB 163 struct group *grp; 164 struct passwd *pwd; 165 struct ucred *cr; 166 struct timeval ktv; 167 char **cpp; 168#endif 169#ifdef __FreeBSD__ 170 struct vfsconf vfc; 171 int error; 172 173 error = getvfsbyname("nfs", &vfc); 174 if (error && vfsisloadable("nfs")) { 175 if (vfsload("nfs")) 176 err(1, "vfsload(nfs)"); 177 endvfsent(); /* flush cache */ 178 error = getvfsbyname("nfs", &vfc); 179 } 180 if (error) 181 errx(1, "NFS is not available in the running kernel"); 182#endif 183 184#ifdef OLD_SETPROCTITLE 185 /* Save start and extent of argv for setproctitle. */ 186 Argv = argv; 187 if (envp == 0 || *envp == 0) 188 envp = argv; 189 while (*envp) 190 envp++; 191 LastArg = envp[-1] + strlen(envp[-1]); 192#endif 193
|
187#define MAXNFSDCNT 20 188#define DEFNFSDCNT 4
| |
189 nfsdcnt = DEFNFSDCNT;
| 194 nfsdcnt = DEFNFSDCNT;
|
190 cltpflag = reregister = tcpflag = tp4cnt = tp4flag = tpipcnt = 0; 191 bindanyflag = tpipflag = udpflag = 0; 192#ifdef ISO 193#define GETOPT "ach:n:rtu" 194#define USAGE "[-acrtu] [-n num_servers] [-h bindip]" 195#else 196#define GETOPT "ah:n:rtu" 197#define USAGE "[-artu] [-n num_servers] [-h bindip]" 198#endif
| 195 cltpflag = unregister = reregister = tcpflag = 0; 196 bindanyflag = udpflag = ip6flag = 0; 197#define GETOPT "ah:n:rdtu" 198#define USAGE "[-ardtu] [-n num_servers] [-h bindip]"
|
199 while ((ch = getopt(argc, argv, GETOPT)) != -1) 200 switch (ch) { 201 case 'a': 202 bindanyflag = 1; 203 break; 204 case 'n': 205 nfsdcnt = atoi(optarg); 206 if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) { 207 warnx("nfsd count %d; reset to %d", nfsdcnt, 208 DEFNFSDCNT); 209 nfsdcnt = DEFNFSDCNT; 210 } 211 break; 212 case 'h': 213 bindhostc++; 214 bindhost = realloc(bindhost,sizeof(char *)*bindhostc); 215 if (bindhost == NULL) 216 errx(1, "Out of memory"); 217 bindhost[bindhostc-1] = strdup(optarg); 218 if (bindhost[bindhostc-1] == NULL) 219 errx(1, "Out of memory"); 220 break; 221 case 'r': 222 reregister = 1; 223 break;
| 199 while ((ch = getopt(argc, argv, GETOPT)) != -1) 200 switch (ch) { 201 case 'a': 202 bindanyflag = 1; 203 break; 204 case 'n': 205 nfsdcnt = atoi(optarg); 206 if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) { 207 warnx("nfsd count %d; reset to %d", nfsdcnt, 208 DEFNFSDCNT); 209 nfsdcnt = DEFNFSDCNT; 210 } 211 break; 212 case 'h': 213 bindhostc++; 214 bindhost = realloc(bindhost,sizeof(char *)*bindhostc); 215 if (bindhost == NULL) 216 errx(1, "Out of memory"); 217 bindhost[bindhostc-1] = strdup(optarg); 218 if (bindhost[bindhostc-1] == NULL) 219 errx(1, "Out of memory"); 220 break; 221 case 'r': 222 reregister = 1; 223 break;
|
| 224 case 'd': 225 unregister = 1; 226 break;
|
224 case 't': 225 tcpflag = 1; 226 break; 227 case 'u': 228 udpflag = 1; 229 break;
| 227 case 't': 228 tcpflag = 1; 229 break; 230 case 'u': 231 udpflag = 1; 232 break;
|
230#ifdef ISO 231 case 'c': 232 cltpflag = 1; 233 break; 234#ifdef notyet 235 case 'i': 236 tp4cnt = 1; 237 break; 238 case 'p': 239 tpipcnt = 1; 240 break; 241#endif /* notyet */ 242#endif /* ISO */
| |
243 default: 244 case '?': 245 usage(); 246 }; 247 if (!tcpflag && !udpflag) 248 udpflag = 1; 249 argv += optind; 250 argc -= optind; 251 252 /* 253 * XXX 254 * Backward compatibility, trailing number is the count of daemons. 255 */ 256 if (argc > 1) 257 usage(); 258 if (argc == 1) { 259 nfsdcnt = atoi(argv[0]); 260 if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) { 261 warnx("nfsd count %d; reset to %d", nfsdcnt, 262 DEFNFSDCNT); 263 nfsdcnt = DEFNFSDCNT; 264 } 265 }
| 233 default: 234 case '?': 235 usage(); 236 }; 237 if (!tcpflag && !udpflag) 238 udpflag = 1; 239 argv += optind; 240 argc -= optind; 241 242 /* 243 * XXX 244 * Backward compatibility, trailing number is the count of daemons. 245 */ 246 if (argc > 1) 247 usage(); 248 if (argc == 1) { 249 nfsdcnt = atoi(argv[0]); 250 if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) { 251 warnx("nfsd count %d; reset to %d", nfsdcnt, 252 DEFNFSDCNT); 253 nfsdcnt = DEFNFSDCNT; 254 } 255 }
|
| 256 ip6flag = 1; 257 s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); 258 if (s < 0 && (errno == EPROTONOSUPPORT || 259 errno == EPFNOSUPPORT || errno == EAFNOSUPPORT)) 260 ip6flag = 0; 261 else 262 close(s);
|
266 267 if (bindhostc == 0 || bindanyflag) { 268 bindhostc++; 269 bindhost = realloc(bindhost,sizeof(char *)*bindhostc); 270 if (bindhost == NULL) 271 errx(1, "Out of memory"); 272 bindhost[bindhostc-1] = strdup("*"); 273 if (bindhost[bindhostc-1] == NULL) 274 errx(1, "Out of memory"); 275 } 276 277 if (debug == 0) { 278 daemon(0, 0); 279 (void)signal(SIGHUP, SIG_IGN); 280 (void)signal(SIGINT, SIG_IGN);
| 263 264 if (bindhostc == 0 || bindanyflag) { 265 bindhostc++; 266 bindhost = realloc(bindhost,sizeof(char *)*bindhostc); 267 if (bindhost == NULL) 268 errx(1, "Out of memory"); 269 bindhost[bindhostc-1] = strdup("*"); 270 if (bindhost[bindhostc-1] == NULL) 271 errx(1, "Out of memory"); 272 } 273 274 if (debug == 0) { 275 daemon(0, 0); 276 (void)signal(SIGHUP, SIG_IGN); 277 (void)signal(SIGINT, SIG_IGN);
|
281 (void)signal(SIGQUIT, SIG_IGN);
| |
282 (void)signal(SIGSYS, nonfs);
| 278 (void)signal(SIGSYS, nonfs);
|
| 279 (void)signal(SIGUSR1, cleanup); 280 /* 281 * nfsd sits in the kernel most of the time. It needs 282 * to ignore SIGTERM/SIGQUIT in order to stay alive as long 283 * as possible during a shutdown, otherwise loopback 284 * mounts will not be able to unmount. 285 */
|
283 (void)signal(SIGTERM, SIG_IGN);
| 286 (void)signal(SIGTERM, SIG_IGN);
|
| 287 (void)signal(SIGQUIT, SIG_IGN);
|
284 } 285 (void)signal(SIGCHLD, reapchild);
| 288 } 289 (void)signal(SIGCHLD, reapchild);
|
286
| 290 if (unregister) { 291 unregistration(); 292 exit (0); 293 }
|
287 if (reregister) {
| 294 if (reregister) {
|
288 if (udpflag && 289 (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) || 290 !pmap_set(RPCPROG_NFS, 3, IPPROTO_UDP, NFS_PORT))) 291 err(1, "can't register with portmap for UDP"); 292 if (tcpflag && 293 (!pmap_set(RPCPROG_NFS, 2, IPPROTO_TCP, NFS_PORT) || 294 !pmap_set(RPCPROG_NFS, 3, IPPROTO_TCP, NFS_PORT))) 295 err(1, "can't register with portmap for TCP"); 296 exit(0);
| 295 if (udpflag) { 296 memset(&hints, 0, sizeof hints); 297 hints.ai_flags = AI_PASSIVE; 298 hints.ai_family = AF_INET; 299 hints.ai_socktype = SOCK_DGRAM; 300 hints.ai_protocol = IPPROTO_UDP; 301 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp); 302 if (ecode != 0) { 303 syslog(LOG_ERR, "getaddrinfo udp: %s", 304 gai_strerror(ecode)); 305 exit(1); 306 } 307 nconf_udp = getnetconfigent("udp"); 308 if (nconf_udp == NULL) 309 err(1, "getnetconfigent udp failed"); 310 nb_udp.buf = ai_udp->ai_addr; 311 nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen; 312 if ((!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp)) || 313 (!rpcb_set(RPCPROG_NFS, 3, nconf_udp, &nb_udp))) 314 err(1, "rpcb_set udp failed"); 315 freeaddrinfo(ai_udp); 316 } 317 if (udpflag && ip6flag) { 318 memset(&hints, 0, sizeof hints); 319 hints.ai_flags = AI_PASSIVE; 320 hints.ai_family = AF_INET6; 321 hints.ai_socktype = SOCK_DGRAM; 322 hints.ai_protocol = IPPROTO_UDP; 323 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6); 324 if (ecode != 0) { 325 syslog(LOG_ERR, "getaddrinfo udp6: %s", 326 gai_strerror(ecode)); 327 exit(1); 328 } 329 nconf_udp6 = getnetconfigent("udp6"); 330 if (nconf_udp6 == NULL) 331 err(1, "getnetconfigent udp6 failed"); 332 nb_udp6.buf = ai_udp6->ai_addr; 333 nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen; 334 if ((!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6)) || 335 (!rpcb_set(RPCPROG_NFS, 3, nconf_udp6, &nb_udp6))) 336 err(1, "rpcb_set udp6 failed"); 337 freeaddrinfo(ai_udp6); 338 } 339 if (tcpflag) { 340 memset(&hints, 0, sizeof hints); 341 hints.ai_flags = AI_PASSIVE; 342 hints.ai_family = AF_INET; 343 hints.ai_socktype = SOCK_STREAM; 344 hints.ai_protocol = IPPROTO_TCP; 345 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp); 346 if (ecode != 0) { 347 syslog(LOG_ERR, "getaddrinfo tcp: %s", 348 gai_strerror(ecode)); 349 exit(1); 350 } 351 nconf_tcp = getnetconfigent("tcp"); 352 if (nconf_tcp == NULL) 353 err(1, "getnetconfigent tcp failed"); 354 nb_tcp.buf = ai_tcp->ai_addr; 355 nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen; 356 if ((!rpcb_set(RPCPROG_NFS, 2, nconf_tcp, &nb_tcp)) || 357 (!rpcb_set(RPCPROG_NFS, 3, nconf_tcp, &nb_tcp))) 358 err(1, "rpcb_set tcp failed"); 359 freeaddrinfo(ai_tcp); 360 } 361 if (tcpflag && ip6flag) { 362 memset(&hints, 0, sizeof hints); 363 hints.ai_flags = AI_PASSIVE; 364 hints.ai_family = AF_INET6; 365 hints.ai_socktype = SOCK_STREAM; 366 hints.ai_protocol = IPPROTO_TCP; 367 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6); 368 if (ecode != 0) { 369 syslog(LOG_ERR, "getaddrinfo tcp6: %s", 370 gai_strerror(ecode)); 371 exit(1); 372 } 373 nconf_tcp6 = getnetconfigent("tcp6"); 374 if (nconf_tcp6 == NULL) 375 err(1, "getnetconfigent tcp6 failed"); 376 nb_tcp6.buf = ai_tcp6->ai_addr; 377 nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen; 378 if ((!rpcb_set(RPCPROG_NFS, 2, nconf_tcp6, &nb_tcp6)) || 379 (!rpcb_set(RPCPROG_NFS, 3, nconf_tcp6, &nb_tcp6))) 380 err(1, "rpcb_set tcp6 failed"); 381 freeaddrinfo(ai_tcp6); 382 } 383 exit (0);
|
297 }
| 384 }
|
| 385
|
298 openlog("nfsd:", LOG_PID, LOG_DAEMON); 299 300 for (i = 0; i < nfsdcnt; i++) {
| 386 openlog("nfsd:", LOG_PID, LOG_DAEMON); 387 388 for (i = 0; i < nfsdcnt; i++) {
|
301 switch (fork()) {
| 389 switch ((pid = fork())) {
|
302 case -1: 303 syslog(LOG_ERR, "fork: %m");
| 390 case -1: 391 syslog(LOG_ERR, "fork: %m");
|
| 392 killchildren();
|
304 exit (1); 305 case 0: 306 break; 307 default:
| 393 exit (1); 394 case 0: 395 break; 396 default:
|
| 397 children[i] = pid;
|
308 continue; 309 } 310 311 setproctitle("server"); 312 nfssvc_flag = NFSSVC_NFSD; 313 nsd.nsd_nfsd = NULL; 314#ifdef NFSKERB 315 if (sizeof (struct nfsrpc_fullverf) != RPCX_FULLVERF || 316 sizeof (struct nfsrpc_fullblock) != RPCX_FULLBLOCK) 317 syslog(LOG_ERR, "Yikes NFSKERB structs not packed!"); 318 nsd.nsd_authstr = (u_char *)&kt; 319 nsd.nsd_authlen = sizeof (kt); 320 nsd.nsd_verfstr = (u_char *)&kverf; 321 nsd.nsd_verflen = sizeof (kverf); 322#endif 323 while (nfssvc(nfssvc_flag, &nsd) < 0) { 324 if (errno != ENEEDAUTH) { 325 syslog(LOG_ERR, "nfssvc: %m"); 326 exit(1); 327 } 328 nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL; 329#ifdef NFSKERB 330 /* 331 * Get the Kerberos ticket out of the authenticator 332 * verify it and convert the principal name to a user 333 * name. The user name is then converted to a set of 334 * user credentials via the password and group file. 335 * Finally, decrypt the timestamp and validate it. 336 * For more info see the IETF Draft "Authentication 337 * in ONC RPC". 338 */ 339 kt.length = ntohl(kt.length); 340 if (gettimeofday(&ktv, (struct timezone *)0) == 0 && 341 kt.length > 0 && kt.length <= 342 (RPCAUTH_MAXSIZ - 3 * NFSX_UNSIGNED)) { 343 kin.w1 = NFS_KERBW1(kt); 344 kt.mbz = 0; 345 (void)strcpy(inst, "*"); 346 if (krb_rd_req(&kt, NFS_KERBSRV, 347 inst, nsd.nsd_haddr, &kauth, "") == RD_AP_OK && 348 krb_kntoln(&kauth, lnam) == KSUCCESS && 349 (pwd = getpwnam(lnam)) != NULL) { 350 cr = &nsd.nsd_cr; 351 cr->cr_uid = pwd->pw_uid; 352 cr->cr_groups[0] = pwd->pw_gid; 353 cr->cr_ngroups = 1; 354 setgrent(); 355 while ((grp = getgrent()) != NULL) { 356 if (grp->gr_gid == cr->cr_groups[0]) 357 continue; 358 for (cpp = grp->gr_mem; 359 *cpp != NULL; ++cpp) 360 if (!strcmp(*cpp, lnam)) 361 break; 362 if (*cpp == NULL) 363 continue; 364 cr->cr_groups[cr->cr_ngroups++] 365 = grp->gr_gid; 366 if (cr->cr_ngroups == NGROUPS) 367 break; 368 } 369 endgrent(); 370 371 /* 372 * Get the timestamp verifier out of the 373 * authenticator and verifier strings. 374 */ 375 kin.t1 = kverf.t1; 376 kin.t2 = kverf.t2; 377 kin.w2 = kverf.w2; 378 bzero((caddr_t)kivec, sizeof (kivec)); 379 bcopy((caddr_t)kauth.session, 380 (caddr_t)nsd.nsd_key,sizeof(kauth.session)); 381 382 /* 383 * Decrypt the timestamp verifier in CBC mode. 384 */ 385 XXX 386 387 /* 388 * Validate the timestamp verifier, to 389 * check that the session key is ok. 390 */ 391 nsd.nsd_timestamp.tv_sec = ntohl(kout.t1); 392 nsd.nsd_timestamp.tv_usec = ntohl(kout.t2); 393 nsd.nsd_ttl = ntohl(kout.w1); 394 if ((nsd.nsd_ttl - 1) == ntohl(kout.w2)) 395 nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN; 396 } 397#endif /* NFSKERB */ 398 } 399 exit(0); 400 } 401
| 398 continue; 399 } 400 401 setproctitle("server"); 402 nfssvc_flag = NFSSVC_NFSD; 403 nsd.nsd_nfsd = NULL; 404#ifdef NFSKERB 405 if (sizeof (struct nfsrpc_fullverf) != RPCX_FULLVERF || 406 sizeof (struct nfsrpc_fullblock) != RPCX_FULLBLOCK) 407 syslog(LOG_ERR, "Yikes NFSKERB structs not packed!"); 408 nsd.nsd_authstr = (u_char *)&kt; 409 nsd.nsd_authlen = sizeof (kt); 410 nsd.nsd_verfstr = (u_char *)&kverf; 411 nsd.nsd_verflen = sizeof (kverf); 412#endif 413 while (nfssvc(nfssvc_flag, &nsd) < 0) { 414 if (errno != ENEEDAUTH) { 415 syslog(LOG_ERR, "nfssvc: %m"); 416 exit(1); 417 } 418 nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL; 419#ifdef NFSKERB 420 /* 421 * Get the Kerberos ticket out of the authenticator 422 * verify it and convert the principal name to a user 423 * name. The user name is then converted to a set of 424 * user credentials via the password and group file. 425 * Finally, decrypt the timestamp and validate it. 426 * For more info see the IETF Draft "Authentication 427 * in ONC RPC". 428 */ 429 kt.length = ntohl(kt.length); 430 if (gettimeofday(&ktv, (struct timezone *)0) == 0 && 431 kt.length > 0 && kt.length <= 432 (RPCAUTH_MAXSIZ - 3 * NFSX_UNSIGNED)) { 433 kin.w1 = NFS_KERBW1(kt); 434 kt.mbz = 0; 435 (void)strcpy(inst, "*"); 436 if (krb_rd_req(&kt, NFS_KERBSRV, 437 inst, nsd.nsd_haddr, &kauth, "") == RD_AP_OK && 438 krb_kntoln(&kauth, lnam) == KSUCCESS && 439 (pwd = getpwnam(lnam)) != NULL) { 440 cr = &nsd.nsd_cr; 441 cr->cr_uid = pwd->pw_uid; 442 cr->cr_groups[0] = pwd->pw_gid; 443 cr->cr_ngroups = 1; 444 setgrent(); 445 while ((grp = getgrent()) != NULL) { 446 if (grp->gr_gid == cr->cr_groups[0]) 447 continue; 448 for (cpp = grp->gr_mem; 449 *cpp != NULL; ++cpp) 450 if (!strcmp(*cpp, lnam)) 451 break; 452 if (*cpp == NULL) 453 continue; 454 cr->cr_groups[cr->cr_ngroups++] 455 = grp->gr_gid; 456 if (cr->cr_ngroups == NGROUPS) 457 break; 458 } 459 endgrent(); 460 461 /* 462 * Get the timestamp verifier out of the 463 * authenticator and verifier strings. 464 */ 465 kin.t1 = kverf.t1; 466 kin.t2 = kverf.t2; 467 kin.w2 = kverf.w2; 468 bzero((caddr_t)kivec, sizeof (kivec)); 469 bcopy((caddr_t)kauth.session, 470 (caddr_t)nsd.nsd_key,sizeof(kauth.session)); 471 472 /* 473 * Decrypt the timestamp verifier in CBC mode. 474 */ 475 XXX 476 477 /* 478 * Validate the timestamp verifier, to 479 * check that the session key is ok. 480 */ 481 nsd.nsd_timestamp.tv_sec = ntohl(kout.t1); 482 nsd.nsd_timestamp.tv_usec = ntohl(kout.t2); 483 nsd.nsd_ttl = ntohl(kout.w1); 484 if ((nsd.nsd_ttl - 1) == ntohl(kout.w2)) 485 nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN; 486 } 487#endif /* NFSKERB */ 488 } 489 exit(0); 490 } 491
|
402 /* If we are serving udp, set up the socket. */ 403 for (i = 0; udpflag && i < bindhostc; i++) { 404 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 405 syslog(LOG_ERR, "can't create udp socket"); 406 exit(1);
| 492 if (atexit(killchildren) == -1) { 493 syslog(LOG_ERR, "atexit: %s", strerror(errno)); 494 exit(1); 495 } 496 FD_ZERO(&v4bits); 497 FD_ZERO(&v6bits); 498 499 rpcbregcnt = 0; 500 /* Set up the socket for udp and rpcb register it. */ 501 if (udpflag) { 502 rpcbreg = 0; 503 for (i = 0; i < bindhostc; i++) { 504 memset(&hints, 0, sizeof hints); 505 hints.ai_flags = AI_PASSIVE; 506 hints.ai_family = AF_INET; 507 hints.ai_socktype = SOCK_DGRAM; 508 hints.ai_protocol = IPPROTO_UDP; 509 if (setbindhost(&ai_udp, bindhost[i], hints) == 0) { 510 rpcbreg = 1; 511 rpcbregcnt++; 512 if ((sock = socket(ai_udp->ai_family, 513 ai_udp->ai_socktype, 514 ai_udp->ai_protocol)) < 0) { 515 syslog(LOG_ERR, 516 "can't create udp socket"); 517 exit(1); 518 } 519 if (bind(sock, ai_udp->ai_addr, 520 ai_udp->ai_addrlen) < 0) { 521 syslog(LOG_ERR, 522 "can't bind udp addr %s: %m", 523 bindhost[i]); 524 exit(1); 525 } 526 freeaddrinfo(ai_udp); 527 nfsdargs.sock = sock; 528 nfsdargs.name = NULL; 529 nfsdargs.namelen = 0; 530 if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) { 531 syslog(LOG_ERR, "can't Add UDP socket"); 532 exit(1); 533 } 534 (void)close(sock); 535 }
|
407 }
| 536 }
|
408 setbindhost(&inetaddr, bindhost[i]); 409 if (bind(sock, 410 (struct sockaddr *)&inetaddr, sizeof(inetaddr)) < 0) { 411 syslog(LOG_ERR, "can't bind udp addr %s: %m", bindhost[i]); 412 exit(1);
| 537 if (rpcbreg == 1) { 538 memset(&hints, 0, sizeof hints); 539 hints.ai_flags = AI_PASSIVE; 540 hints.ai_family = AF_INET; 541 hints.ai_socktype = SOCK_DGRAM; 542 hints.ai_protocol = IPPROTO_UDP; 543 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp); 544 if (ecode != 0) { 545 syslog(LOG_ERR, "getaddrinfo udp: %s", 546 gai_strerror(ecode)); 547 exit(1); 548 } 549 nconf_udp = getnetconfigent("udp"); 550 if (nconf_udp == NULL) 551 err(1, "getnetconfigent udp failed"); 552 nb_udp.buf = ai_udp->ai_addr; 553 nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen; 554 if ((!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp)) || 555 (!rpcb_set(RPCPROG_NFS, 3, nconf_udp, &nb_udp))) 556 err(1, "rpcb_set udp failed"); 557 freeaddrinfo(ai_udp);
|
413 }
| 558 }
|
414 if (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) || 415 !pmap_set(RPCPROG_NFS, 3, IPPROTO_UDP, NFS_PORT)) { 416 syslog(LOG_ERR, "can't register with udp portmap"); 417 exit(1); 418 } 419 nfsdargs.sock = sock; 420 nfsdargs.name = NULL; 421 nfsdargs.namelen = 0; 422 if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) { 423 syslog(LOG_ERR, "can't Add UDP socket"); 424 exit(1); 425 } 426 (void)close(sock);
| |
427 } 428
| 559 } 560
|
429#ifdef ISO 430 /* If we are serving cltp, set up the socket. */ 431 if (cltpflag) { 432 if ((sock = socket(AF_ISO, SOCK_DGRAM, 0)) < 0) { 433 syslog(LOG_ERR, "can't create cltp socket"); 434 exit(1);
| 561 /* Set up the socket for udp6 and rpcb register it. */ 562 if (udpflag && ip6flag) { 563 rpcbreg = 0; 564 for (i = 0; i < bindhostc; i++) { 565 memset(&hints, 0, sizeof hints); 566 hints.ai_flags = AI_PASSIVE; 567 hints.ai_family = AF_INET6; 568 hints.ai_socktype = SOCK_DGRAM; 569 hints.ai_protocol = IPPROTO_UDP; 570 if (setbindhost(&ai_udp6, bindhost[i], hints) == 0) { 571 rpcbreg = 1; 572 rpcbregcnt++; 573 if ((sock = socket(ai_udp6->ai_family, 574 ai_udp6->ai_socktype, 575 ai_udp6->ai_protocol)) < 0) { 576 syslog(LOG_ERR, 577 "can't create udp6 socket"); 578 exit(1); 579 } 580 if (setsockopt(sock, IPPROTO_IPV6, 581 IPV6_BINDV6ONLY, 582 &on, sizeof on) < 0) { 583 syslog(LOG_ERR, 584 "can't set v6-only binding for " 585 "udp6 socket: %m"); 586 exit(1); 587 } 588 if (bind(sock, ai_udp6->ai_addr, 589 ai_udp6->ai_addrlen) < 0) { 590 syslog(LOG_ERR, 591 "can't bind udp6 addr %s: %m", 592 bindhost[i]); 593 exit(1); 594 } 595 freeaddrinfo(ai_udp6); 596 nfsdargs.sock = sock; 597 nfsdargs.name = NULL; 598 nfsdargs.namelen = 0; 599 if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) { 600 syslog(LOG_ERR, 601 "can't add UDP6 socket"); 602 exit(1); 603 } 604 (void)close(sock); 605 }
|
435 }
| 606 }
|
436 memset(&isoaddr, 0, sizeof(isoaddr)); 437 isoaddr.siso_family = AF_ISO; 438 isoaddr.siso_tlen = 2; 439 cp = TSEL(&isoaddr); 440 *cp++ = (NFS_PORT >> 8); 441 *cp = (NFS_PORT & 0xff); 442 isoaddr.siso_len = sizeof(isoaddr); 443 if (bind(sock, 444 (struct sockaddr *)&isoaddr, sizeof(isoaddr)) < 0) { 445 syslog(LOG_ERR, "can't bind cltp addr"); 446 exit(1);
| 607 if (rpcbreg == 1) { 608 memset(&hints, 0, sizeof hints); 609 hints.ai_flags = AI_PASSIVE; 610 hints.ai_family = AF_INET6; 611 hints.ai_socktype = SOCK_DGRAM; 612 hints.ai_protocol = IPPROTO_UDP; 613 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6); 614 if (ecode != 0) { 615 syslog(LOG_ERR, "getaddrinfo udp6: %s", 616 gai_strerror(ecode)); 617 exit(1); 618 } 619 nconf_udp6 = getnetconfigent("udp6"); 620 if (nconf_udp6 == NULL) 621 err(1, "getnetconfigent udp6 failed"); 622 nb_udp6.buf = ai_udp6->ai_addr; 623 nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen; 624 if ((!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6)) || 625 (!rpcb_set(RPCPROG_NFS, 3, nconf_udp6, &nb_udp6))) 626 err(1, "rpcb_set udp6 failed"); 627 freeaddrinfo(ai_udp6);
|
447 }
| 628 }
|
448#ifdef notyet 449 /* 450 * XXX 451 * Someday this should probably use "rpcbind", the son of 452 * portmap. 453 */ 454 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) { 455 syslog(LOG_ERR, "can't register with udp portmap"); 456 exit(1); 457 } 458#endif /* notyet */ 459 nfsdargs.sock = sock; 460 nfsdargs.name = NULL; 461 nfsdargs.namelen = 0; 462 if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) { 463 syslog(LOG_ERR, "can't add UDP socket"); 464 exit(1); 465 } 466 close(sock);
| |
467 }
| 629 }
|
468#endif /* ISO */
| |
469
| 630
|
470 /* Now set up the master server socket waiting for tcp connections. */ 471 on = 1; 472 FD_ZERO(&sockbits); 473 connect_type_cnt = 0; 474 for (i = 0; tcpflag && i < bindhostc; i++) { 475 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 476 syslog(LOG_ERR, "can't create tcp socket"); 477 exit(1);
| 631 /* Set up the socket for tcp and rpcb register it. */ 632 if (tcpflag) { 633 rpcbreg = 0; 634 for (i = 0; i < bindhostc; i++) { 635 memset(&hints, 0, sizeof hints); 636 hints.ai_flags = AI_PASSIVE; 637 hints.ai_family = AF_INET; 638 hints.ai_socktype = SOCK_STREAM; 639 hints.ai_protocol = IPPROTO_TCP; 640 if (setbindhost(&ai_tcp, bindhost[i], hints) == 0) { 641 rpcbreg = 1; 642 rpcbregcnt++; 643 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 644 0)) < 0) { 645 syslog(LOG_ERR, 646 "can't create tpc socket"); 647 exit(1); 648 } 649 if (setsockopt(tcpsock, SOL_SOCKET, 650 SO_REUSEADDR, 651 (char *)&on, sizeof(on)) < 0) 652 syslog(LOG_ERR, 653 "setsockopt SO_REUSEADDR: %m"); 654 if (bind(tcpsock, ai_tcp->ai_addr, 655 ai_tcp->ai_addrlen) < 0) { 656 syslog(LOG_ERR, 657 "can't bind tcp addr %s: %m", 658 bindhost[i]); 659 exit(1); 660 } 661 if (listen(tcpsock, 5) < 0) { 662 syslog(LOG_ERR, "listen failed"); 663 exit(1); 664 } 665 freeaddrinfo(ai_tcp); 666 FD_SET(tcpsock, &sockbits); 667 FD_SET(tcpsock, &v4bits); 668 maxsock = tcpsock; 669 connect_type_cnt++; 670 }
|
478 }
| 671 }
|
479 if (setsockopt(tcpsock, 480 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 481 syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 482 setbindhost(&inetaddr, bindhost[i]); 483 if (bind(tcpsock, 484 (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) { 485 syslog(LOG_ERR, "can't bind tcp addr %s: %m", bindhost[i]); 486 exit(1);
| 672 if (rpcbreg == 1) { 673 memset(&hints, 0, sizeof hints); 674 hints.ai_flags = AI_PASSIVE; 675 hints.ai_family = AF_INET; 676 hints.ai_socktype = SOCK_STREAM; 677 hints.ai_protocol = IPPROTO_TCP; 678 ecode = getaddrinfo(NULL, "nfs", &hints, 679 &ai_tcp); 680 if (ecode != 0) { 681 syslog(LOG_ERR, "getaddrinfo tcp: %s", 682 gai_strerror(ecode)); 683 exit(1); 684 } 685 nconf_tcp = getnetconfigent("tcp"); 686 if (nconf_tcp == NULL) 687 err(1, "getnetconfigent tcp failed"); 688 nb_tcp.buf = ai_tcp->ai_addr; 689 nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen; 690 if ((!rpcb_set(RPCPROG_NFS, 2, nconf_tcp, 691 &nb_tcp)) || (!rpcb_set(RPCPROG_NFS, 3, 692 nconf_tcp, &nb_tcp))) 693 err(1, "rpcb_set tcp failed"); 694 freeaddrinfo(ai_tcp);
|
487 }
| 695 }
|
488 if (listen(tcpsock, 5) < 0) { 489 syslog(LOG_ERR, "listen failed"); 490 exit(1); 491 } 492 if (!pmap_set(RPCPROG_NFS, 2, IPPROTO_TCP, NFS_PORT) || 493 !pmap_set(RPCPROG_NFS, 3, IPPROTO_TCP, NFS_PORT)) { 494 syslog(LOG_ERR, "can't register tcp with portmap"); 495 exit(1); 496 } 497 FD_SET(tcpsock, &sockbits); 498 maxsock = tcpsock; 499 connect_type_cnt++;
| |
500 } 501
| 696 } 697
|
502#ifdef notyet 503 /* Now set up the master server socket waiting for tp4 connections. */ 504 if (tp4flag) { 505 if ((tp4sock = socket(AF_ISO, SOCK_SEQPACKET, 0)) < 0) { 506 syslog(LOG_ERR, "can't create tp4 socket"); 507 exit(1);
| 698 /* Set up the socket for tcp6 and rpcb register it. */ 699 if (tcpflag && ip6flag) { 700 rpcbreg = 0; 701 for (i = 0; i < bindhostc; i++) { 702 memset(&hints, 0, sizeof hints); 703 hints.ai_flags = AI_PASSIVE; 704 hints.ai_family = AF_INET6; 705 hints.ai_socktype = SOCK_STREAM; 706 hints.ai_protocol = IPPROTO_TCP; 707 if (setbindhost(&ai_tcp6, bindhost[i], hints) == 0) { 708 rpcbreg = 1; 709 rpcbregcnt++; 710 if ((tcp6sock = socket(ai_tcp6->ai_family, 711 ai_tcp6->ai_socktype, 712 ai_tcp6->ai_protocol)) < 0) { 713 syslog(LOG_ERR, 714 "can't create tcp6 socket"); 715 exit(1); 716 } 717 if (setsockopt(tcp6sock, SOL_SOCKET, 718 SO_REUSEADDR, 719 (char *)&on, sizeof(on)) < 0) 720 syslog(LOG_ERR, 721 "setsockopt SO_REUSEADDR: %m"); 722 if (setsockopt(tcp6sock, IPPROTO_IPV6, 723 IPV6_BINDV6ONLY, &on, sizeof on) < 0) { 724 syslog(LOG_ERR, 725 "can't set v6-only binding for tcp6 " 726 "socket: %m"); 727 exit(1); 728 } 729 if (bind(tcp6sock, ai_tcp6->ai_addr, 730 ai_tcp6->ai_addrlen) < 0) { 731 syslog(LOG_ERR, 732 "can't bind tcp6 addr %s: %m", 733 bindhost[i]); 734 exit(1); 735 } 736 if (listen(tcp6sock, 5) < 0) { 737 syslog(LOG_ERR, "listen failed"); 738 exit(1); 739 } 740 freeaddrinfo(ai_tcp6); 741 FD_SET(tcp6sock, &sockbits); 742 FD_SET(tcp6sock, &v6bits); 743 if (maxsock < tcp6sock) 744 maxsock = tcp6sock; 745 connect_type_cnt++; 746 }
|
508 }
| 747 }
|
509 if (setsockopt(tp4sock, 510 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 511 syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 512 memset(&isoaddr, 0, sizeof(isoaddr)); 513 isoaddr.siso_family = AF_ISO; 514 isoaddr.siso_tlen = 2; 515 cp = TSEL(&isoaddr); 516 *cp++ = (NFS_PORT >> 8); 517 *cp = (NFS_PORT & 0xff); 518 isoaddr.siso_len = sizeof(isoaddr); 519 if (bind(tp4sock, 520 (struct sockaddr *)&isoaddr, sizeof (isoaddr)) < 0) { 521 syslog(LOG_ERR, "can't bind tp4 addr"); 522 exit(1);
| 748 if (rpcbreg == 1) { 749 memset(&hints, 0, sizeof hints); 750 hints.ai_flags = AI_PASSIVE; 751 hints.ai_family = AF_INET6; 752 hints.ai_socktype = SOCK_STREAM; 753 hints.ai_protocol = IPPROTO_TCP; 754 ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6); 755 if (ecode != 0) { 756 syslog(LOG_ERR, "getaddrinfo tcp6: %s", 757 gai_strerror(ecode)); 758 exit(1); 759 } 760 nconf_tcp6 = getnetconfigent("tcp6"); 761 if (nconf_tcp6 == NULL) 762 err(1, "getnetconfigent tcp6 failed"); 763 nb_tcp6.buf = ai_tcp6->ai_addr; 764 nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen; 765 if ((!rpcb_set(RPCPROG_NFS, 2, nconf_tcp6, &nb_tcp6)) || 766 (!rpcb_set(RPCPROG_NFS, 3, nconf_tcp6, &nb_tcp6))) 767 err(1, "rpcb_set tcp6 failed"); 768 freeaddrinfo(ai_tcp6);
|
523 }
| 769 }
|
524 if (listen(tp4sock, 5) < 0) { 525 syslog(LOG_ERR, "listen failed"); 526 exit(1); 527 } 528 /* 529 * XXX 530 * Someday this should probably use "rpcbind", the son of 531 * portmap. 532 */ 533 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 534 syslog(LOG_ERR, "can't register tcp with portmap"); 535 exit(1); 536 } 537 FD_SET(tp4sock, &sockbits); 538 maxsock = tp4sock; 539 connect_type_cnt++;
| |
540 } 541
| 770 } 771
|
542 /* Now set up the master server socket waiting for tpip connections. */ 543 for (i = 0; tpipflag && i < bindhostc; i++) { 544 if ((tpipsock = socket(AF_INET, SOCK_SEQPACKET, 0)) < 0) { 545 syslog(LOG_ERR, "can't create tpip socket"); 546 exit(1); 547 } 548 if (setsockopt(tpipsock, 549 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 550 syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 551 setbindhost(&inetaddr, bindhost[i]); 552 if (bind(tpipsock, 553 (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) { 554 syslog(LOG_ERR, "can't bind tcp addr %s: %m", bindhost[i]); 555 exit(1); 556 } 557 if (listen(tpipsock, 5) < 0) { 558 syslog(LOG_ERR, "listen failed"); 559 exit(1); 560 } 561 /* 562 * XXX 563 * Someday this should probably use "rpcbind", the son of 564 * portmap. 565 */ 566 if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 567 syslog(LOG_ERR, "can't register tcp with portmap"); 568 exit(1); 569 } 570 FD_SET(tpipsock, &sockbits); 571 maxsock = tpipsock; 572 connect_type_cnt++;
| 772 if (rpcbregcnt == 0) { 773 syslog(LOG_ERR, "rpcb_set() failed, nothing to do: %m"); 774 exit(1);
|
573 }
| 775 }
|
574#endif /* notyet */
| |
575
| 776
|
576 if (connect_type_cnt == 0) 577 exit(0);
| 777 if ((tcpflag) && (connect_type_cnt == 0)) { 778 syslog(LOG_ERR, "tcp connects == 0, nothing to do: %m"); 779 exit(1); 780 }
|
578 579 setproctitle("master"); 580 581 /* 582 * Loop forever accepting connections and passing the sockets 583 * into the kernel for the mounts. 584 */ 585 for (;;) { 586 ready = sockbits; 587 if (connect_type_cnt > 1) { 588 if (select(maxsock + 1, 589 &ready, NULL, NULL, NULL) < 1) { 590 syslog(LOG_ERR, "select failed: %m"); 591 exit(1); 592 } 593 }
| 781 782 setproctitle("master"); 783 784 /* 785 * Loop forever accepting connections and passing the sockets 786 * into the kernel for the mounts. 787 */ 788 for (;;) { 789 ready = sockbits; 790 if (connect_type_cnt > 1) { 791 if (select(maxsock + 1, 792 &ready, NULL, NULL, NULL) < 1) { 793 syslog(LOG_ERR, "select failed: %m"); 794 exit(1); 795 } 796 }
|
594 if (tcpflag && FD_ISSET(tcpsock, &ready)) { 595 len = sizeof(inetpeer); 596 if ((msgsock = accept(tcpsock, 597 (struct sockaddr *)&inetpeer, &len)) < 0) { 598 syslog(LOG_ERR, "accept failed: %m"); 599 exit(1);
| 797 for (tcpsock = 0; tcpsock <= maxsock; tcpsock++) { 798 if (FD_ISSET(tcpsock, &ready)) { 799 if (FD_ISSET(tcpsock, &v4bits)) { 800 len = sizeof(inetpeer); 801 if ((msgsock = accept(tcpsock, 802 (struct sockaddr *)&inetpeer, &len)) < 0) { 803 syslog(LOG_ERR, "accept failed: %m"); 804 exit(1); 805 } 806 memset(inetpeer.sin_zero, 0, 807 sizeof(inetpeer.sin_zero)); 808 if (setsockopt(msgsock, SOL_SOCKET, 809 SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 810 syslog(LOG_ERR, 811 "setsockopt SO_KEEPALIVE: %m"); 812 nfsdargs.sock = msgsock; 813 nfsdargs.name = (caddr_t)&inetpeer; 814 nfsdargs.namelen = sizeof(inetpeer); 815 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 816 (void)close(msgsock); 817 } else if (FD_ISSET(tcpsock, &v6bits)) { 818 len = sizeof(inet6peer); 819 if ((msgsock = accept(tcpsock, 820 (struct sockaddr *)&inet6peer, 821 &len)) < 0) { 822 syslog(LOG_ERR, 823 "accept failed: %m"); 824 exit(1); 825 } 826 if (setsockopt(msgsock, SOL_SOCKET, 827 SO_KEEPALIVE, (char *)&on, 828 sizeof(on)) < 0) 829 syslog(LOG_ERR, "setsockopt " 830 "SO_KEEPALIVE: %m"); 831 nfsdargs.sock = msgsock; 832 nfsdargs.name = (caddr_t)&inet6peer; 833 nfsdargs.namelen = sizeof(inet6peer); 834 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 835 (void)close(msgsock); 836 }
|
600 }
| 837 }
|
601 memset(inetpeer.sin_zero, 0, sizeof(inetpeer.sin_zero)); 602 if (setsockopt(msgsock, SOL_SOCKET, 603 SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 604 syslog(LOG_ERR, 605 "setsockopt SO_KEEPALIVE: %m"); 606 nfsdargs.sock = msgsock; 607 nfsdargs.name = (caddr_t)&inetpeer; 608 nfsdargs.namelen = sizeof(inetpeer); 609 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 610 (void)close(msgsock);
| |
611 }
| 838 }
|
612#ifdef notyet 613 if (tp4flag && FD_ISSET(tp4sock, &ready)) { 614 len = sizeof(isopeer); 615 if ((msgsock = accept(tp4sock, 616 (struct sockaddr *)&isopeer, &len)) < 0) { 617 syslog(LOG_ERR, "accept failed: %m"); 618 exit(1); 619 } 620 if (setsockopt(msgsock, SOL_SOCKET, 621 SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 622 syslog(LOG_ERR, 623 "setsockopt SO_KEEPALIVE: %m"); 624 nfsdargs.sock = msgsock; 625 nfsdargs.name = (caddr_t)&isopeer; 626 nfsdargs.namelen = len; 627 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 628 (void)close(msgsock); 629 } 630 if (tpipflag && FD_ISSET(tpipsock, &ready)) { 631 len = sizeof(inetpeer); 632 if ((msgsock = accept(tpipsock, 633 (struct sockaddr *)&inetpeer, &len)) < 0) { 634 syslog(LOG_ERR, "accept failed: %m"); 635 exit(1); 636 } 637 if (setsockopt(msgsock, SOL_SOCKET, 638 SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 639 syslog(LOG_ERR, "setsockopt SO_KEEPALIVE: %m"); 640 nfsdargs.sock = msgsock; 641 nfsdargs.name = (caddr_t)&inetpeer; 642 nfsdargs.namelen = len; 643 nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 644 (void)close(msgsock); 645 } 646#endif /* notyet */
| |
647 } 648} 649
| 839 } 840} 841
|
650void 651setbindhost(struct sockaddr_in *ia, const char *bindhost)
| 842int 843setbindhost(struct addrinfo **ai, const char *bindhost, struct addrinfo hints)
|
652{
| 844{
|
653 ia->sin_family = AF_INET; 654 ia->sin_port = htons(NFS_PORT); 655 ia->sin_len = sizeof(*ia); 656 if (bindhost == NULL || strcmp(bindhost,"*") == 0) { 657 ia->sin_addr.s_addr = INADDR_ANY; 658 } else { 659 if (inet_aton(bindhost, &ia->sin_addr) == 0) { 660 struct hostent *he;
| 845 int ecode; 846 u_int32_t host_addr[4]; /* IPv4 or IPv6 */ 847 const char *hostptr;
|
661
| 848
|
662 he = gethostbyname2(bindhost, ia->sin_family); 663 if (he == NULL) { 664 syslog(LOG_ERR, "gethostbyname of %s failed", bindhost); 665 exit(1);
| 849 if (bindhost == NULL || strcmp("*", bindhost) == 0) 850 hostptr = NULL; 851 else 852 hostptr = bindhost; 853 854 if (hostptr != NULL) { 855 switch (hints.ai_family) { 856 case AF_INET: 857 if (inet_pton(AF_INET, hostptr, host_addr) == 1) { 858 hints.ai_flags = AI_NUMERICHOST; 859 } else { 860 if (inet_pton(AF_INET6, hostptr, 861 host_addr) == 1) 862 return (1);
|
666 }
| 863 }
|
667 bcopy(he->h_addr, &ia->sin_addr, he->h_length);
| 864 break; 865 case AF_INET6: 866 if (inet_pton(AF_INET6, hostptr, host_addr) == 1) { 867 hints.ai_flags = AI_NUMERICHOST; 868 } else { 869 if (inet_pton(AF_INET, hostptr, 870 host_addr) == 1) 871 return (1); 872 } 873 break; 874 default:
|
668 } 669 }
| 875 } 876 }
|
| 877 878 ecode = getaddrinfo(hostptr, "nfs", &hints, ai); 879 if (ecode != 0) { 880 syslog(LOG_ERR, "getaddrinfo %s: %s", bindhost, 881 gai_strerror(ecode)); 882 return (1); 883 } 884 return (0);
|
670} 671 672void 673usage() 674{ 675 (void)fprintf(stderr, "usage: nfsd %s\n", USAGE); 676 exit(1); 677} 678 679void 680nonfs(signo) 681 int signo; 682{ 683 syslog(LOG_ERR, "missing system call: NFS not available"); 684} 685 686void 687reapchild(signo) 688 int signo; 689{ 690 691 while (wait3(NULL, WNOHANG, NULL) > 0); 692} 693
| 885} 886 887void 888usage() 889{ 890 (void)fprintf(stderr, "usage: nfsd %s\n", USAGE); 891 exit(1); 892} 893 894void 895nonfs(signo) 896 int signo; 897{ 898 syslog(LOG_ERR, "missing system call: NFS not available"); 899} 900 901void 902reapchild(signo) 903 int signo; 904{ 905 906 while (wait3(NULL, WNOHANG, NULL) > 0); 907} 908
|
| 909void 910unregistration() 911{ 912 if ((!rpcb_unset(RPCPROG_NFS, 2, NULL)) || 913 (!rpcb_unset(RPCPROG_NFS, 3, NULL))) 914 syslog(LOG_ERR, "rpcb_unset failed"); 915} 916 917void 918killchildren() 919{ 920 int i; 921 sigset_t sigs; 922 923 sigemptyset(&sigs); 924 /* 925 * Block SIGCHLD to avoid killing a reaped process (although it is 926 * unlikely, the pid might have been reused). 927 */ 928 sigaddset(&sigs, SIGCHLD); 929 if (sigprocmask(SIG_BLOCK, &sigs, NULL) == -1) { 930 syslog(LOG_ERR, "sigprocmask: %s", 931 strerror(errno)); 932 return; 933 } 934 for (i = 0; i < nfsdcnt; i++) { 935 if (children[i] > 0) 936 kill(children[i], SIGKILL); 937 } 938 if (sigprocmask(SIG_UNBLOCK, &sigs, NULL) == -1) { 939 syslog(LOG_ERR, "sigprocmask: %s", strerror(errno)); 940 } 941 unregistration(); 942} 943 944void 945cleanup(signo) 946{ 947 killchildren(); 948 exit (0); 949} 950
|
694#ifdef OLD_SETPROCTITLE 695#ifdef __FreeBSD__ 696void 697setproctitle(a) 698 char *a; 699{ 700 register char *cp; 701 char buf[80]; 702 703 cp = Argv[0]; 704 (void)snprintf(buf, sizeof(buf), "nfsd-%s", a); 705 (void)strncpy(cp, buf, LastArg - cp); 706 cp += strlen(cp); 707 while (cp < LastArg) 708 *cp++ = '\0'; 709 Argv[1] = NULL; 710} 711#endif /* __FreeBSD__ */ 712#endif
| 951#ifdef OLD_SETPROCTITLE 952#ifdef __FreeBSD__ 953void 954setproctitle(a) 955 char *a; 956{ 957 register char *cp; 958 char buf[80]; 959 960 cp = Argv[0]; 961 (void)snprintf(buf, sizeof(buf), "nfsd-%s", a); 962 (void)strncpy(cp, buf, LastArg - cp); 963 cp += strlen(cp); 964 while (cp < LastArg) 965 *cp++ = '\0'; 966 Argv[1] = NULL; 967} 968#endif /* __FreeBSD__ */ 969#endif
|