xref: /freebsd/contrib/pam-krb5/module/internal.h (revision d903f2e289a7f8c502918ebc64d46aaa86efce24)
1 /*
2  * Internal prototypes and structures for pam-krb5.
3  *
4  * Copyright 2005-2009, 2014, 2020 Russ Allbery <eagle@eyrie.org>
5  * Copyright 2011, 2012
6  *     The Board of Trustees of the Leland Stanford Junior University
7  * Copyright 2005 Andres Salomon <dilinger@debian.org>
8  * Copyright 1999-2000 Frank Cusack <fcusack@fcusack.com>
9  *
10  * SPDX-License-Identifier: BSD-3-clause or GPL-1+
11  */
12 
13 #ifndef INTERNAL_H
14 #define INTERNAL_H 1
15 
16 #include <config.h>
17 #include <portable/krb5.h>
18 #include <portable/macros.h>
19 #include <portable/pam.h>
20 
21 #include <stdarg.h>
22 #include <syslog.h>
23 
24 /* Forward declarations to avoid unnecessary includes. */
25 struct pam_args;
26 struct passwd;
27 struct vector;
28 
29 /* Used for unused parameters to silence gcc warnings. */
30 #define UNUSED __attribute__((__unused__))
31 
32 /*
33  * An authentication context, including all the data we want to preserve
34  * across calls to the public entry points.  This context is stored in the PAM
35  * state and a pointer to it is stored in the pam_args struct that is passed
36  * as the first argument to most internal functions.
37  */
38 struct context {
39     char *name;             /* Username being authenticated. */
40     krb5_context context;   /* Kerberos context. */
41     krb5_ccache cache;      /* Active credential cache, if any. */
42     krb5_principal princ;   /* Principal being authenticated. */
43     int expired;            /* If set, account was expired. */
44     int dont_destroy_cache; /* If set, don't destroy cache on shutdown. */
45     int initialized;        /* If set, ticket cache initialized. */
46     krb5_creds *creds;      /* Credentials for password changing. */
47     krb5_ccache fast_cache; /* Temporary credential cache for FAST. */
48 };
49 
50 /*
51  * The global structure holding our arguments, both from krb5.conf and from
52  * the PAM configuration.  Filled in by pamk5_init and stored in the pam_args
53  * struct passed as a first argument to most internal functions.  Sort by
54  * documentation order.
55  */
56 struct pam_config {
57     /* Authorization. */
58     char *alt_auth_map;  /* An sprintf pattern to map principals. */
59     bool force_alt_auth; /* Alt principal must be used if it exists. */
60     bool ignore_k5login; /* Don't check .k5login files. */
61     bool ignore_root;    /* Skip authentication for root. */
62     long minimum_uid;    /* Ignore users below this UID. */
63     bool only_alt_auth;  /* Alt principal must be used. */
64     bool search_k5login; /* Try password with each line of .k5login. */
65 
66     /* Kerberos behavior. */
67     char *fast_ccache;           /* Cache containing armor ticket. */
68     bool anon_fast;              /* sets up an anonymous fast armor cache */
69     bool forwardable;            /* Obtain forwardable tickets. */
70     char *keytab;                /* Keytab for credential validation. */
71     char *realm;                 /* Default realm for Kerberos. */
72     krb5_deltat renew_lifetime;  /* Renewable lifetime of credentials. */
73     krb5_deltat ticket_lifetime; /* Lifetime of credentials. */
74     char *user_realm;            /* Default realm for user principals. */
75 
76     /* PAM behavior. */
77     bool clear_on_fail;  /* Delete saved password on change failure. */
78     bool debug;          /* Log debugging information. */
79     bool defer_pwchange; /* Defer expired account fail to account. */
80     bool fail_pwchange;  /* Treat expired password as auth failure. */
81     bool force_pwchange; /* Change expired passwords in auth. */
82     bool no_update_user; /* Don't update PAM_USER with local name. */
83     bool silent;         /* Suppress text and errors (PAM_SILENT). */
84     char *trace;         /* File name for trace logging. */
85 
86     /* PKINIT. */
87     char *pkinit_anchors;       /* Trusted certificates, usually per realm. */
88     bool pkinit_prompt;         /* Prompt user to insert smart card. */
89     char *pkinit_user;          /* User ID to pass to PKINIT. */
90     struct vector *preauth_opt; /* Preauth options. */
91     bool try_pkinit;            /* Attempt PKINIT, fall back to password. */
92     bool use_pkinit;            /* Require PKINIT. */
93 
94     /* Prompting. */
95     char *banner;          /* Addition to password changing prompts. */
96     bool expose_account;   /* Display principal in password prompts. */
97     bool force_first_pass; /* Require a previous password be stored. */
98     bool no_prompt;        /* Let Kerberos handle password prompting. */
99     bool prompt_principal; /* Prompt for the Kerberos principal. */
100     bool try_first_pass;   /* Try the previously entered password. */
101     bool use_authtok;      /* Use the stored new password for changes. */
102     bool use_first_pass;   /* Always use the previous password. */
103 
104     /* Ticket caches. */
105     char *ccache;            /* Path to write ticket cache to. */
106     char *ccache_dir;        /* Directory for ticket cache. */
107     bool no_ccache;          /* Don't create a ticket cache. */
108     bool retain_after_close; /* Don't destroy the cache on session end. */
109 
110     /* The authentication context, which bundles together Kerberos data. */
111     struct context *ctx;
112     bool no_warn;            /* XXX Dummy argument, remove when Heimdal is removed. */
113 };
114 
115 /* Default to a hidden visibility for all internal functions. */
116 #pragma GCC visibility push(hidden)
117 
118 /* Parse the PAM flags, arguments, and krb5.conf and fill out pam_args. */
119 struct pam_args *pamk5_init(pam_handle_t *, int flags, int, const char **);
120 
121 /* Free the pam_args struct when we're done. */
122 void pamk5_free(struct pam_args *);
123 
124 /*
125  * The underlying functions between several of the major PAM interfaces.
126  */
127 int pamk5_account(struct pam_args *);
128 int pamk5_authenticate(struct pam_args *);
129 
130 /*
131  * The underlying function below pam_sm_chauthtok.  If the second argument is
132  * true, we're doing the preliminary check and shouldn't actually change the
133  * password.
134  */
135 int pamk5_password(struct pam_args *, bool only_auth);
136 
137 /*
138  * Create or refresh the user's ticket cache.  This is the underlying function
139  * beneath pam_sm_setcred and pam_sm_open_session.
140  */
141 int pamk5_setcred(struct pam_args *, bool refresh);
142 
143 /*
144  * Authenticate the user.  Prompts for the password as needed and obtains
145  * tickets for in_tkt_service, krbtgt/<realm> by default.  Stores the initial
146  * credentials in the final argument, allocating a new krb5_creds structure.
147  * If possible, the initial credentials are verified by checking them against
148  * the local system key.
149  */
150 int pamk5_password_auth(struct pam_args *, const char *service, krb5_creds **);
151 
152 /*
153  * Prompt the user for a new password, twice so that they can confirm.  Sets
154  * PAM_AUTHTOK and puts the new password in newly allocated memory in pass if
155  * it's not NULL.
156  */
157 int pamk5_password_prompt(struct pam_args *, char **pass);
158 
159 /*
160  * Change the user's password.  Prompts for the current password as needed and
161  * the new password.  If the second argument is true, only obtains the
162  * necessary credentials without changing anything.
163  */
164 int pamk5_password_change(struct pam_args *, bool only_auth);
165 
166 /*
167  * Generic conversation function to display messages or get information from
168  * the user.  Takes the message, the message type, and a place to put the
169  * result of a prompt.
170  */
171 int pamk5_conv(struct pam_args *, const char *, int, char **);
172 
173 /*
174  * Function specifically for getting a password.  Takes a prefix (if non-NULL,
175  * args->banner will also be prepended) and a pointer into which to store the
176  * password.  The password must be freed by the caller.
177  */
178 int pamk5_get_password(struct pam_args *, const char *, char **);
179 
180 /* Prompting function for the Kerberos libraries. */
181 krb5_error_code pamk5_prompter_krb5(krb5_context, void *data, const char *name,
182                                     const char *banner, int, krb5_prompt *);
183 
184 /* Prompting function that doesn't allow passwords. */
185 krb5_error_code pamk5_prompter_krb5_no_password(krb5_context, void *data,
186                                                 const char *name,
187                                                 const char *banner, int,
188                                                 krb5_prompt *);
189 
190 /* Check the user with krb5_kuserok or the configured equivalent. */
191 int pamk5_authorized(struct pam_args *);
192 
193 /* Returns true if we should ignore this user (root or low UID). */
194 int pamk5_should_ignore(struct pam_args *, PAM_CONST char *);
195 
196 /*
197  * alt_auth_map support.
198  *
199  * pamk5_map_principal attempts to map the user to a Kerberos principal
200  * according to alt_auth_map.  Returns 0 on success, storing the mapped
201  * principal name in newly allocated memory in principal.  The caller is
202  * responsiple for freeing. Returns an errno value on any error.
203  *
204  * pamk5_alt_auth attempts an authentication to the given service with the
205  * given options and password and returns a Kerberos error code.  On success,
206  * the new credentials are stored in krb5_creds.
207  *
208  * pamk5_alt_auth_verify verifies that Kerberos credentials are authorized to
209  * access the account given the configured alt_auth_map and is meant to be
210  * called from pamk5_authorized.  It returns a PAM status code.
211  */
212 int pamk5_map_principal(struct pam_args *, const char *username,
213                         char **principal);
214 krb5_error_code pamk5_alt_auth(struct pam_args *, const char *service,
215                                krb5_get_init_creds_opt *, const char *pass,
216                                krb5_creds *);
217 int pamk5_alt_auth_verify(struct pam_args *);
218 
219 /* FAST support.  Set up FAST protection of authentication. */
220 void pamk5_fast_setup(struct pam_args *, krb5_get_init_creds_opt *);
221 
222 /* Context management. */
223 int pamk5_context_new(struct pam_args *);
224 int pamk5_context_fetch(struct pam_args *);
225 void pamk5_context_free(struct pam_args *);
226 void pamk5_context_destroy(pam_handle_t *, void *data, int pam_end_status);
227 
228 /* Get and set environment variables for the ticket cache. */
229 const char *pamk5_get_krb5ccname(struct pam_args *, const char *key);
230 int pamk5_set_krb5ccname(struct pam_args *, const char *, const char *key);
231 
232 /*
233  * Create a ticket cache file securely given a mkstemp template.  Modifies
234  * template in place to store the name of the created file.
235  */
236 int pamk5_cache_mkstemp(struct pam_args *, char *template);
237 
238 /*
239  * Create a ticket cache and initialize it with the provided credentials,
240  * returning the new cache in the last argument
241  */
242 int pamk5_cache_init(struct pam_args *, const char *ccname, krb5_creds *,
243                      krb5_ccache *);
244 
245 /*
246  * Create a ticket cache with a random path, initialize it with the provided
247  * credentials, store it in the context, and put the path into PAM_KRB5CCNAME.
248  */
249 int pamk5_cache_init_random(struct pam_args *, krb5_creds *);
250 
251 /*
252  * Compatibility functions.  Depending on whether pam_krb5 is built with MIT
253  * Kerberos or Heimdal, appropriate implementations for the Kerberos
254  * implementation will be provided.
255  */
256 krb5_error_code pamk5_compat_set_realm(struct pam_config *, const char *);
257 void pamk5_compat_free_realm(struct pam_config *);
258 
259 /* Undo default visibility change. */
260 #pragma GCC visibility pop
261 
262 #endif /* !INTERNAL_H */
263