bind02.c revision 56207cec7732e09c216c751c0b5f88a242bacae6
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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#include "usctest.h"
60
61char *TCID = "bind02";		/* Test program identifier.    */
62int testno;
63int TST_TOTAL = 1;
64extern int Tst_count;
65
66/* This port needs to be a Privledged port */
67#define TCP_PRIVLEGED_COM_PORT 463
68
69struct passwd *pw;
70struct group *gr;
71
72uid_t uid;
73gid_t gid;
74char nobody_uid[] = "nobody";
75
76int rc;
77
78void try_bind()
79{
80	struct sockaddr_in servaddr;
81	int sockfd, r_value;
82
83	// Set effective user/group
84	if ((rc = setegid(gid)) == -1) {
85		tst_brkm(TBROK, 0, "Unable to set process group id.");
86		tst_exit();
87	}
88	if ((rc = seteuid(uid)) == -1) {
89		tst_brkm(TBROK, 0, "Unable to set process user id.");
90		tst_exit();
91	}
92
93	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
94		printf("socket error\n");
95		exit(-1);
96	}
97
98	memset(&servaddr, 0, sizeof(servaddr));
99	servaddr.sin_family = AF_INET;
100	servaddr.sin_port = htons(TCP_PRIVLEGED_COM_PORT);
101	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
102	r_value = bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
103	if (r_value) {
104		if (errno == EACCES) {
105			tst_resm(TPASS, "correct error");
106		} else {
107			tst_resm(TFAIL, "incorrect error, %d", r_value);
108		}
109	} else {
110		tst_resm(TFAIL, "user was able to bind successfully");
111	}
112
113	close(sockfd);
114
115	// Set effective user/group
116	if ((rc = setegid(0)) == -1) {
117		tst_brkm(TBROK, 0, "Unable to reset process group id.");
118		tst_exit();
119	}
120	if ((rc = seteuid(uid)) == -1) {
121		tst_brkm(TBROK, 0, "Unable to reset process user id.");
122		tst_exit();
123	}
124
125}
126
127int main(int argc, char *argv[])
128{
129
130	if (argc != 2) {
131		tst_resm(TINFO, "Defaulting to user nobody");
132		pw = getpwnam(nobody_uid);
133	} else {
134		/*
135		 * Get test user uid/gid.
136		 */
137		if ((pw = getpwnam(argv[1])) == NULL) {
138			tst_brkm(TBROK, 0, "User %s not found", argv[1]);
139			tst_exit();
140		}
141	}
142
143	if ((gr = getgrgid(pw->pw_gid)) == NULL) {
144		tst_brkm(TBROK, 0, "Invalid group, %s", pw->pw_gid);
145		tst_exit();
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	/* NOT REACHED */
158	return 0;
159}
160