xref: /titanic_44/usr/src/cmd/smbsrv/bind-helper/bind-helper.c (revision b819cea2f73f98c5662230cc9affc8cc84f77fcf)
1*b819cea2SGordon Ross /*
2*b819cea2SGordon Ross  * This file and its contents are supplied under the terms of the
3*b819cea2SGordon Ross  * Common Development and Distribution License ("CDDL"), version 1.0.
4*b819cea2SGordon Ross  * You may only use this file in accordance with the terms of version
5*b819cea2SGordon Ross  * 1.0 of the CDDL.
6*b819cea2SGordon Ross  *
7*b819cea2SGordon Ross  * A full copy of the text of the CDDL should have accompanied this
8*b819cea2SGordon Ross  * source.  A copy of the CDDL is also available via the Internet at
9*b819cea2SGordon Ross  * http://www.illumos.org/license/CDDL.
10*b819cea2SGordon Ross  */
11*b819cea2SGordon Ross 
12*b819cea2SGordon Ross /*
13*b819cea2SGordon Ross  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
14*b819cea2SGordon Ross  */
15*b819cea2SGordon Ross 
16*b819cea2SGordon Ross /*
17*b819cea2SGordon Ross  * This program is installed with an RBAC exec_attr
18*b819cea2SGordon Ross  * that allows it to bind a reserved address.
19*b819cea2SGordon Ross  * (Or just make it setuid root.)
20*b819cea2SGordon Ross  *
21*b819cea2SGordon Ross  * To grant privileges to the program using RBAC,
22*b819cea2SGordon Ross  * add the following line to /etc/security/exec_attr
23*b819cea2SGordon Ross  *	Forced Privilege:solaris:cmd:::\
24*b819cea2SGordon Ross  *	/usr/lib/smbsrv/bind-helper:\
25*b819cea2SGordon Ross  *	privs=net_privaddr,sys_smb\
26*b819cea2SGordon Ross  *
27*b819cea2SGordon Ross  * Args: family address port
28*b819cea2SGordon Ross  * Does a bind on fileno(stdin)
29*b819cea2SGordon Ross  */
30*b819cea2SGordon Ross 
31*b819cea2SGordon Ross #include <stdio.h>
32*b819cea2SGordon Ross #include <stdlib.h>
33*b819cea2SGordon Ross #include <unistd.h>
34*b819cea2SGordon Ross #include <string.h>
35*b819cea2SGordon Ross #include <errno.h>
36*b819cea2SGordon Ross #include <sys/types.h>
37*b819cea2SGordon Ross #include <sys/socket.h>
38*b819cea2SGordon Ross #include <netinet/in.h>
39*b819cea2SGordon Ross #include <arpa/inet.h>
40*b819cea2SGordon Ross 
41*b819cea2SGordon Ross int
main(int argc,char ** argv)42*b819cea2SGordon Ross main(int argc, char **argv)
43*b819cea2SGordon Ross {
44*b819cea2SGordon Ross 	struct sockaddr sa;
45*b819cea2SGordon Ross 	/* LINTED E_BAD_PTR_CAST_ALIGN */
46*b819cea2SGordon Ross 	struct sockaddr_in  *sin  = (struct sockaddr_in *)&sa;
47*b819cea2SGordon Ross 	/* LINTED E_BAD_PTR_CAST_ALIGN */
48*b819cea2SGordon Ross 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
49*b819cea2SGordon Ross 	int rc, err = 0;
50*b819cea2SGordon Ross 
51*b819cea2SGordon Ross 	if (argc < 4) {
52*b819cea2SGordon Ross 		(void) fprintf(stderr, "usage: %s family address port\n",
53*b819cea2SGordon Ross 		    argv[0]);
54*b819cea2SGordon Ross 		exit(1);
55*b819cea2SGordon Ross 	}
56*b819cea2SGordon Ross 
57*b819cea2SGordon Ross 	(void) memset(&sa, 0, sizeof (sa));
58*b819cea2SGordon Ross 	sa.sa_family = atoi(argv[1]);
59*b819cea2SGordon Ross 	switch (sa.sa_family) {
60*b819cea2SGordon Ross 	case AF_INET:
61*b819cea2SGordon Ross 		rc = inet_pton(AF_INET, argv[2], &sin->sin_addr);
62*b819cea2SGordon Ross 		sin->sin_port = htons(atoi(argv[3]));
63*b819cea2SGordon Ross 		break;
64*b819cea2SGordon Ross 	case AF_INET6:
65*b819cea2SGordon Ross 		rc = inet_pton(AF_INET6, argv[2], &sin6->sin6_addr);
66*b819cea2SGordon Ross 		sin6->sin6_port = htons(atoi(argv[3]));
67*b819cea2SGordon Ross 		break;
68*b819cea2SGordon Ross 	default:
69*b819cea2SGordon Ross 		rc = 0;
70*b819cea2SGordon Ross 		break;
71*b819cea2SGordon Ross 	}
72*b819cea2SGordon Ross 
73*b819cea2SGordon Ross 	if (rc > 0)
74*b819cea2SGordon Ross 		err = 0;
75*b819cea2SGordon Ross 	else if (rc == 0)
76*b819cea2SGordon Ross 		err = EINVAL;
77*b819cea2SGordon Ross 	else if (rc < 0)
78*b819cea2SGordon Ross 		err = errno;
79*b819cea2SGordon Ross 	if (err != 0) {
80*b819cea2SGordon Ross 		(void) fprintf(stderr, "%s: bad proto addr %s %s %s\n",
81*b819cea2SGordon Ross 		    argv[0], argv[1], argv[2], argv[3]);
82*b819cea2SGordon Ross 		exit(1);
83*b819cea2SGordon Ross 	}
84*b819cea2SGordon Ross 
85*b819cea2SGordon Ross 	if (bind(0, &sa, sizeof (sa)) < 0) {
86*b819cea2SGordon Ross 		err = errno;
87*b819cea2SGordon Ross 		(void) fprintf(stderr, "%s: bind: %s\n",
88*b819cea2SGordon Ross 		    argv[0], strerror(err));
89*b819cea2SGordon Ross 		exit(2);
90*b819cea2SGordon Ross 	}
91*b819cea2SGordon Ross 	exit(0);
92*b819cea2SGordon Ross }
93