Skip to content

Commit

Permalink
auth
Browse files Browse the repository at this point in the history
  • Loading branch information
edwintorok committed Oct 9, 2023
1 parent d303123 commit aecf87c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 8 deletions.
42 changes: 35 additions & 7 deletions ocaml/auth/pam.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,41 @@

type pam_handle

external authenticate_start : unit -> pam_handle = "stub_XA_mh_authorize_start"
external authorize_start : unit -> pam_handle = "stub_XA_mh_authorize_start"

external authenticate_stop : pam_handle -> unit = "stub_XA_mh_authorize_stop"
external authorize_stop : pam_handle -> unit = "stub_XA_mh_authorize_stop"

external authorize : pam_handle -> string -> string -> unit
= "stub_XA_mh_authorize"

type t =
{ handle: pam_handle option Atomic.t
; owner: Thread.t
}

let authorize_start () =
let pam_handle = authorize_start () in
{ handle = Atomic.make (Some pam_handle)
; owner = Thread.self ()
}

let check_handle t =
(* handle can only be used in same thread that created it *)
assert (Thread.id (Thread.self ()) = Thread.id t.owner);
match Atomic.get t.handle with
| Some h -> h
| None -> assert false (* use after free *)

let authorize_stop t =
let handle = check_handle t in
(* even if authorize_stop would fail we can only call it once, so mark it as freed now *)
Atomic.set t.handle None;
authorize_stop handle

let authorize t username password =
let handle = check_handle t in
authorize handle username password

(* TODO: make this configurable in Xapi_globs *)
(* because this is initialized on startup this is not settable from a config file yet! *)
(*let auth_workers : (pam_handle, unit) Threadpool.t =
Expand All @@ -30,14 +58,14 @@ let () = at_exit (fun () -> Threadpool.shutdown auth_workers)
*)

let authenticate user password =
let handle = authenticate_start () in
Fun.protect ~finally:(fun () -> authenticate_stop handle) @@ fun () ->
let handle = authorize_start () in
Fun.protect ~finally:(fun () -> authorize_stop handle) @@ fun () ->
authorize handle user password

external change_password : pam_handle -> string -> string -> unit
= "stub_XA_mh_chpasswd"

let change_password user password =
let handle = authenticate_start () in
Fun.protect ~finally:(fun () -> authenticate_stop handle) @@ fun () ->
change_password handle user password
let handle = authorize_start () in
Fun.protect ~finally:(fun () -> authorize_stop handle) @@ fun () ->
change_password (check_handle handle) user password
6 changes: 5 additions & 1 deletion ocaml/auth/xa_auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@ int XA_mh_authorize (pam_handle_t *pamh, const char *username, const char *passw
rc = pam_acct_mgmt(pamh, PAM_DISALLOW_NULL_AUTHTOK);

exit:
if (rc != PAM_SUCCESS) {
if (PAM_ABORT == rc) {
/* according to manpage we must call pam_end immediately. */
*error = "PAM_ABORT";
rc = XA_ABORT;
} else if (rc != PAM_SUCCESS) {
if (error) *error = pam_strerror(pamh, rc);
rc = XA_ERR_EXTERNAL;
}
Expand Down
1 change: 1 addition & 0 deletions ocaml/auth/xa_auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <security/pam_appl.h>
#define XA_SUCCESS 0
#define XA_ERR_EXTERNAL 1
#define XA_ABORT 2

pam_handle_t *XA_mh_authorize_start (const char **error);
int XA_mh_authorize_stop (pam_handle_t *pamh, int rc, const char **error);
Expand Down
5 changes: 5 additions & 0 deletions ocaml/auth/xa_auth_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,15 @@ CAMLprim value stub_XA_mh_authorize(value ml_handle, value username, value passw

caml_enter_blocking_section();
rc = XA_mh_authorize(handle, c_username, c_password, &error);
if (XA_ABORT == rc)
XA_mh_authorize_stop(handle, rc, NULL);
free(c_username);
free(c_password);
caml_leave_blocking_section();

if (XA_ABORT == rc)
*((pam_handle_t** ) Data_abstract_val(ml_handle)) = NULL;

if (rc != XA_SUCCESS)
caml_failwith(error ? error : "Unknown error");
CAMLreturn(ret);
Expand Down

0 comments on commit aecf87c

Please sign in to comment.