source: trunk/debathena/third/schroot/sbuild/sbuild-auth.h @ 24167

Revision 24167, 12.0 KB checked in by broder, 15 years ago (diff)
Import schroot upstream into subversion.
Line 
1/* Copyright © 2005-2007  Roger Leigh <rleigh@debian.org>
2 *
3 * schroot is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * schroot is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program.  If not, see
15 * <http://www.gnu.org/licenses/>.
16 *
17 *********************************************************************/
18
19#ifndef SBUILD_AUTH_H
20#define SBUILD_AUTH_H
21
22#include <sbuild/sbuild-config.h>
23#include <sbuild/sbuild-custom-error.h>
24#include <sbuild/sbuild-environment.h>
25#include <sbuild/sbuild-types.h>
26#include <sbuild/sbuild-tr1types.h>
27
28#include <string>
29
30#include <sys/types.h>
31#include <sys/wait.h>
32#include <grp.h>
33#include <pwd.h>
34#include <unistd.h>
35
36namespace sbuild
37{
38
39  /**
40   * Authentication handler.
41   *
42   * auth handles user authentication, authorisation and session
43   * management using the Pluggable Authentication Modules (PAM)
44   * library.  It is essentially an object-oriented wrapper around PAM.
45   *
46   * In order to use PAM correctly, it is important to call several of
47   * the methods in the correct order.  For example, it is not possible
48   * to authorise a user before authenticating a user, and a session may
49   * not be started before either of these have occurred.
50   *
51   * A conversation handler must be specified using set_conv before
52   * calling any of the functions below.
53   *
54   * The correct order is
55   * - start
56   * - authenticate
57   * - setupenv
58   * - account
59   * - cred_establish
60   * - open_session
61   *
62   * After the session has finished, or if an error occurred, the
63   * corresponding cleanup methods should be called
64   * - close_session
65   * - cred_delete
66   * - stop
67   */
68  class auth
69  {
70  public:
71    /// Authentication status
72    enum status
73      {
74        STATUS_NONE, ///< Authentication is not required.
75        STATUS_USER, ///< Authentication is required by the user.
76        STATUS_FAIL  ///< Authentication has failed.
77      };
78
79    /// Message verbosity
80    enum verbosity
81      {
82        VERBOSITY_QUIET,  ///< Only print essential messages.
83        VERBOSITY_NORMAL, ///< Print messages (the default).
84        VERBOSITY_VERBOSE ///< Print all messages.
85      };
86
87    /// Error codes.
88    enum error_code
89      {
90        HOSTNAME,        ///< Failed to get hostname.
91        USER,            ///< User not found.
92        GROUP,           ///< Group not found.
93        AUTHENTICATION,  ///< Authentication failed.
94        AUTHORISATION,   ///< Authorisation failed.
95        PAM_DOUBLE_INIT, ///< PAM was already initialised.
96        PAM              ///< PAM error.
97      };
98
99    /// Exception type.
100    typedef custom_error<error_code> error;
101
102    /// A shared_ptr to a auth object.
103    typedef std::tr1::shared_ptr<auth> ptr;
104
105  protected:
106    /**
107     * The constructor.
108     *
109     * @param service_name the PAM service name.  This should be a
110     * hard-coded constant string literal for safety and security.
111     * This is passed to pam_start() when initialising PAM, and is
112     * used to load the correct configuration file from /etc/pam.d.
113     */
114    auth (std::string const& service_name);
115
116  public:
117    /**
118     * The destructor.
119     */
120    virtual ~auth ();
121
122    /**
123     * Get the PAM service name.
124     *
125     * @returns the service name.
126     */
127    std::string const&
128    get_service () const;
129
130    /**
131     * Get the uid of the user.  This is the uid to run as in the *
132     * session.
133     *
134     * @returns a uid.  This will be 0 if no user was set, or the user
135     * is uid 0.
136     */
137    uid_t
138    get_uid () const;
139
140    /**
141     * Get the gid of the user.  This is the gid to run as in the
142     * session.
143     *
144     * @returns a gid.  This will be 0 if no user was set, or the user
145     * is gid 0.
146     */
147    gid_t
148    get_gid () const;
149
150    /**
151     * Get the name of the user.  This is the user to run as in the
152     * session.
153     *
154     * @returns the user's name.
155     */
156    std::string const&
157    get_user () const;
158
159    /**
160     * Set the name of the user.  This is the user to run as in the
161     * session.
162     *
163     * As a side effect, the uid, gid, home and shell member variables
164     * will also be set, so calling the corresponding get methods will
165     * now return meaningful values.
166     *
167     * @param user the name to set.
168     */
169    void
170    set_user (std::string const& user);
171
172    /**
173     * Get the command to run in the session.
174     *
175     * @returns the command as string list, each item being a separate
176     * argument.  If no command has been specified, the list will be
177     * empty.
178     */
179    string_list const&
180    get_command () const;
181
182    /**
183     * Set the command to run in the session.
184     *
185     * @param command the command to run.  This is a string list, each
186     * item being a separate argument.
187     */
188    void
189    set_command (string_list const& command);
190
191    /**
192     * Get the home directory.  This is the $HOME to set in the session,
193     * if the user environment is not being preserved.
194     *
195     * @returns the home directory.
196     */
197    std::string const&
198    get_home () const;
199
200    /**
201     * Get the working directory.  This is the working directory to
202     * set in the session.
203     *
204     * @returns the current working directory.
205     */
206    std::string const&
207    get_wd () const;
208
209    /**
210     * Set the working directory.  This is the working directory to
211     * set in the session.
212     *
213     * @param wd the current working directory.
214     */
215    void
216    set_wd (std::string const& wd);
217
218    /**
219     * Get the name of the shell.  This is the shell to run in the
220     * session.
221     *
222     * @returns the shell.  This is typically a full pathname, though
223     * the executable name only should also work (the caller will have
224     * to search for it).
225     */
226    std::string const&
227    get_shell () const;
228
229    /**
230     * Get the environment to use in the session.
231     *
232     * @returns an environment list (a list of key-value pairs).
233     */
234    environment const&
235    get_environment () const;
236
237    /**
238     * Set the environment to use in the session.
239     *
240     * @param environment an environ- or envp-like string vector
241     * containing key=value pairs.
242     */
243    void
244    set_environment (char **environment);
245
246    /**
247     * Set the environment to use in the session.
248     *
249     * @param environment an environment list.
250     */
251    void
252    set_environment (environment const& environment);
253
254    /**
255     * Get the minimal environment.  This is the user environment plus
256     * essential environment variables which are set if not already
257     * present.
258     *
259     * @returns an environment list.
260     */
261    environment
262    get_minimal_environment () const;
263
264    /**
265     * Get the PAM environment.  This is the environment as set by PAM
266     * modules.
267     *
268     * @returns an environment list.
269     */
270    virtual environment
271    get_auth_environment () const = 0;
272
273    /**
274     * Get the "remote uid" of the user.  This is the uid which is
275     * requesting authentication.
276     *
277     * @returns a uid.
278     */
279    uid_t
280    get_ruid () const;
281
282    /**
283     * Get the "remote gid" of the user.  This is the gid which is
284     * requesting authentication.
285     *
286     * @returns a gid.
287     */
288    gid_t
289    get_rgid () const;
290
291    /**
292     * Get the "remote" name of the user.  This is the user which is
293     * requesting authentication.
294     *
295     * @returns a user name.
296     */
297    std::string const&
298    get_ruser () const;
299
300    /**
301     * Get the "remote" name of the group.  This is the group which is
302     * requesting authentication.
303     *
304     * @returns a group name.
305     */
306    std::string const&
307    get_rgroup () const;
308
309    /**
310     * Get the message verbosity.
311     *
312     * Returns the verbosity level.
313     */
314    verbosity
315    get_verbosity () const;
316
317    /**
318     * Set the message verbosity.
319     *
320     * @param verbosity the verbosity level.
321     */
322    void
323    set_verbosity (verbosity verbosity);
324
325    /**
326     * Start the PAM system.  No other PAM functions may be called before
327     * calling this function.
328     *
329     * An error will be thrown on failure.
330     */
331    virtual void
332    start ();
333
334    /**
335     * Stop the PAM system.  No other PAM functions may be used after
336     * calling this function.
337     *
338     * An error will be thrown on failure.
339     */
340    virtual void
341    stop ();
342
343    /**
344     * Perform PAM authentication.  If auth_status is set to
345     * AUTH_USER, the user will be prompted to authenticate
346     * themselves.  If auth_status is AUTH_NONE, no authentication is
347     * required, and if AUTH_FAIL, authentication will fail.
348     *
349     * An error will be thrown on failure.
350     *
351     * @param auth_status initial authentication status.
352     * @todo Use sysconf(_SC_HOST_NAME_MAX) when libc in a stable
353     * release supports it.
354     */
355    virtual void
356    authenticate (status auth_status);
357
358    /**
359     * Import the user environment into PAM.  If no environment was
360     * specified with set_environment, a minimal environment will be
361     * created containing HOME, LOGNAME, PATH, TERM and LOGNAME.
362     *
363     * An error will be thrown on failure.
364     *
365     * Note that the environment is not sanitised in any way.  This is
366     * the responsibility of the user.
367     */
368    virtual void
369    setupenv ();
370
371    /**
372     * Do PAM account management (authorisation).
373     *
374     * An error will be thrown on failure.
375     */
376    virtual void
377    account ();
378
379    /**
380     * Use PAM to establish credentials.
381     *
382     * An error will be thrown on failure.
383     */
384    virtual void
385    cred_establish ();
386
387    /**
388     * Use PAM to delete credentials.
389     *
390     * An error will be thrown on failure.
391     */
392    virtual void
393    cred_delete ();
394
395    /**
396     * Open a PAM session.
397     *
398     * An error will be thrown on failure.
399     */
400    virtual void
401    open_session ();
402
403    /**
404     * Close a PAM session.
405     *
406     * An error will be thrown on failure.
407     */
408    virtual void
409    close_session ();
410
411    /**
412     * Set new authentication status.  If newauth > oldauth, newauth
413     * is returned, otherwise oldauth is returned.  This is to ensure
414     * the authentication status can never be decreased (relaxed).
415     *
416     * @param oldauth the current authentication status.
417     * @param newauth the new authentication status.
418     * @returns the new authentication status.
419     */
420    static status
421    change_auth (status oldauth,
422                 status newauth)
423    {
424      /* Ensure auth level always escalates. */
425      if (newauth > oldauth)
426        return newauth;
427      else
428        return oldauth;
429    }
430
431    /**
432     * Check if PAM is initialised (i.e. start has been called).
433     * @returns true if initialised, otherwise false.
434     */
435    virtual bool
436    is_initialised () const = 0;
437
438  protected:
439    /// The PAM service name.
440    const std::string  service;
441    /// The uid to run as.
442    uid_t              uid;
443    /// The gid to run as.
444    gid_t              gid;
445    /// The user name to run as.
446    std::string        user;
447    /// The command to run.
448    string_list        command;
449    /// The home directory.
450    std::string        home;
451    /// The directory to run in.
452    std::string        wd;
453    /// The user shell to run.
454    std::string        shell;
455    /// The user environment to set.
456    environment        user_environment;
457    /// The uid requesting authentication.
458    uid_t              ruid;
459    /// The gid requesting authentication.
460    gid_t              rgid;
461    /// The user name requesting authentication.
462    std::string        ruser;
463    /// The group name requesting authentication.
464    std::string        rgroup;
465#ifndef SBUILD_FEATURE_PAM
466    /// Minimal environment.
467    environment        auth_environment;
468#endif // !SBUILD_FEATURE_PAM
469    /// The message verbosity.
470    verbosity          message_verbosity;
471  };
472
473}
474
475#endif /* SBUILD_AUTH_H */
476
477/*
478 * Local Variables:
479 * mode:C++
480 * End:
481 */
Note: See TracBrowser for help on using the repository browser.