]> granicus.if.org Git - linux-pam/blob - xtests/tst-pam_unix4.c
pam_mkhomedir: Add debug option to pam_mkhomedir(8) man page
[linux-pam] / xtests / tst-pam_unix4.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  * Check password change minimum days handling.
36  */
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <security/pam_appl.h>
46 #include <sys/types.h>
47 #include <pwd.h>
48 #include <unistd.h>
49
50 /* A conversation function which uses an internally-stored value for
51    the responses. */
52 static int
53 fake_conv (int num_msg, const struct pam_message **msgm UNUSED,
54            struct pam_response **response, void *appdata_ptr UNUSED)
55 {
56   struct pam_response *reply;
57   int count;
58   static int respnum = 0;
59   static const char *resps[] = { "pamunix01", "TsTPAM01MAP", "TsTPAM01MAP" };
60
61   /* Sanity test. */
62   if (num_msg <= 0)
63     return PAM_CONV_ERR;
64
65   /* Allocate memory for the responses. */
66   reply = calloc (num_msg, sizeof (struct pam_response));
67   if (reply == NULL)
68     return PAM_CONV_ERR;
69
70   /* Answer with appropriate response from the above array. */
71   for (count = 0; count < num_msg; ++count)
72     {
73       if (msgm[count]->msg_style == PAM_PROMPT_ECHO_OFF)
74         {
75           reply[count].resp_retcode = 0;
76           reply[count].resp = strdup (resps[respnum % 3]);
77           ++respnum;
78         }
79     }
80
81   /* Set the pointers in the response structure and return. */
82   *response = reply;
83   return PAM_SUCCESS;
84 }
85
86 static struct pam_conv conv = {
87     fake_conv,
88     NULL
89 };
90
91
92 /* Check that errors of optional modules are ignored and that
93    required modules after a sufficient one are not executed.  */
94
95 int
96 main(int argc, char *argv[])
97 {
98   pam_handle_t *pamh=NULL;
99   const char *user="tstpamunix";
100   int retval;
101   int debug = 0;
102   int fail;
103   struct passwd *pwd;
104
105   if (argc < 2 || (*argv[1] != 'f' &&
106       *argv[1] != 'p'))
107     {
108       fprintf (stderr, "Need fail or pass argument.\n");
109       return 2;
110     }
111
112   fail = *argv[1] == 'f';
113
114   if (argc > 2 && strcmp (argv[2], "-d") == 0)
115     debug = 1;
116
117   pwd = getpwnam (user);
118
119   if (pwd == NULL)
120     {
121        if (debug)
122          fprintf (stderr, "unix4: Missing tstpamunix user.\n");
123        return 2;
124     }
125
126   /* we must switch the real (not effective) user so the restrictions
127      are enforced */
128   setreuid (pwd->pw_uid, -1);
129
130   retval = pam_start("tst-pam_unix4", user, &conv, &pamh);
131   if (retval != PAM_SUCCESS)
132     {
133       if (debug)
134         fprintf (stderr, "unix4: pam_start returned %d\n", retval);
135       return 1;
136     }
137
138   retval = pam_chauthtok (pamh, 0);
139   if ((!fail && retval != PAM_SUCCESS) || (fail && retval == PAM_SUCCESS))
140     {
141       if (debug)
142         fprintf (stderr, "unix4-1: pam_chauthtok returned %d\n", retval);
143       return 1;
144     }
145
146   retval = pam_end (pamh,retval);
147   if (retval != PAM_SUCCESS)
148     {
149       if (debug)
150         fprintf (stderr, "unix4: pam_end returned %d\n", retval);
151       return 1;
152     }
153   return 0;
154 }