Remove 'grp' and merge into 'nss' and 'posix'
[platform/upstream/glibc.git] / gshadow / tst-putsgent.c
1 /* Test for processing of invalid gshadow entries.  [BZ #18724]
2    Copyright (C) 2015-2023 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 <errno.h>
20 #include <gshadow.h>
21 #include <stdbool.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 static bool errors;
27
28 static void
29 check (struct sgrp e, const char *expected)
30 {
31   char *buf;
32   size_t buf_size;
33   FILE *f = open_memstream (&buf, &buf_size);
34
35   if (f == NULL)
36     {
37       printf ("open_memstream: %m\n");
38       errors = true;
39       return;
40     }
41
42   int ret = putsgent (&e, f);
43
44   if (expected == NULL)
45     {
46       if (ret == -1)
47         {
48           if (errno != EINVAL)
49             {
50               printf ("putsgent: unexpected error code: %m\n");
51               errors = true;
52             }
53         }
54       else
55         {
56           printf ("putsgent: unexpected success (\"%s\")\n", e.sg_namp);
57           errors = true;
58         }
59     }
60   else
61     {
62       /* Expect success.  */
63       size_t expected_length = strlen (expected);
64       if (ret == 0)
65         {
66           long written = ftell (f);
67
68           if (written <= 0 || fflush (f) < 0)
69             {
70               printf ("stream error: %m\n");
71               errors = true;
72             }
73           else if (buf[written - 1] != '\n')
74             {
75               printf ("FAILED: \"%s\" without newline\n", expected);
76               errors = true;
77             }
78           else if (strncmp (buf, expected, written - 1) != 0
79                    || written - 1 != expected_length)
80             {
81               printf ("FAILED: \"%s\" (%ld), expected \"%s\" (%zu)\n",
82                       buf, written - 1, expected, expected_length);
83               errors = true;
84             }
85         }
86       else
87         {
88           printf ("FAILED: putsgent (expected \"%s\"): %m\n", expected);
89           errors = true;
90         }
91     }
92
93   fclose (f);
94   free (buf);
95 }
96
97 static int
98 do_test (void)
99 {
100   check ((struct sgrp) {
101       .sg_namp = (char *) "root",
102     },
103     "root:::");
104   check ((struct sgrp) {
105       .sg_namp = (char *) "root",
106       .sg_passwd = (char *) "password",
107     },
108     "root:password::");
109   check ((struct sgrp) {
110       .sg_namp = (char *) "root",
111       .sg_passwd = (char *) "password",
112       .sg_adm = (char *[]) {(char *) "adm1", (char *) "adm2", NULL},
113       .sg_mem = (char *[]) {(char *) "mem1", (char *) "mem2", NULL},
114     },
115     "root:password:adm1,adm2:mem1,mem2");
116
117   /* Bad values.  */
118   {
119     static const char *const bad_strings[] = {
120       ":",
121       "\n",
122       ":bad",
123       "\nbad",
124       "b:ad",
125       "b\nad",
126       "bad:",
127       "bad\n",
128       "b:a\nd",
129       ",",
130       "\n,",
131       ":,",
132       ",bad",
133       "b,ad",
134       "bad,",
135       NULL
136     };
137     for (const char *const *bad = bad_strings; *bad != NULL; ++bad)
138       {
139         char *members[]
140           = {(char *) "first", (char *) *bad, (char *) "last", NULL};
141         if (strpbrk (*bad, ":\n") != NULL)
142           {
143             check ((struct sgrp) {
144                 .sg_namp = (char *) *bad,
145               }, NULL);
146             check ((struct sgrp) {
147                 .sg_namp = (char *) "root",
148                 .sg_passwd = (char *) *bad,
149               }, NULL);
150           }
151         check ((struct sgrp) {
152             .sg_namp = (char *) "root",
153             .sg_passwd = (char *) "password",
154             .sg_adm = members
155           }, NULL);
156         check ((struct sgrp) {
157             .sg_namp = (char *) "root",
158             .sg_passwd = (char *) "password",
159             .sg_mem = members
160           }, NULL);
161       }
162   }
163
164   return errors;
165 }
166
167 #define TEST_FUNCTION do_test ()
168 #include "../test-skeleton.c"