1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
use std::ffi::CString; use login_cap_sys as ffi; mod login; mod error; pub use error::Error; pub use login::*; /// Bit flags which can be returned by authenticate()/auth_scan() #[repr(u32)] pub enum AuthFlags { /// User authenticated Okay = ffi::AUTH_OKAY, /// Authenticated as root RootOkay = ffi::AUTH_ROOTOKAY, /// Secure login Secure = ffi::AUTH_SECURE, /// Silent rejection Silent = ffi::AUTH_SILENT, /// A challenge was given Challenge = ffi::AUTH_CHALLENGE, /// Account expired Expired = ffi::AUTH_EXPIRED, /// Password expired PwExpired = ffi::AUTH_PWEXPIRED, /// (AUTH_OKAY | AUTH_ROOTOKAY | AUTH_SECURE) Allow = ffi::AUTH_ALLOW, } /// Check whether the path is secure /// /// Returns Ok(true) if the path is secure, Ok(false) otherwise /// /// Returns Err if an error occurs /// /// Example: /// /// ```rust /// # use login_cap::secure_path; /// assert!(secure_path("/etc/passwd").unwrap()); /// assert_eq!(secure_path("/etc/").unwrap(), false); /// ``` /// /// From `login_getclass(3)`: /// /// ```no_build /// The secure_path() function takes a path name and returns 0 if the path /// name is secure, -1 if not. To be secure a path must exist, be a regular /// file (and not a directory), owned by root, and only writable by the owner /// (root). /// ``` pub fn secure_path(path: &str) -> Result<bool, Error> { let path_ptr = CString::new(path)?.into_raw(); // safety: pointer is guaranteed non-null, and points to valid memory let ret = unsafe { ffi::secure_path(path_ptr) }; // safety: pointer is guaranteed non-null, and should still point to valid memory // Recreate a CString to free allocated memory unsafe { CString::from_raw(path_ptr) }; Ok(ret == 0) } /// Set the class context using resources defined by flags /// /// Example: /// /// ```rust /// # use login_cap::{setclasscontext, LoginFlags}; /// assert!(setclasscontext("default", LoginFlags::SetEnv.into()).is_ok()); /// assert!(setclasscontext("default", LoginFlags::SetEnv | LoginFlags::SetUmask).is_ok()); /// // invalid class /// assert!(setclasscontext("not-a-class", LoginFlags::SetEnv.into()).is_err()); /// ``` /// /// From `login_getclass(3)`: /// ///```no_build /// The setclasscontext() function takes class, the name of a user class, and /// sets the resources defined by that class according to flags. Only the /// LOGIN_SETPATH, LOGIN_SETPRIORITY, LOGIN_SETRESOURCES, and LOGIN_SETUMASK /// bits are used (see setusercontext() below). It returns 0 on success and /// -1 on failure. ///``` pub fn setclasscontext(class: &str, flags: LoginFlagsOr) -> Result<(), Error> { let class_ptr = CString::new(class)?.into_raw(); // safety: pointer is guaranteed non-null, and points to valid memory let ret = unsafe { ffi::setclasscontext(class_ptr, flags.into()) }; // safety: pointer is guaranteed non-null, and should still point to valid memory // Recreate a CString to free allocated memory unsafe { CString::from_raw(class_ptr) }; if ret == -1 { Err(Error::SetClassContext) } else { Ok(()) } }