3 use serde_json
::{json, Value}
;
5 use proxmox
::api
::{api, RpcEnvironment}
;
6 use proxmox
::api
::router
::{Router, SubdirMap}
;
7 use proxmox
::{sortable, identity}
;
8 use proxmox
::{http_err, list_subdirs_api_method}
;
11 use crate::tools
::ticket
::*;
12 use crate::auth_helpers
::*;
13 use crate::api2
::types
::*;
19 fn authenticate_user(username
: &str, password
: &str) -> Result
<(), Error
> {
21 let ticket_lifetime
= tools
::ticket
::TICKET_LIFETIME
;
23 if password
.starts_with("PBS:") {
24 if let Ok((_age
, Some(ticket_username
))) = tools
::ticket
::verify_rsa_ticket(public_auth_key(), "PBS", password
, None
, -300, ticket_lifetime
) {
25 if ticket_username
== username
{
28 bail
!("ticket login failed - wrong username");
33 crate::auth
::authenticate_user(username
, password
)
40 schema
: PROXMOX_USER_ID_SCHEMA
,
43 schema
: PASSWORD_SCHEMA
,
51 description
: "User name.",
55 description
: "Auth ticket.",
57 CSRFPreventionToken
: {
59 description
: "Cross Site Request Forgery Prevention Token.",
65 /// Create or verify authentication ticket.
67 /// Returns: An authentication ticket with additional infos.
68 fn create_ticket(username
: String
, password
: String
) -> Result
<Value
, Error
> {
69 match authenticate_user(&username
, &password
) {
72 let ticket
= assemble_rsa_ticket( private_auth_key(), "PBS", Some(&username
), None
)?
;
74 let token
= assemble_csrf_prevention_token(csrf_secret(), &username
);
76 log
::info
!("successful auth for user '{}'", username
);
81 "CSRFPreventionToken": token
,
85 let client_ip
= "unknown"; // $rpcenv->get_client_ip() || '';
86 log
::error
!("authentication failure; rhost={} user={} msg={}", client_ip
, username
, err
.to_string());
87 Err(http_err
!(UNAUTHORIZED
, "permission check failed.".into()))
96 schema
: PROXMOX_USER_ID_SCHEMA
,
99 schema
: PASSWORD_SCHEMA
,
104 /// Change user password
106 /// Each user is allowed to change his own password. Superuser
107 /// can change all passwords.
111 rpcenv
: &mut dyn RpcEnvironment
,
112 ) -> Result
<Value
, Error
> {
114 let current_user
= rpcenv
.get_user()
115 .ok_or_else(|| format_err
!("unknown user"))?
;
117 let mut allowed
= userid
== current_user
;
119 if userid
== "root@pam" { allowed = true; }
122 bail
!("you are not authorized to change the password.");
125 let (username
, realm
) = crate::auth
::parse_userid(&userid
)?
;
126 let authenticator
= crate::auth
::lookup_authenticator(&realm
)?
;
127 authenticator
.store_password(&username
, &password
)?
;
133 const SUBDIRS
: SubdirMap
= &sorted
!([
134 ("acl", &acl
::ROUTER
),
136 "password", &Router
::new()
137 .put(&API_METHOD_CHANGE_PASSWORD
)
140 "ticket", &Router
::new()
141 .post(&API_METHOD_CREATE_TICKET
)
143 ("domains", &domain
::ROUTER
),
144 ("users", &user
::ROUTER
),
147 pub const ROUTER
: Router
= Router
::new()
148 .get(&list_subdirs_api_method
!(SUBDIRS
))