Home | History | Annotate | Download | only in bind
      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 
     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 
    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