]> granicus.if.org Git - linux-pam/blob - xtests/tst-pam_group1.c
Relevant BUGIDs:
[linux-pam] / xtests / tst-pam_group1.c
1 /*
2  * Redistribution and use in source and binary forms, with or without
3  * modification, are permitted provided that the following conditions
4  * are met:
5  * 1. Redistributions of source code must retain the above copyright
6  *    notice, and the entire permission notice in its entirety,
7  *    including the disclaimer of warranties.
8  * 2. Redistributions in binary form must reproduce the above copyright
9  *    notice, this list of conditions and the following disclaimer in the
10  *    documentation and/or other materials provided with the distribution.
11  * 3. The name of the author may not be used to endorse or promote
12  *    products derived from this software without specific prior
13  *    written permission.
14  *
15  * ALTERNATIVELY, this product may be distributed under the terms of
16  * the GNU Public License, in which case the provisions of the GPL are
17  * required INSTEAD OF the above restrictions.  (This clause is
18  * necessary due to a potential bad interaction between the GPL and
19  * the restrictions contained in a BSD-style copyright.)
20  *
21  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
22  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31  * OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 /*
35   test case:
36
37   Check the following line in group.conf:
38
39   tst-pam_group1;*;tstpamgrp;Al0000-2400;tstpamgrp
40
41
42   pam_group should add group tstpamgrp to user tstpamgrp, but not
43   to tstpamgrp2.
44 */
45
46 #ifdef HAVE_CONFIG_H
47 #include <config.h>
48 #endif
49
50 #include <grp.h>
51 #include <stdio.h>
52 #include <string.h>
53 #include <unistd.h>
54 #include <sys/types.h>
55 #include <security/pam_appl.h>
56
57 #define GROUP_BLK 10
58 #define blk_size(len) (((len-1 + GROUP_BLK)/GROUP_BLK)*GROUP_BLK)
59
60 /* A conversation function which uses an internally-stored value for
61    the responses. */
62 static int
63 fake_conv (int num_msg, const struct pam_message **msgm UNUSED,
64            struct pam_response **response, void *appdata_ptr UNUSED)
65 {
66   struct pam_response *reply;
67   int count;
68
69   /* Sanity test. */
70   if (num_msg <= 0)
71     return PAM_CONV_ERR;
72
73   /* Allocate memory for the responses. */
74   reply = calloc (num_msg, sizeof (struct pam_response));
75   if (reply == NULL)
76     return PAM_CONV_ERR;
77
78   /* Each prompt elicits the same response. */
79   for (count = 0; count < num_msg; ++count)
80     {
81       reply[count].resp_retcode = 0;
82       reply[count].resp = strdup ("!!");
83     }
84
85   /* Set the pointers in the response structure and return. */
86   *response = reply;
87   return PAM_SUCCESS;
88 }
89
90 static struct pam_conv conv = {
91     fake_conv,
92     NULL
93 };
94
95 static int debug = 0;
96
97 static int
98 run_test (const char *user, gid_t groupid, int needit)
99 {
100   pam_handle_t *pamh = NULL;
101   int retval;
102
103   retval = pam_start("tst-pam_group1", user, &conv, &pamh);
104   if (retval != PAM_SUCCESS)
105     {
106       if (debug)
107         fprintf (stderr, "pam_group1: pam_start returned %d\n", retval);
108       return 1;
109     }
110
111   retval = pam_set_item (pamh, PAM_TTY, "/dev/tty1");
112   if (retval != PAM_SUCCESS)
113     {
114       if (debug)
115         fprintf (stderr,
116                  "pam_group1: pam_set_item(PAM_TTY) returned %d\n",
117                  retval);
118       return 1;
119     }
120
121   retval = pam_authenticate (pamh, 0);
122   if (retval != PAM_SUCCESS)
123     {
124       if (debug)
125         fprintf (stderr, "pam_group1: pam_authenticate returned %d\n", retval);
126       return 1;
127     }
128
129   retval = pam_setcred (pamh, PAM_ESTABLISH_CRED);
130   if (retval != PAM_SUCCESS)
131     {
132       if (debug)
133         fprintf (stderr, "pam_group1: pam_setcred returned %d\n", retval);
134       return 1;
135     }
136
137
138   int no_grps = getgroups(0, NULL); /* find the current number of groups */
139   if (no_grps > 0)
140     {
141       int i, found;
142       gid_t *grps = calloc (blk_size (no_grps), sizeof(gid_t));
143
144       if (getgroups(no_grps, grps) < 0)
145         {
146           if (debug)
147             fprintf (stderr, "pam_group1: getroups returned error: %m\n");
148           pam_end (pamh, PAM_SYSTEM_ERR);
149           return 1;
150         }
151
152       found = 0;
153       for (i = 0; i < no_grps; ++i)
154         {
155 #if 0
156           if (debug)
157             fprintf (stderr, "gid[%d]=%d\n", i, grps[i]);
158 #endif
159           if (grps[i] == groupid)
160             found = 1;
161         }
162       if ((needit && found) || (!needit && !found))
163         {
164           /* everything is ok */
165         }
166       else
167         {
168           pam_end (pamh, PAM_SYSTEM_ERR);
169           if (debug)
170             fprintf (stderr,
171                      "pam_group1: unexpected result for %s: needit=%d, found=%d\n",
172                      user, needit, found);
173           return 1;
174         }
175     }
176
177   retval = pam_end (pamh,retval);
178   if (retval != PAM_SUCCESS)
179     {
180       if (debug)
181         fprintf (stderr, "pam_group1: pam_end returned %d\n", retval);
182       return 1;
183     }
184   return 0;
185 }
186
187 int
188 main(int argc, char *argv[])
189 {
190   struct group *grp;
191   gid_t grpid;
192
193   if (argc > 1 && strcmp (argv[1], "-d") == 0)
194     debug = 1;
195
196   grp = getgrnam ("tstpamgrp");
197   if (grp == NULL)
198     return 1;
199   grpid = grp->gr_gid;
200
201   if (run_test ("root", grpid, 0) != 0 ||
202       run_test ("tstpamgrp2", grpid, 0) != 0 ||
203       run_test ("tstpamgrp", grpid, 1) != 0)
204     return 1;
205
206   return 0;
207 }