1 /* Basic test for gethostid.
2    Copyright (C) 2018-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library 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 the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <gnu/lib-names.h>
20 #include <nss.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <support/namespace.h>
25 #include <support/support.h>
26 #include <support/temp_file.h>
27 #include <support/xdlfcn.h>
28 #include <support/xstdio.h>
29 #include <support/xunistd.h>
30 #include <unistd.h>
31 
32 /* Initial test is run outside a chroot, to increase the likelihood of
33    success.  */
34 static void
outside_chroot(void * closure)35 outside_chroot (void *closure)
36 {
37   long id = gethostid ();
38   printf ("info: host ID outside chroot: 0x%lx\n", id);
39 }
40 
41 /* The same, but this time perform a chroot operation.  */
42 static void
in_chroot(void * closure)43 in_chroot (void *closure)
44 {
45   const char *chroot_path = closure;
46   xchroot (chroot_path);
47   long id = gethostid ();
48   printf ("info: host ID in chroot: 0x%lx\n", id);
49 }
50 
51 static int
do_test(void)52 do_test (void)
53 {
54   support_isolate_in_subprocess (outside_chroot, NULL);
55 
56   /* Now run the test inside a chroot.  */
57   support_become_root ();
58   if (!support_can_chroot ())
59     /* Cannot perform further tests.  */
60     return 0;
61 
62   /* Only use nss_files.  */
63   __nss_configure_lookup ("hosts", "files");
64 
65   /* Load the DSO outside of the chroot.  */
66   xdlopen (LIBNSS_FILES_SO, RTLD_LAZY);
67 
68   char *chroot_dir = support_create_temp_directory ("tst-gethostid-");
69   support_isolate_in_subprocess (in_chroot, chroot_dir);
70 
71   /* Tests with /etc/hosts in the chroot.  */
72   {
73     char *path = xasprintf ("%s/etc", chroot_dir);
74     add_temp_file (path);
75     xmkdir (path, 0777);
76     free (path);
77     path = xasprintf ("%s/etc/hosts", chroot_dir);
78     add_temp_file (path);
79 
80     FILE *fp = xfopen (path, "w");
81     xfclose (fp);
82     printf ("info: chroot test with an empty /etc/hosts file\n");
83     support_isolate_in_subprocess (in_chroot, chroot_dir);
84 
85     char hostname[1024];
86     int ret = gethostname (hostname, sizeof (hostname));
87     if (ret < 0)
88       printf ("warning: invalid result from gethostname: %d\n", ret);
89     else if (strlen (hostname) == 0)
90       puts ("warning: gethostname returned empty string");
91     else
92       {
93         printf ("info: chroot test with IPv6 address in /etc/hosts for: %s\n",
94                 hostname);
95         fp = xfopen (path, "w");
96         /* Use an IPv6 address to induce another lookup failure.  */
97         fprintf (fp, "2001:db8::1 %s\n", hostname);
98         xfclose (fp);
99         support_isolate_in_subprocess (in_chroot, chroot_dir);
100       }
101     free (path);
102   }
103   free (chroot_dir);
104 
105   return 0;
106 }
107 
108 #include <support/test-driver.c>
109