1272343Sngie/* $NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $ */ 2272343Sngie 3272343Sngie/*- 4272343Sngie * Copyright (c) 2011 The NetBSD Foundation, Inc. 5272343Sngie * All rights reserved. 6272343Sngie * 7272343Sngie * This code is derived from software contributed to The NetBSD Foundation 8272343Sngie * by Jukka Ruohonen. 9272343Sngie * 10272343Sngie * Redistribution and use in source and binary forms, with or without 11272343Sngie * modification, are permitted provided that the following conditions 12272343Sngie * are met: 13272343Sngie * 1. Redistributions of source code must retain the above copyright 14272343Sngie * notice, this list of conditions and the following disclaimer. 15272343Sngie * 2. Redistributions in binary form must reproduce the above copyright 16272343Sngie * notice, this list of conditions and the following disclaimer in the 17272343Sngie * documentation and/or other materials provided with the distribution. 18272343Sngie * 19272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21272343Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22272343Sngie * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23272343Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24272343Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27272343Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29272343Sngie * POSSIBILITY OF SUCH DAMAGE. 30272343Sngie */ 31272343Sngie#include <sys/cdefs.h> 32272343Sngie__RCSID("$NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $"); 33272343Sngie 34272343Sngie#include <sys/param.h> 35272343Sngie 36272343Sngie#include <atf-c.h> 37321878Sasomers#include <err.h> 38272343Sngie#include <errno.h> 39321878Sasomers#include <fcntl.h> 40272343Sngie#include <string.h> 41272343Sngie#include <unistd.h> 42272343Sngie 43321878Sasomers#define DOMAIN_BACKUP_FILE "domain.bak" 44272343Sngie 45272343Sngiestatic const char domains[][MAXHOSTNAMELEN] = { 46272343Sngie "1234567890", 47272343Sngie "abcdefghijklmnopqrst", 48272343Sngie "!#\xa4%&/(..xasS812=!=!(I(!;X;;X.as.dasa=?;,..<>|**^\xa8", 49272343Sngie "--------------------------------------------------------------------" 50272343Sngie}; 51272343Sngie 52321878Sasomersstatic void 53321878Sasomersbackup_domain(void) 54321878Sasomers{ 55321878Sasomers char domain[MAXHOSTNAMELEN]; 56321878Sasomers int fd; 57321878Sasomers size_t l; 58321878Sasomers ssize_t r,n = 0; 59321878Sasomers 60321878Sasomers memset(domain, 0, sizeof(domain)); 61321878Sasomers 62321878Sasomers ATF_REQUIRE_EQ(0, getdomainname(domain, sizeof(domain))); 63321878Sasomers l = strnlen(domain, MAXHOSTNAMELEN); 64321878Sasomers fd = open(DOMAIN_BACKUP_FILE, O_WRONLY | O_CREAT | O_EXCL, 0644); 65321878Sasomers ATF_REQUIRE(fd >= 0); 66321878Sasomers while ((r = write(fd, domain + n, l - n)) > 0) 67321878Sasomers n += r; 68321878Sasomers ATF_REQUIRE_EQ(0, r); 69321878Sasomers close(fd); 70321878Sasomers} 71321878Sasomers 72321878Sasomersstatic void 73321878Sasomersrestore_domain(void) 74321878Sasomers{ 75321878Sasomers char domain[MAXHOSTNAMELEN]; 76321878Sasomers int fd; 77321878Sasomers ssize_t r, n = 0; 78321878Sasomers 79321878Sasomers memset(domain, 0, sizeof(domain)); 80321878Sasomers if ((fd = open(DOMAIN_BACKUP_FILE, O_RDONLY)) < 0) 81321878Sasomers err(1, "open"); 82321878Sasomers while ((r = read(fd, domain + n, sizeof(domain) - n)) > 0) 83321878Sasomers n += r; 84321878Sasomers if (r < 0) 85321878Sasomers err(1, "read"); 86321878Sasomers if (setdomainname(domain, n) != 0) 87321878Sasomers err(1, "setdomainname"); 88321878Sasomers close(fd); 89321878Sasomers} 90321878Sasomers 91272343SngieATF_TC_WITH_CLEANUP(setdomainname_basic); 92272343SngieATF_TC_HEAD(setdomainname_basic, tc) 93272343Sngie{ 94272343Sngie atf_tc_set_md_var(tc, "descr", "A basic test of setdomainname(3)"); 95272343Sngie atf_tc_set_md_var(tc, "require.user", "root"); 96272343Sngie} 97272343Sngie 98272343SngieATF_TC_BODY(setdomainname_basic, tc) 99272343Sngie{ 100272343Sngie char name[MAXHOSTNAMELEN]; 101272343Sngie size_t i; 102272343Sngie 103321878Sasomers backup_domain(); 104272343Sngie for (i = 0; i < __arraycount(domains); i++) { 105272343Sngie 106272343Sngie (void)memset(name, 0, sizeof(name)); 107272343Sngie 108276478Sngie#ifdef __FreeBSD__ 109312095Sngie /* 110276478Sngie * Sanity checks to ensure that the wrong invariant isn't being 111276478Sngie * tested for per PR # 181127 112276478Sngie */ 113276478Sngie ATF_REQUIRE_EQ(sizeof(domains[i]), MAXHOSTNAMELEN); 114276478Sngie ATF_REQUIRE_EQ(sizeof(name), MAXHOSTNAMELEN); 115276478Sngie 116276478Sngie ATF_REQUIRE(setdomainname(domains[i],sizeof(domains[i]) - 1) == 0); 117276478Sngie ATF_REQUIRE(getdomainname(name, sizeof(name) - 1) == 0); 118276478Sngie#else 119272343Sngie ATF_REQUIRE(setdomainname(domains[i],sizeof(domains[i])) == 0); 120272343Sngie ATF_REQUIRE(getdomainname(name, sizeof(name)) == 0); 121276478Sngie#endif 122272343Sngie ATF_REQUIRE(strcmp(domains[i], name) == 0); 123272343Sngie } 124272343Sngie 125272343Sngie} 126272343Sngie 127272343SngieATF_TC_CLEANUP(setdomainname_basic, tc) 128272343Sngie{ 129321878Sasomers restore_domain(); 130272343Sngie} 131272343Sngie 132272343SngieATF_TC_WITH_CLEANUP(setdomainname_limit); 133272343SngieATF_TC_HEAD(setdomainname_limit, tc) 134272343Sngie{ 135272343Sngie atf_tc_set_md_var(tc, "descr", "Too long domain name errors out?"); 136272343Sngie atf_tc_set_md_var(tc, "require.user", "root"); 137272343Sngie} 138272343Sngie 139272343SngieATF_TC_BODY(setdomainname_limit, tc) 140272343Sngie{ 141272343Sngie char name[MAXHOSTNAMELEN + 1]; 142272343Sngie 143272343Sngie (void)memset(name, 0, sizeof(name)); 144321878Sasomers backup_domain(); 145272343Sngie 146276478Sngie#ifdef __FreeBSD__ 147276478Sngie ATF_REQUIRE(setdomainname(name, MAXHOSTNAMELEN - 1 ) == 0); 148276478Sngie ATF_REQUIRE(setdomainname(name, MAXHOSTNAMELEN) == -1); 149276478Sngie#endif 150272343Sngie ATF_REQUIRE(setdomainname(name, sizeof(name)) == -1); 151272343Sngie} 152272343Sngie 153272343SngieATF_TC_CLEANUP(setdomainname_limit, tc) 154272343Sngie{ 155321878Sasomers restore_domain(); 156272343Sngie} 157272343Sngie 158321878SasomersATF_TC(setdomainname_perm); 159272343SngieATF_TC_HEAD(setdomainname_perm, tc) 160272343Sngie{ 161272343Sngie atf_tc_set_md_var(tc, "descr", "Can normal user set the domain name?"); 162272343Sngie atf_tc_set_md_var(tc, "require.user", "unprivileged"); 163272343Sngie} 164272343Sngie 165272343SngieATF_TC_BODY(setdomainname_perm, tc) 166272343Sngie{ 167321878Sasomers char domain[MAXHOSTNAMELEN]; 168272343Sngie 169321878Sasomers memset(domain, 0, sizeof(domain)); 170321878Sasomers 171272343Sngie errno = 0; 172272343Sngie ATF_REQUIRE_ERRNO(EPERM, setdomainname(domain, sizeof(domain)) == -1); 173272343Sngie} 174272343Sngie 175272343SngieATF_TP_ADD_TCS(tp) 176272343Sngie{ 177272343Sngie ATF_TP_ADD_TC(tp, setdomainname_basic); 178272343Sngie ATF_TP_ADD_TC(tp, setdomainname_limit); 179272343Sngie ATF_TP_ADD_TC(tp, setdomainname_perm); 180272343Sngie 181272343Sngie return atf_no_error(); 182272343Sngie} 183