• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *   Copyright (c) International Business Machines  Corp., 2004
4  *
5  *   This program is free software;  you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  *   the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program;  if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 /*
21  * Test Name: bind02
22  *
23  * Test Description:
24  *  Make sure bind() gives EACCESS error for (non-root) users.
25  *
26  * Usage:  <for command-line>
27  *  bind01 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
28  *     where,  -c n : Run n copies concurrently.
29  *             -e   : Turn on errno logging.
30  *             -i n : Execute test n times.
31  *             -I x : Execute test for x seconds.
32  *             -P x : Pause for x seconds between iterations.
33  *             -t   : Turn on syscall timing.
34  *
35  * HISTORY
36  *      07/2004 Written by Dan Jones
37  *      07/2004 Ported to LTP format by Robbie Williamson
38  *
39  * RESTRICTIONS:
40  *  None.
41  *
42  */
43 
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <errno.h>
48 #include <fcntl.h>
49 #include <pwd.h>
50 #include <grp.h>
51 
52 #include <sys/types.h>
53 #include <sys/socket.h>
54 #include <sys/un.h>
55 
56 #include <netinet/in.h>
57 
58 #include "test.h"
59 
60 char *TCID = "bind02";
61 int testno;
62 int TST_TOTAL = 1;
63 
64 /* This port needs to be a Privledged port */
65 #define TCP_PRIVLEGED_COM_PORT 463
66 
67 struct passwd *pw;
68 struct group *gr;
69 
70 uid_t uid;
71 gid_t gid;
72 
73 int rc;
74 
try_bind(void)75 void try_bind(void)
76 {
77 	struct sockaddr_in servaddr;
78 	int sockfd, r_value;
79 
80 	// Set effective user/group
81 	if ((rc = setegid(gid)) == -1) {
82 		tst_brkm(TBROK | TERRNO, 0, "setegid(%u) failed", gid);
83 	}
84 	if ((rc = seteuid(uid)) == -1) {
85 		tst_brkm(TBROK | TERRNO, 0, "seteuid(%u) failed", uid);
86 	}
87 
88 	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
89 		tst_brkm(TBROK | TERRNO, 0, "socket() failed");
90 	}
91 
92 	memset(&servaddr, 0, sizeof(servaddr));
93 	servaddr.sin_family = AF_INET;
94 	servaddr.sin_port = htons(TCP_PRIVLEGED_COM_PORT);
95 	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
96 	r_value = bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
97 	if (r_value) {
98 		if (errno == EACCES) {
99 			tst_resm(TPASS, "correct error");
100 		} else {
101 			tst_resm(TFAIL, "incorrect error, %d", r_value);
102 		}
103 	} else {
104 		tst_resm(TFAIL, "user was able to bind successfully");
105 	}
106 
107 	close(sockfd);
108 
109 	// Set effective user/group
110 	if ((rc = setegid(0)) == -1) {
111 		tst_brkm(TBROK | TERRNO, 0, "setegid(0) reset failed");
112 	}
113 	if ((rc = seteuid(uid)) == -1) {
114 		/* XXX: is this seteuid() correct !?  it isnt a reset if we
115 		 *      made the same exact call above ...
116 		 */
117 		tst_brkm(TBROK | TERRNO, 0, "seteuid(%u) reset failed", uid);
118 	}
119 
120 }
121 
main(int argc,char * argv[])122 int main(int argc, char *argv[])
123 {
124 	char *username = "nobody";
125 
126 	tst_parse_opts(argc, argv, NULL, NULL);
127 
128 	tst_require_root();
129 
130 	if ((pw = getpwnam(username)) == NULL) {
131 		tst_brkm(TBROK, 0, "Username - %s - not found", username);
132 	}
133 
134 	if ((gr = getgrgid(pw->pw_gid)) == NULL) {
135 		tst_brkm(TBROK | TERRNO, 0, "getgrgid(%u) failed", pw->pw_gid);
136 	}
137 
138 	uid = pw->pw_uid;
139 	gid = gr->gr_gid;
140 
141 	tst_resm(TINFO, "Socket will try to be bind by user: %s, group: %s",
142 		 pw->pw_name, gr->gr_name);
143 
144 	try_bind();
145 	tst_exit();
146 }
147