users/
lib.rs

1#![warn(missing_copy_implementations)]
2#![warn(missing_docs)]
3#![warn(nonstandard_style)]
4#![warn(trivial_numeric_casts)]
5#![warn(unreachable_pub)]
6#![warn(unused)]
7
8
9//! This is a library for getting information on Unix users and groups. It
10//! supports getting the system users, and creating your own mock tables.
11//!
12//! In Unix, each user has an individual *user ID*, and each process has an
13//! *effective user ID* that says which user’s permissions it is using.
14//! Furthermore, users can be the members of *groups*, which also have names and
15//! IDs. This functionality is exposed in libc, the C standard library, but as
16//! an unsafe Rust interface. This wrapper library provides a safe interface,
17//! using [`User`](struct.user.html) and [`Group`](struct.group.html) types
18//! and functions such as [`get_user_by_uid`](fn.get_user_by_uid.html) instead
19//! of low-level pointers and strings. It also offers basic caching
20//! functionality.
21//!
22//! It does not (yet) offer *editing* functionality; the values returned are
23//! read-only.
24//!
25//!
26//! ## Users
27//!
28//! The function [`get_current_uid`](fn.get_current_uid.html) returns a
29//! `uid_t` value representing the user currently running the program, and the
30//! [`get_user_by_uid`](fn.get_user_by_uid.html) function scans the users
31//! database and returns a `User` with the user’s information. This function
32//! returns `None` when there is no user for that ID. The `uid_t` type is
33//! re-exported from the libc crate.
34//!
35//! A [`User`](struct.User.html) value has the following accessors:
36//!
37//! - **uid:** The user’s ID
38//! - **name:** The user’s name
39//! - **primary_group:** The ID of this user’s primary group
40//!
41//! Here is a complete example that prints out the current user’s name:
42//!
43//! ```
44//! use users::{get_user_by_uid, get_current_uid};
45//!
46//! let user = get_user_by_uid(get_current_uid()).unwrap();
47//! println!("Hello, {}!", user.name().to_string_lossy());
48//! ```
49//!
50//! This code assumes (with `unwrap()`) that the user hasn’t been deleted after
51//! the program has started running. For arbitrary user IDs, this is **not** a
52//! safe assumption: it’s possible to delete a user while it’s running a
53//! program, or is the owner of files, or for that user to have never existed.
54//! So always check the return values!
55//!
56//! There is also a [`get_current_username`](fn.get_current_username.html)
57//! function, as it’s such a common operation that it deserves special
58//! treatment.
59//!
60//!
61//! ## Caching
62//!
63//! Despite the above warning, the users and groups database rarely changes.
64//! While a short program may only need to get user information once, a
65//! long-running one may need to re-query the database many times, and a
66//! medium-length one may get away with caching the values to save on redundant
67//! system calls.
68//!
69//! For this reason, this crate offers a caching interface to the database,
70//! which offers the same functionality while holding on to every result,
71//! caching the information so it can be re-used.
72//!
73//! To introduce a cache, create a new
74//! [`UsersCache`](cache/struct.UsersCache.html). It has functions with the
75//! same names as the ones from earlier. For example:
76//!
77//! ```
78//! use users::{Users, Groups, UsersCache};
79//!
80//! let mut cache = UsersCache::new();
81//! let uid = cache.get_current_uid();
82//! let user = cache.get_user_by_uid(uid).unwrap();
83//! println!("Hello again, {}!", user.name().to_string_lossy());
84//! ```
85//!
86//! This cache is **only additive**: it’s not possible to drop it, or erase
87//! selected entries, as when the database may have been modified, it’s best to
88//! start entirely afresh. So to accomplish this, just start using a new
89//! `UsersCache`.
90//!
91//!
92//! ## Groups
93//!
94//! Finally, it’s possible to get groups in a similar manner.
95//! A [`Group`](struct.Group.html) has the following accessors:
96//!
97//! - **gid:** The group’s ID
98//! - **name:** The group’s name
99//!
100//! And again, a complete example:
101//!
102//! ```no_run
103//! use users::{Users, Groups, UsersCache};
104//!
105//! let mut cache = UsersCache::new();
106//! let group = cache.get_group_by_name("admin").expect("No such group 'admin'!");
107//! println!("The '{}' group has the ID {}", group.name().to_string_lossy(), group.gid());
108//! ```
109//!
110//!
111//! ## Logging
112//!
113//! The `logging` feature, which is on by default, uses the `log` crate to
114//! record all interactions with the operating system.
115//!
116//!
117//! ## Caveats
118//!
119//! You should be prepared for the users and groups tables to be completely
120//! broken: IDs shouldn’t be assumed to map to actual users and groups, and
121//! usernames and group names aren’t guaranteed to map either!
122//!
123//! Use the [`mock`](mock/index.html) module to create custom tables to test
124//! your code for these edge cases.
125
126
127extern crate libc;
128pub use libc::{uid_t, gid_t};
129
130mod base;
131pub use base::{User, Group, os};
132pub use base::{get_user_by_uid, get_user_by_name};
133pub use base::{get_group_by_gid, get_group_by_name};
134pub use base::{get_current_uid, get_current_username};
135pub use base::{get_effective_uid, get_effective_username};
136pub use base::{get_current_gid, get_current_groupname};
137pub use base::{get_effective_gid, get_effective_groupname};
138pub use base::{get_user_groups, group_access_list};
139pub use base::{all_users};
140
141#[cfg(feature = "cache")]
142pub mod cache;
143
144#[cfg(feature = "cache")]
145pub use cache::UsersCache;
146
147#[cfg(feature = "mock")]
148pub mod mock;
149
150pub mod switch;
151
152mod traits;
153pub use traits::{Users, Groups};