• 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 char nobody_uid[] = "nobody";
73 
74 int rc;
75 
try_bind(void)76 void try_bind(void)
77 {
78 	struct sockaddr_in servaddr;
79 	int sockfd, r_value;
80 
81 	// Set effective user/group
82 	if ((rc = setegid(gid)) == -1) {
83 		tst_brkm(TBROK | TERRNO, 0, "setegid(%u) failed", gid);
84 	}
85 	if ((rc = seteuid(uid)) == -1) {
86 		tst_brkm(TBROK | TERRNO, 0, "seteuid(%u) failed", uid);
87 	}
88 
89 	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
90 		tst_brkm(TBROK | TERRNO, 0, "socket() failed");
91 	}
92 
93 	memset(&servaddr, 0, sizeof(servaddr));
94 	servaddr.sin_family = AF_INET;
95 	servaddr.sin_port = htons(TCP_PRIVLEGED_COM_PORT);
96 	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
97 	r_value = bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
98 	if (r_value) {
99 		if (errno == EACCES) {
100 			tst_resm(TPASS, "correct error");
101 		} else {
102 			tst_resm(TFAIL, "incorrect error, %d", r_value);
103 		}
104 	} else {
105 		tst_resm(TFAIL, "user was able to bind successfully");
106 	}
107 
108 	close(sockfd);
109 
110 	// Set effective user/group
111 	if ((rc = setegid(0)) == -1) {
112 		tst_brkm(TBROK | TERRNO, 0, "setegid(0) reset failed");
113 	}
114 	if ((rc = seteuid(uid)) == -1) {
115 		/* XXX: is this seteuid() correct !?  it isnt a reset if we
116 		 *      made the same exact call above ...
117 		 */
118 		tst_brkm(TBROK | TERRNO, 0, "seteuid(%u) reset failed", uid);
119 	}
120 
121 }
122 
main(int argc,char * argv[])123 int main(int argc, char *argv[])
124 {
125 
126 	/* FreeBSD has set limits for user login name -- MAXLOGNAME, but
127 	 * Linux doesn't have that limitation apparently. */
128 	char *username = NULL;
129 
130 	tst_require_root();
131 
132 	if (argc != 2) {
133 		tst_resm(TINFO, "Defaulting to user nobody");
134 		username = strdup(nobody_uid);
135 	} else {
136 		/* Get test user uid/gid. */
137 		username = argv[1];
138 	}
139 
140 	if ((pw = getpwnam(username)) == NULL) {
141 		tst_brkm(TBROK, 0, "Username - %s - not found", username);
142 	}
143 
144 	if ((gr = getgrgid(pw->pw_gid)) == NULL) {
145 		tst_brkm(TBROK | TERRNO, 0, "getgrgid(%u) failed", pw->pw_gid);
146 	}
147 
148 	uid = pw->pw_uid;
149 	gid = gr->gr_gid;
150 
151 	tst_resm(TINFO, "Socket will try to be bind by user: %s, group: %s",
152 		 pw->pw_name, gr->gr_name);
153 
154 	try_bind();
155 	tst_exit();
156 }
157