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

Revision 24167, 13.8 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_SESSION_H
20#define SBUILD_SESSION_H
21
22#include <sbuild/sbuild-auth.h>
23#include <sbuild/sbuild-chroot-config.h>
24#include <sbuild/sbuild-custom-error.h>
25
26#include <string>
27
28#include <signal.h>
29#include <sys/types.h>
30#include <termios.h>
31#include <unistd.h>
32
33namespace sbuild
34{
35
36  /**
37   * Session handler.
38   *
39   * This class provides the session handling for schroot.  It uses
40   * auth, which performs all the necessary PAM actions.  This allows
41   * more sophisticated handling of user authorisation (users, groups,
42   * root-users and root-groups membership in the configuration file)
43   * and session management (setting up the session, entering the
44   * chroot and running the requested command or shell).
45   */
46  class session
47  {
48  public:
49    /// Session operations.
50    enum operation
51      {
52        OPERATION_AUTOMATIC, ///< Begin, end and run a session automatically.
53        OPERATION_BEGIN,     ///< Begin a session.
54        OPERATION_RECOVER,   ///< Recover an existing (but inactive) session.
55        OPERATION_END,       ///< End a session.
56        OPERATION_RUN        ///< Run a command in an existing session.
57      };
58
59    /// Error codes.
60    enum error_code
61      {
62        CHDIR,          ///< Failed to change to directory.
63        CHDIR_FB,       ///< Falling back to directory.
64        CHILD_CORE,     ///< Child dumped core.
65        CHILD_FAIL,     ///< Child exited abnormally (reason unknown)
66        CHILD_FORK,     ///< Failed to fork child.
67        CHILD_SIGNAL,   ///< Child terminated by signal.
68        CHILD_WAIT,     ///< Wait for child failed.
69        CHROOT,         ///< Failed to change root to directory.
70        CHROOT_ALIAS,   ///< No chroot found matching alias.
71        CHROOT_LOCK,    ///< Failed to lock chroot.
72        CHROOT_SETUP,   ///< Setup failed.
73        CHROOT_UNKNOWN, ///< Failed to find chroot.
74        CHROOT_UNLOCK,  ///< Failed to unlock chroot.
75        COMMAND_ABS,    ///< Command must have an absolute path.
76        EXEC,           ///< Failed to execute.
77        GROUP_GET_SUP,  ///< Failed to get supplementary groups.
78        GROUP_GET_SUPC, ///< Failed to get supplementary group count
79        GROUP_SET,      ///< Failed to set group.
80        GROUP_SET_SUP,  ///< Failed to set supplementary groups.
81        GROUP_UNKNOWN,  ///< Group not found.
82        PAM,            ///< PAM error.
83        ROOT_DROP,      ///< Failed to drop root permissions.
84        SET_SESSION_ID, ///< Chroot does not support setting a session ID.
85        SHELL,          ///< Shell not available.
86        SHELL_FB,       ///< Falling back to shell.
87        SIGNAL_CATCH,   ///< Caught signal.
88        SIGNAL_SET,     ///< Failed to set signal handler.
89        USER_SET,       ///< Failed to set user.
90        USER_SWITCH     ///< User switching is not permitted.
91      };
92
93    /// Exception type.
94    typedef custom_error<error_code> error;
95
96    /// A shared_ptr to a chroot_config object.
97    typedef std::tr1::shared_ptr<chroot_config> config_ptr;
98
99    /// A shared_ptr to a session object.
100    typedef std::tr1::shared_ptr<session> ptr;
101
102    /**
103     * The constructor.
104     *
105     * @param service the PAM service name.
106     * @param config a shared_ptr to the chroot configuration.
107     * @param operation the session operation to perform.
108     * @param chroots the chroots to act upon.
109     */
110    session (std::string const& service,
111             config_ptr&        config,
112             operation          operation,
113             string_list const& chroots);
114
115    /// The destructor.
116    virtual ~session ();
117
118    /**
119     * Get the authentication state associated with this session.
120     *
121     * @returns a shared_ptr to the authentication state.
122     */
123    auth::ptr const&
124    get_auth () const;
125
126    /**
127     * Set the authentication state associated with this session.
128     *
129     * @param auth a shared_ptr to the authentication state.
130     */
131    void
132    set_auth (auth::ptr& auth);
133
134    /**
135     * Get the configuration associated with this session.
136     *
137     * @returns a shared_ptr to the configuration.
138     */
139    config_ptr const&
140    get_config () const;
141
142    /**
143     * Set the configuration associated with this session.
144     *
145     * @param config a shared_ptr to the configuration.
146     */
147    void
148    set_config (config_ptr& config);
149
150    /**
151     * Get the chroots to use in this session.
152     *
153     * @returns a list of chroots.
154     */
155    string_list const&
156    get_chroots () const;
157
158    /**
159     * Set the chroots to use in this session.
160     *
161     * @param chroots a list of chroots.
162     */
163    void
164    set_chroots (string_list const& chroots);
165
166    /**
167     * Get the operation this session will perform.
168     *
169     * @returns the operation.
170     */
171    operation
172    get_operation () const;
173
174    /**
175     * Set the operation this session will perform.
176     *
177     * @param operation the operation.
178     */
179    void
180    set_operation (operation operation);
181
182    /**
183     * Get the session identifier.  The session identifier is a unique
184     * string to identify a session.
185     *
186     * @returns the session id.
187     */
188    std::string const&
189    get_session_id () const;
190
191    /**
192     * Set the session identifier.  The session identifier is a unique
193     * string to identify a session.
194     *
195     * @param session_id the session id.
196     */
197    void
198    set_session_id (std::string const& session_id);
199
200    /**
201     * Get the force status of this session.
202     *
203     * @returns true if operation will be forced, otherwise false.
204     */
205    bool
206    get_force () const;
207
208    /**
209     * Set the force status of this session.
210     *
211     * @param force true to force operation, otherwise false.
212     */
213    void
214    set_force (bool force);
215
216    /**
217     * Save terminal state.
218     */
219    void
220    save_termios ();
221
222    /**
223     * Restore terminal state.
224     */
225    void
226    restore_termios ();
227
228    /**
229     * Get the exit (wait) status of the last child process to run in this
230     * session.
231     *
232     * @returns the exit status.
233     */
234    int
235    get_child_status () const;
236
237  protected:
238    /**
239     * Get the chroot authentication properties the user is included in.
240     */
241    void
242    get_chroot_membership (chroot::ptr const& chroot,
243                           bool&              in_users,
244                           bool&              in_root_users,
245                           bool&              in_groups,
246                           bool&              in_root_groups) const;
247
248    /**
249     * Check if authentication is required for a single chroot, taking
250     * users, groups, root-users and root-groups membership into
251     * account.
252     */
253    virtual auth::status
254    get_chroot_auth_status (auth::status status,
255                            chroot::ptr const& chroot) const;
256
257  public:
258    /**
259     * Check if authentication is required, taking users, groups,
260     * root-users and root-groups membership of all chroots specified
261     * into account.
262     */
263    virtual sbuild::auth::status
264    get_auth_status () const;
265
266    /**
267     * Run a session.  The user will be asked for authentication if
268     * required, and then the run_impl virtual method will be called.
269     *
270     * An auth::error will be thrown on failure.
271     */
272    void
273    run ();
274
275  protected:
276    /**
277     * Run a session.  If a command has been specified, this will be
278     * run in each of the specified chroots.  If no command has been
279     * specified, a login shell will run in the specified chroot.
280     *
281     * An error will be thrown on failure.
282     */
283    virtual void
284    run_impl ();
285
286    /**
287     * Get a list of directories to change to when running a login
288     * shell.  Multiple directories are used as fallbacks.
289     *
290     * @returns a list of directories
291     */
292    virtual string_list
293    get_login_directories () const;
294
295    /**
296     * Get a list of directories to change to when running a command
297     * Multiple directories are used as fallbacks.
298     *
299     * @returns a list of directories
300     */
301    virtual string_list
302    get_command_directories () const;
303
304    /**
305     * Get the shell to run.  This finds a suitable shell to run in
306     * the chroot, falling back to /bin/sh if necessary.  Note that it
307     * assumes it is inside the chroot when called.
308     *
309     * @returns the shell.
310     */
311    virtual std::string
312    get_shell () const;
313
314    /**
315     * Get the command to run.
316     *
317     * @param session_chroot the chroot to setup.  This must be
318     * present in the chroot list and the chroot configuration object.
319     * @param file the filename to pass to execve(2).
320     * @param command the argv to pass to execve(2).
321     */
322    virtual void
323    get_command (chroot::ptr& session_chroot,
324                 std::string& file,
325                 string_list& command) const;
326
327    /**
328     * Get the command to run a login shell.
329     *
330     * @param session_chroot the chroot to setup.  This must be
331     * present in the chroot list and the chroot configuration object.
332     * @param file the filename to pass to execve(2).
333     * @param command the argv to pass to execve(2).
334     */
335    virtual void
336    get_login_command (chroot::ptr& session_chroot,
337                       std::string& file,
338                       string_list& command) const;
339
340    /**
341     * Get the command to run a user command.
342     *
343     * @param session_chroot the chroot to setup.  This must be
344     * present in the chroot list and the chroot configuration object.
345     * @param file the filename to pass to execve(2).
346     * @param command the argv to pass to execve(2).
347     */
348    virtual void
349    get_user_command (chroot::ptr& session_chroot,
350                      std::string& file,
351                      string_list& command) const;
352
353  private:
354    /**
355     * Setup a chroot.  This runs all of the commands in setup.d or run.d.
356     *
357     * The environment variables CHROOT_NAME, CHROOT_DESCRIPTION,
358     * CHROOT_LOCATION, AUTH_USER and AUTH_VERBOSITY are set for use in
359     * setup scripts.  See schroot-setup(5) for a complete list.
360     *
361     * An error will be thrown on failure.
362     *
363     * @param session_chroot the chroot to setup.  This must be
364     * present in the chroot list and the chroot configuration object.
365     * @param setup_type the type of setup to perform.
366     */
367    void
368    setup_chroot (chroot::ptr&       session_chroot,
369                  chroot::setup_type setup_type);
370
371    /**
372     * Run command or login shell in the specified chroot.
373     *
374     * An error will be thrown on failure.
375     *
376     * @param session_chroot the chroot to setup.  This must be
377     * present in the chroot list and the chroot configuration object.
378     */
379    void
380    run_chroot (chroot::ptr& session_chroot);
381
382    /**
383     * Run a command or login shell as a child process in the
384     * specified chroot.  This method is only ever to be run in a
385     * child process, and will never return.
386     *
387     * @param session_chroot the chroot to setup.  This must be
388     * present in the chroot list and the chroot configuration object.
389     */
390    void
391    run_child (chroot::ptr& session_chroot);
392
393    /**
394     * Wait for a child process to complete, and check its exit status.
395     *
396     * An error will be thrown on failure.
397     *
398     * @param pid the pid to wait for.
399     * @param child_status the place to store the child exit status.
400     */
401    void
402    wait_for_child (pid_t pid,
403                    int&  child_status);
404
405    /**
406     * Set the SIGHUP handler.
407     *
408     * An error will be thrown on failure.
409     */
410    void
411    set_sighup_handler ();
412
413    /**
414     * Restore the state of SIGHUP prior to setting the handler.
415     */
416    void
417    clear_sighup_handler ();
418
419    /**
420     * Set the SIGTERM handler.
421     *
422     * An error will be thrown on failure.
423     */
424    void
425    set_sigterm_handler ();
426
427    /**
428     * Restore the state of SIGTERM prior to setting the handler.
429     */
430    void
431    clear_sigterm_handler ();
432
433    /**
434     * Set a signal handler.
435     * An error will be thrown on failure.
436     *
437     * @param signal the signal number.
438     * @param saved_signal the location to save the current handler.
439     * @param handler the signal handler to install.
440     */
441    void
442    set_signal_handler (int                signal,
443                        struct sigaction  *saved_signal,
444                        void             (*handler)(int));
445
446    /**
447     * Restore the state of the signal prior to setting the handler.
448     *
449     * @param signal the signal number.
450     * @param saved_signal the location from which to restore the
451     * saved handler.
452     */
453    void
454    clear_signal_handler (int               signal,
455                          struct sigaction *saved_signal);
456
457    /// Authentication state.
458    auth::ptr        authstat;
459    /// The chroot configuration.
460    config_ptr       config;
461    /// The chroots to run the session operation in.
462    string_list      chroots;
463    /// The current chroot status.
464    int              chroot_status;
465    /// Lock status for locks acquired during chroot setup.
466    bool lock_status;
467    /// The child exit status.
468    int              child_status;
469    /// The session operation to perform.
470    operation        session_operation;
471    /// The session identifier.
472    std::string      session_id;
473    /// The session force status.
474    bool             force;
475    /// Signal saved while sighup handler is set.
476    struct sigaction saved_sighup_signal;
477    /// Signal saved while sigterm handler is set.
478    struct sigaction saved_sigterm_signal;
479    /// Saved terminal settings.
480    struct termios saved_termios;
481    /// Are the saved terminal settings valid?
482    bool termios_ok;
483
484  protected:
485    /// Current working directory.
486    std::string      cwd;
487  };
488
489}
490
491#endif /* SBUILD_SESSION_H */
492
493/*
494 * Local Variables:
495 * mode:C++
496 * End:
497 */
Note: See TracBrowser for help on using the repository browser.