Skip to content

Commit 6159aa3

Browse files
author
Colin
authored
Merge pull request #5901 from contificate/CP-50426
CP-50426: Trace external authentication modules
2 parents 787a01e + 4acf937 commit 6159aa3

File tree

11 files changed

+170
-106
lines changed

11 files changed

+170
-106
lines changed

ocaml/tests/testauthx.ml

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,22 @@ let usage () =
2020
exit 1
2121

2222
let _ =
23+
let __context = Context.make __MODULE__ in
2324
if Array.length Sys.argv <> 3 then usage () ;
2425
let username = Sys.argv.(1) and password = Sys.argv.(2) in
2526
let hr x = print_endline ("-----------------------------\n" ^ x) in
2627
(* should return 2037 *)
2728
hr ("TEST 1a. Authx.get_subject_identifier " ^ username) ;
28-
let userid = AuthX.methods.get_subject_identifier username in
29+
let userid = AuthX.methods.get_subject_identifier ~__context username in
2930
print_endline ("userid=" ^ userid) ;
3031
hr
3132
("TEST 1b. AuthX.methods.get_subject_identifier "
3233
^ username
3334
^ "_werq (unknown subject)"
3435
) ;
35-
try print_endline (AuthX.methods.get_subject_identifier (username ^ "_werq"))
36+
try
37+
print_endline
38+
(AuthX.methods.get_subject_identifier ~__context (username ^ "_werq"))
3639
with Not_found -> (
3740
print_endline "subject Not_found, as expected" ;
3841
(* should return a list of groups that subjectid 1000 (a user) belongs to *)
@@ -42,7 +45,7 @@ let _ =
4245
^ " (a user subject)"
4346
) ;
4447
let conc x y = x ^ "," ^ y in
45-
let groupid_list = AuthX.methods.query_group_membership userid in
48+
let groupid_list = AuthX.methods.query_group_membership ~__context userid in
4649
print_endline (List.fold_left conc "" groupid_list) ;
4750
(* should return a list of groups that subjectid 10024 (a group) belongs to *)
4851
let agroup = List.hd groupid_list in
@@ -52,23 +55,31 @@ let _ =
5255
^ " (a group subject)"
5356
) ;
5457
print_endline
55-
(List.fold_left conc "" (AuthX.methods.query_group_membership agroup)) ;
58+
(List.fold_left conc ""
59+
(AuthX.methods.query_group_membership ~__context agroup)
60+
) ;
5661
hr "TEST 2c. AuthX.methods.query_group_membership u999 (unknown subject)" ;
5762
try
5863
print_endline
59-
(List.fold_left conc "" (AuthX.methods.query_group_membership "u999"))
64+
(List.fold_left conc ""
65+
(AuthX.methods.query_group_membership ~__context "u999")
66+
)
6067
with Not_found -> (
6168
print_endline "subject Not_found, as expected." ;
6269
hr "TEST 2d. AuthX.methods.query_group_membership a999 (unknown subject)" ;
6370
try
6471
print_endline
65-
(List.fold_left conc "" (AuthX.methods.query_group_membership "a999"))
72+
(List.fold_left conc ""
73+
(AuthX.methods.query_group_membership ~__context "a999")
74+
)
6675
with Not_found -> (
6776
print_endline "subject Not_found, as expected." ;
6877
hr "TEST 2e. AuthX.methods.query_group_membership 999 (unknown subject)" ;
6978
try
7079
print_endline
71-
(List.fold_left conc "" (AuthX.methods.query_group_membership "999"))
80+
(List.fold_left conc ""
81+
(AuthX.methods.query_group_membership ~__context "999")
82+
)
7283
with Not_found -> (
7384
print_endline "subject Not_found, as expected." ;
7485
(* should return a list with information about subject_id 1000 (a user)*)
@@ -77,7 +88,9 @@ let _ =
7788
^ userid
7889
^ " (a user)"
7990
) ;
80-
let infolist1 = AuthX.methods.query_subject_information userid in
91+
let infolist1 =
92+
AuthX.methods.query_subject_information ~__context userid
93+
in
8194
for i = 0 to List.length infolist1 - 1 do
8295
let print_elems (e1, e2) = print_endline (e1 ^ ": " ^ e2) in
8396
print_elems (List.nth infolist1 i)
@@ -88,7 +101,9 @@ let _ =
88101
^ agroup
89102
^ " (a group)"
90103
) ;
91-
let infolist1 = AuthX.methods.query_subject_information agroup in
104+
let infolist1 =
105+
AuthX.methods.query_subject_information ~__context agroup
106+
in
92107
for i = 0 to List.length infolist1 - 1 do
93108
let print_elems (e1, e2) = print_endline (e1 ^ ": " ^ e2) in
94109
print_elems (List.nth infolist1 i)
@@ -98,7 +113,9 @@ let _ =
98113
"TEST 3c. AuthX.methods.query_subject_information u999 (unknown \
99114
subject)" ;
100115
try
101-
let infolist1 = AuthX.methods.query_subject_information "u999" in
116+
let infolist1 =
117+
AuthX.methods.query_subject_information ~__context "u999"
118+
in
102119
for i = 0 to List.length infolist1 - 1 do
103120
let print_elems (e1, e2) = print_endline (e1 ^ ": " ^ e2) in
104121
print_elems (List.nth infolist1 i)
@@ -110,7 +127,9 @@ let _ =
110127
"TEST 3d. AuthX.methods.query_subject_information a999 (unknown \
111128
subject)" ;
112129
try
113-
let infolist1 = AuthX.methods.query_subject_information "a999" in
130+
let infolist1 =
131+
AuthX.methods.query_subject_information ~__context "a999"
132+
in
114133
for i = 0 to List.length infolist1 - 1 do
115134
let print_elems (e1, e2) = print_endline (e1 ^ ": " ^ e2) in
116135
print_elems (List.nth infolist1 i)
@@ -122,7 +141,9 @@ let _ =
122141
"TEST 3e. AuthX.methods.query_subject_information 999 (unknown \
123142
subject)" ;
124143
try
125-
let infolist1 = AuthX.methods.query_subject_information "999" in
144+
let infolist1 =
145+
AuthX.methods.query_subject_information ~__context "999"
146+
in
126147
for i = 0 to List.length infolist1 - 1 do
127148
let print_elems (e1, e2) = print_endline (e1 ^ ": " ^ e2) in
128149
print_elems (List.nth infolist1 i)
@@ -134,8 +155,8 @@ let _ =
134155
^ username
135156
) ;
136157
print_endline
137-
(AuthX.methods.authenticate_username_password username
138-
password
158+
(AuthX.methods.authenticate_username_password ~__context
159+
username password
139160
)
140161
)
141162
)

ocaml/xapi/auth_signature.ml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,21 @@ type t = {
6767
the auth module/service itself -- e.g. maybe a SID or something in the AD case).
6868
Raises auth_failure if authentication is not successful
6969
*)
70-
authenticate_username_password: string -> string -> string
70+
authenticate_username_password:
71+
__context:Context.t -> string -> string -> string
7172
; (* subject_id Authenticate_ticket(string ticket)
7273
7374
As above but uses a ticket as credentials (i.e. for single sign-on)
7475
*)
75-
authenticate_ticket: string -> string
76+
authenticate_ticket: __context:Context.t -> string -> string
7677
; (* subject_id get_subject_identifier(string subject_name)
7778
7879
Takes a subject_name (as may be entered into the XenCenter UI when defining subjects --
7980
see Access Control wiki page); and resolves it to a subject_id against the external
8081
auth/directory service.
8182
Raises Not_found if authentication is not succesful.
8283
*)
83-
get_subject_identifier: string -> string
84+
get_subject_identifier: __context:Context.t -> string -> string
8485
; (* ((string*string) list) query_subject_information(string subject_identifier)
8586
8687
Takes a subject_identifier and returns the user record from the directory service as
@@ -91,15 +92,16 @@ type t = {
9192
it's a string*string list anyway for possible future expansion.
9293
Raises Not_found if subject_id cannot be resolved by external auth service
9394
*)
94-
query_subject_information: string -> (string * string) list
95+
query_subject_information:
96+
__context:Context.t -> string -> (string * string) list
9597
; (* (string list) query_group_membership(string subject_identifier)
9698
9799
Takes a subject_identifier and returns its group membership (i.e. a list of subject
98100
identifiers of the groups that the subject passed in belongs to). The set of groups returned
99101
_must_ be transitively closed wrt the is_member_of relation if the external directory service
100102
supports nested groups (as AD does for example)
101103
*)
102-
query_group_membership: string -> string list
104+
query_group_membership: __context:Context.t -> string -> string list
103105
; (*
104106
In addition, there are some event hooks that auth modules implement as follows:
105107
*)
@@ -118,26 +120,26 @@ type t = {
118120
explicitly filter any one-time credentials [like AD username/password for example] that it
119121
does not need long-term.]
120122
*)
121-
on_enable: (string * string) list -> unit
123+
on_enable: __context:Context.t -> (string * string) list -> unit
122124
; (* unit on_disable()
123125
124126
Called internally by xapi _on each host_ when a client disables an auth service via the XenAPI.
125127
The hook will be called _before_ the Pool configuration fields relating to the external-auth
126128
service are cleared (i.e. so you can access the config params you need from the pool metadata
127129
within the body of the on_disable method)
128130
*)
129-
on_disable: (string * string) list -> unit
131+
on_disable: __context:Context.t -> (string * string) list -> unit
130132
; (* unit on_xapi_initialize(bool system_boot)
131133
132134
Called internally by xapi whenever it starts up. The system_boot flag is true iff xapi is
133135
starting for the first time after a host boot
134136
*)
135-
on_xapi_initialize: bool -> unit
137+
on_xapi_initialize: __context:Context.t -> bool -> unit
136138
; (* unit on_xapi_exit()
137139
138140
Called internally when xapi is doing a clean exit.
139141
*)
140-
on_xapi_exit: unit -> unit
142+
on_xapi_exit: __context:Context.t -> unit -> unit
141143
}
142144

143145
(* Auth modules must implement this signature:*)

ocaml/xapi/authx.ml

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ module D = Debug.Make (struct let name = "extauth_plugin_PAM_NSS" end)
1919

2020
open D
2121

22+
let ( let@ ) = ( @@ )
23+
2224
module AuthX : Auth_signature.AUTH_MODULE = struct
2325
(*
2426
* External Authentication Plugin component
@@ -113,7 +115,8 @@ module AuthX : Auth_signature.AUTH_MODULE = struct
113115
auth/directory service.
114116
Raises Not_found if authentication is not succesful.
115117
*)
116-
let get_subject_identifier subject_name =
118+
let get_subject_identifier ~__context subject_name =
119+
let@ __context = Context.with_tracing ~__context __FUNCTION__ in
117120
try (* looks up list of users*)
118121
"u" ^ getent_idbyname "passwd" subject_name
119122
with Not_found ->
@@ -131,15 +134,16 @@ module AuthX : Auth_signature.AUTH_MODULE = struct
131134
Raises auth_failure if authentication is not successful
132135
*)
133136

134-
let authenticate_username_password username password =
137+
let authenticate_username_password ~__context username password =
138+
let@ __context = Context.with_tracing ~__context __FUNCTION__ in
135139
(* we try to authenticate against our user database using PAM *)
136140
let () =
137141
try
138142
Pam.authenticate username password
139143
(* no exception raised, then authentication succeeded *)
140144
with Failure msg -> raise (Auth_signature.Auth_failure msg)
141145
in
142-
try get_subject_identifier username
146+
try get_subject_identifier ~__context username
143147
with Not_found ->
144148
raise
145149
(Auth_signature.Auth_failure
@@ -155,7 +159,7 @@ module AuthX : Auth_signature.AUTH_MODULE = struct
155159
*)
156160
(* not implemented now, not needed for our tests, only for a *)
157161
(* future single sign-on feature *)
158-
let authenticate_ticket _tgt =
162+
let authenticate_ticket ~__context:_ _tgt =
159163
failwith "authx authenticate_ticket not implemented"
160164

161165
(* ((string*string) list) query_subject_information(string subject_identifier)
@@ -168,7 +172,8 @@ module AuthX : Auth_signature.AUTH_MODULE = struct
168172
it's a string*string list anyway for possible future expansion.
169173
Raises Not_found if subject_id cannot be resolved by external auth service
170174
*)
171-
let query_subject_information subject_identifier =
175+
let query_subject_information ~__context subject_identifier =
176+
let@ __context = Context.with_tracing ~__context __FUNCTION__ in
172177
(* we are expecting an id such as u0, g0, u123 etc *)
173178
if String.length subject_identifier < 2 then raise Not_found ;
174179
match subject_identifier.[0] with
@@ -246,7 +251,8 @@ module AuthX : Auth_signature.AUTH_MODULE = struct
246251
*)
247252
(* in unix, groups cannot contain groups, so we just verify the groups a user *)
248253
(* belongs to and, if that fails, if some group has the required identifier *)
249-
let query_group_membership subject_identifier =
254+
let query_group_membership ~__context subject_identifier =
255+
let@ __context = Context.with_tracing ~__context __FUNCTION__ in
250256
(* 1. first we try to see if our subject identifier is a user id...*)
251257
let sanitized_subject_id = String.escaped subject_identifier in
252258
(* we are expecting an id such as u0, g0, u123 etc *)
@@ -303,7 +309,7 @@ module AuthX : Auth_signature.AUTH_MODULE = struct
303309
explicitly filter any one-time credentials [like AD username/password for example] that it
304310
does not need long-term.]
305311
*)
306-
let on_enable _config_params =
312+
let on_enable ~__context:_ _config_params =
307313
(* nothing to do in this unix plugin, we always have /etc/passwd and /etc/group *)
308314
()
309315

@@ -314,7 +320,7 @@ module AuthX : Auth_signature.AUTH_MODULE = struct
314320
service are cleared (i.e. so you can access the config params you need from the pool metadata
315321
within the body of the on_disable method)
316322
*)
317-
let on_disable _config_params =
323+
let on_disable ~__context:_ _config_params =
318324
(* nothing to disable in this unix plugin, we should not disable /etc/passwd and /etc/group:) *)
319325
()
320326

@@ -323,29 +329,30 @@ module AuthX : Auth_signature.AUTH_MODULE = struct
323329
Called internally by xapi whenever it starts up. The system_boot flag is true iff xapi is
324330
starting for the first time after a host boot
325331
*)
326-
let on_xapi_initialize _system_boot =
332+
let on_xapi_initialize ~__context:_ _system_boot =
327333
(* again, nothing to be initialized here in this unix plugin *)
328334
()
329335

330336
(* unit on_xapi_exit()
331337
332338
Called internally when xapi is doing a clean exit.
333339
*)
334-
let on_xapi_exit () =
340+
let on_xapi_exit ~__context:_ () =
335341
(* nothing to do here in this unix plugin *)
336342
()
337343

338344
(* Implement the single value required for the module signature *)
339345
let methods =
340-
{
341-
Auth_signature.authenticate_username_password
342-
; Auth_signature.authenticate_ticket
343-
; Auth_signature.get_subject_identifier
344-
; Auth_signature.query_subject_information
345-
; Auth_signature.query_group_membership
346-
; Auth_signature.on_enable
347-
; Auth_signature.on_disable
348-
; Auth_signature.on_xapi_initialize
349-
; Auth_signature.on_xapi_exit
350-
}
346+
Auth_signature.
347+
{
348+
authenticate_username_password
349+
; authenticate_ticket
350+
; get_subject_identifier
351+
; query_subject_information
352+
; query_group_membership
353+
; on_enable
354+
; on_disable
355+
; on_xapi_initialize
356+
; on_xapi_exit
357+
}
351358
end

0 commit comments

Comments
 (0)