user.rs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. use core::ptr::null;
  2. use libc::{uid_t, gid_t, c_char};
  3. use ::types::passwd;
  4. use syscall::{Error, ENOENT};
  5. use alloc::string::{String, ToString};
  6. use core::str::FromStr;
  7. static mut PASSWD: passwd = passwd {
  8. pw_name: null(),
  9. pw_passwd: null(),
  10. pw_uid: 0,
  11. pw_gid: 0,
  12. pw_gecos: null(),
  13. pw_dir: null(),
  14. pw_shell: null()
  15. };
  16. static mut PW_NAME: Option<String> = None;
  17. static mut PW_PASSWD: Option<String> = None;
  18. static mut PW_GECOS: Option<String> = None;
  19. static mut PW_DIR: Option<String> = None;
  20. static mut PW_SHELL: Option<String> = None;
  21. macro_rules! try_opt {
  22. ($e:expr) =>(
  23. match $e {
  24. Some(v) => v,
  25. None => return None,
  26. }
  27. )
  28. }
  29. unsafe fn parse_passwd(pwd: &str) -> Option<*const passwd> {
  30. let mut parts = pwd.split(';');
  31. let name = try_opt!(parts.next()).to_string() + "\0";
  32. let passwd = try_opt!(parts.next()).to_string() + "\0";
  33. let uid = if let Ok(uid) = uid_t::from_str(try_opt!(parts.next())) {
  34. uid
  35. } else {
  36. return None
  37. };
  38. let gid = if let Ok(gid) = gid_t::from_str(try_opt!(parts.next())) {
  39. gid
  40. } else {
  41. return None
  42. };
  43. let gecos = try_opt!(parts.next()).to_string() + "\0";
  44. let dir = try_opt!(parts.next()).to_string() + "\0";
  45. let shell = try_opt!(parts.next()).to_string() + "\0";
  46. PASSWD = passwd {
  47. pw_name: name.as_ptr() as *const c_char,
  48. pw_passwd: passwd.as_ptr() as *const c_char,
  49. pw_uid: uid,
  50. pw_gid: gid,
  51. pw_gecos: gecos.as_ptr() as *const c_char,
  52. pw_dir: dir.as_ptr() as *const c_char,
  53. pw_shell: shell.as_ptr() as *const c_char
  54. };
  55. PW_NAME = Some(name);
  56. PW_PASSWD = Some(passwd);
  57. PW_GECOS = Some(gecos);
  58. PW_DIR = Some(dir);
  59. PW_SHELL = Some(shell);
  60. Some(&PASSWD as *const _)
  61. }
  62. libc_fn!(unsafe getpwnam(name: *const c_char) -> Result<*const passwd> {
  63. if let Ok(passwd_string) = String::from_utf8(::file_read_all("/etc/passwd")?) {
  64. for line in passwd_string.lines() {
  65. if line.split(';').nth(0).map(str::as_bytes) == Some(::cstr_to_slice(name)) {
  66. if let Some(pass) = parse_passwd(line) {
  67. return Ok(pass);
  68. }
  69. }
  70. }
  71. }
  72. Err(Error::new(ENOENT))
  73. });
  74. libc_fn!(unsafe getpwuid(uid: uid_t) -> Result<*const passwd> {
  75. if let Ok(passwd_string) = String::from_utf8(::file_read_all("/etc/passwd")?) {
  76. for line in passwd_string.lines() {
  77. if line.split(';').nth(2).map(uid_t::from_str) == Some(Ok(uid)) {
  78. if let Some(pass) = parse_passwd(line) {
  79. return Ok(pass);
  80. }
  81. }
  82. }
  83. }
  84. Err(Error::new(ENOENT))
  85. });