Home | History | Annotate | Line # | Download | only in sys
      1 /* $NetBSD: t_getlogin.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2011 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jukka Ruohonen.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 #include <sys/cdefs.h>
     32 __RCSID("$NetBSD: t_getlogin.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
     33 
     34 #include <sys/param.h>
     35 #include <sys/wait.h>
     36 
     37 #include <atf-c.h>
     38 #include <errno.h>
     39 #include <stdlib.h>
     40 #include <string.h>
     41 #include <unistd.h>
     42 
     43 ATF_TC(getlogin_r_err);
     44 ATF_TC_HEAD(getlogin_r_err, tc)
     45 {
     46 	atf_tc_set_md_var(tc, "descr", "Test errors from getlogin_r(2)");
     47 }
     48 
     49 ATF_TC_BODY(getlogin_r_err, tc)
     50 {
     51 	char small[0];
     52 
     53 	ATF_REQUIRE(getlogin_r(small, sizeof(small)) == ERANGE);
     54 }
     55 
     56 ATF_TC(getlogin_same);
     57 ATF_TC_HEAD(getlogin_same, tc)
     58 {
     59 	atf_tc_set_md_var(tc, "descr", "getlogin(2) vs. getlogin_r(2)");
     60 }
     61 
     62 ATF_TC_BODY(getlogin_same, tc)
     63 {
     64 	char buf[MAXLOGNAME];
     65 	char *str;
     66 
     67 	str = getlogin();
     68 
     69 	if (str == NULL)
     70 		return;
     71 
     72 	ATF_REQUIRE(getlogin_r(buf, sizeof(buf)) == 0);
     73 
     74 	if (strcmp(str, buf) != 0)
     75 		atf_tc_fail("getlogin(2) and getlogin_r(2) differ");
     76 }
     77 
     78 ATF_TC(setlogin_basic);
     79 ATF_TC_HEAD(setlogin_basic, tc)
     80 {
     81 	atf_tc_set_md_var(tc, "descr", "Test that setlogin(2) works");
     82 	atf_tc_set_md_var(tc, "require.user", "root");
     83 }
     84 
     85 ATF_TC_BODY(setlogin_basic, tc)
     86 {
     87 	char *name;
     88 	pid_t pid;
     89 	int sta;
     90 
     91 	pid = fork();
     92 	ATF_REQUIRE(pid >= 0);
     93 
     94 	if (pid == 0) {
     95 
     96 		(void)setsid();
     97 
     98 		if (setlogin("foobar") != 0)
     99 			_exit(EXIT_FAILURE);
    100 
    101 		name = getlogin();
    102 
    103 		if (name == NULL)
    104 			_exit(EXIT_FAILURE);
    105 
    106 		if (strcmp(name, "foobar") != 0)
    107 			_exit(EXIT_FAILURE);
    108 
    109 		_exit(EXIT_SUCCESS);
    110 	}
    111 
    112 	(void)wait(&sta);
    113 
    114 	if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
    115 		atf_tc_fail("setlogin(2) failed to set login name");
    116 }
    117 
    118 ATF_TC(setlogin_err);
    119 ATF_TC_HEAD(setlogin_err, tc)
    120 {
    121 	atf_tc_set_md_var(tc, "descr", "Test errors from setlogin(2)");
    122 	atf_tc_set_md_var(tc, "require.user", "root");
    123 }
    124 
    125 ATF_TC_BODY(setlogin_err, tc)
    126 {
    127 	char buf[MAXLOGNAME + 1];
    128 	char *name;
    129 	pid_t pid;
    130 	int sta;
    131 
    132 	pid = fork();
    133 	ATF_REQUIRE(pid >= 0);
    134 
    135 	(void)memset(buf, 'x', sizeof(buf));
    136 
    137 	if (pid == 0) {
    138 
    139 		(void)setsid();
    140 
    141 		errno = 0;
    142 
    143 		if (setlogin(buf) != -1)
    144 			_exit(EINVAL);
    145 
    146 		if (errno != EINVAL)
    147 			_exit(EINVAL);
    148 
    149 		errno = 0;
    150 
    151 		if (setlogin((void *)-1) != -1)
    152 			_exit(EFAULT);
    153 
    154 		if (errno != EFAULT)
    155 			_exit(EFAULT);
    156 
    157 		name = getlogin();
    158 
    159 		if (name == NULL)
    160 			_exit(EXIT_FAILURE);
    161 
    162 		if (strcmp(name, "foobar") == 0)
    163 			_exit(EXIT_FAILURE);
    164 
    165 		_exit(EXIT_SUCCESS);
    166 	}
    167 
    168 	(void)wait(&sta);
    169 
    170 	if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) {
    171 
    172 		if (WEXITSTATUS(sta) == EFAULT)
    173 			atf_tc_fail("expected EFAULT, but the call succeeded");
    174 
    175 		if (WEXITSTATUS(sta) == EINVAL)
    176 			atf_tc_fail("expected EINVAL, but the call succeeded");
    177 
    178 		atf_tc_fail("setlogin(2) failed, but login name was set");
    179 	}
    180 }
    181 
    182 ATF_TC(setlogin_perm);
    183 ATF_TC_HEAD(setlogin_perm, tc)
    184 {
    185 	atf_tc_set_md_var(tc, "descr", "Test setlogin(2) as normal user");
    186 	atf_tc_set_md_var(tc, "require.user", "unprivileged");
    187 }
    188 
    189 ATF_TC_BODY(setlogin_perm, tc)
    190 {
    191 	char *name;
    192 	pid_t pid;
    193 	int sta;
    194 
    195 	pid = fork();
    196 	ATF_REQUIRE(pid >= 0);
    197 
    198 	if (pid == 0) {
    199 
    200 		(void)setsid();
    201 
    202 		errno = 0;
    203 
    204 		if (setlogin("foobar") != -1)
    205 			_exit(EXIT_FAILURE);
    206 
    207 		if (errno != EPERM)
    208 			_exit(EXIT_FAILURE);
    209 
    210 		name = getlogin();
    211 
    212 		if (name == NULL)
    213 			_exit(EXIT_FAILURE);
    214 
    215 		if (strcmp(name, "foobar") == 0)
    216 			_exit(EXIT_FAILURE);
    217 
    218 		_exit(EXIT_SUCCESS);
    219 	}
    220 
    221 	(void)wait(&sta);
    222 
    223 	if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
    224 		atf_tc_fail("login name was set as an unprivileged user");
    225 }
    226 
    227 ATF_TP_ADD_TCS(tp)
    228 {
    229 
    230 	ATF_TP_ADD_TC(tp, getlogin_r_err);
    231 	ATF_TP_ADD_TC(tp, getlogin_same);
    232 	ATF_TP_ADD_TC(tp, setlogin_basic);
    233 	ATF_TP_ADD_TC(tp, setlogin_err);
    234 	ATF_TP_ADD_TC(tp, setlogin_perm);
    235 
    236 	return atf_no_error();
    237 }
    238