sudo_plugin/errors.rs
1// Copyright 2018 Square Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12// implied. See the License for the specific language governing
13// permissions and limitations under the License.
14
15//! The collection of `Error` types used by this library.
16
17// TODO: use error types as directly defined by sudo_plugin(8).
18
19// TODO: remove when error_chain is updated to compile cleanly
20#![allow(bare_trait_objects)]
21#![allow(renamed_and_removed_lints)]
22#![allow(single_use_lifetimes)]
23#![allow(variant_size_differences)]
24
25use crate::version::Version;
26
27use std::fmt;
28
29use sudo_plugin_sys as sys;
30use libc::c_int;
31use error_chain::*;
32
33pub use error_chain::bail;
34
35/// The list of supported facilities to communicate with the end-user.
36#[derive(Clone, Copy, Debug)]
37pub enum IoFacility {
38 /// A printf-style function that can be used for one-way communication
39 /// with the invoking user.
40 PluginPrintf,
41
42 /// A more complicated facility that enables two-way communication
43 /// with the invoking user.
44 Conversation,
45}
46
47impl fmt::Display for IoFacility {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 match *self {
50 IoFacility::PluginPrintf => write!(f, "plugin_printf"),
51 IoFacility::Conversation => write!(f, "conversation"),
52 }
53 }
54}
55
56error_chain! {
57 errors {
58 /// An error which can be returned when the requsested plugin API
59 /// version is incompatible with the version implemented by this
60 /// library.
61 UnsupportedApiVersion(cur: Version) {
62 description("sudo doesn't support the minimum plugin API version required by this plugin"),
63 display("sudo called this plugin with an API version of {}, but a minimum of {} is required", cur, Version::minimum()),
64 }
65
66 /// An error which can be returned when there's a general error
67 /// when initiailizing the plugin.
68 Uninitialized {
69 description("the plugin failed to initialize"),
70 display("the plugin failed to initialize"),
71 }
72
73 /// An error which can be returned if the user is not authorized
74 /// to invoke sudo with the provided command and/or options.
75 Unauthorized {
76 description("command unauthorized"),
77 display("command unauthorized"),
78 }
79 }
80}
81
82/// A trait that is implemented by all Error types in this library, which
83/// allows any error to be converted to its corresponding integer error
84/// code as understood by the sudo plugin API.
85///
86/// The sudo plugin API understands the following error codes:
87///
88/// * 1: Success
89/// * 0: Failure
90/// * -1: General error
91/// * -2: Usage error
92pub trait AsSudoPluginRetval {
93 /// Converts the error to its corresponding integer error code for
94 /// the I/O plugin `open` function.
95 fn as_sudo_io_plugin_open_retval(&self) -> c_int;
96
97 /// Converts the error to its corresponding integer error code for
98 /// the I/O plugin `log_*` suite of functions.
99 fn as_sudo_io_plugin_log_retval(&self) -> c_int;
100}
101
102impl<T, E: AsSudoPluginRetval> AsSudoPluginRetval for ::std::result::Result<T, E> {
103 fn as_sudo_io_plugin_open_retval(&self) -> c_int {
104 match *self {
105 Ok(_) => sys::SUDO_PLUGIN_OPEN_SUCCESS,
106 Err(ref e) => e.as_sudo_io_plugin_open_retval(),
107 }
108 }
109
110 fn as_sudo_io_plugin_log_retval(&self) -> c_int {
111 match *self {
112 Ok(_) => sys::SUDO_PLUGIN_OPEN_SUCCESS,
113 Err(ref e) => e.as_sudo_io_plugin_log_retval(),
114 }
115 }
116}
117
118impl AsSudoPluginRetval for Error {
119 fn as_sudo_io_plugin_open_retval(&self) -> c_int {
120 match *self {
121 Error(ErrorKind::Unauthorized, _) => sys::SUDO_PLUGIN_OPEN_GENERAL_ERROR,
122 Error(_, _) => sys::SUDO_PLUGIN_OPEN_FAILURE,
123 }
124 }
125
126 fn as_sudo_io_plugin_log_retval(&self) -> c_int {
127 match *self {
128 Error(ErrorKind::Unauthorized, _) => sys::SUDO_PLUGIN_OPEN_FAILURE,
129 Error(_, _) => sys::SUDO_PLUGIN_OPEN_GENERAL_ERROR,
130 }
131 }
132}