@@ -100,12 +100,14 @@ let get_string_field name obj =
100100 member name obj |> to_string
101101
102102let read_command_definitions () =
103+ let () = Logs. debug @@ fun m -> m " Reading command definitions from %s" op_def_file in
103104 let ic = open_in op_def_file in
104105 let data = Yojson.Safe. from_channel ic in
105106 let () = close_in ic in
106107 data
107108
108109let read_permissions () =
110+ let () = Logs. debug @@ fun m -> m " Reading user permissions from %s" permissions_file in
109111 let ic = open_in permissions_file in
110112 let data = Yojson.Safe. from_channel ic in
111113 let () = close_in ic in
@@ -218,13 +220,21 @@ let group_perms_match perms group cmd =
218220
219221let is_admin () =
220222 (* If executed by root, skip all permission checks *)
221- if Unix. getuid () = 0 then true else
222- (* Otherwise, check if the user is a VyOS admin *)
223- let admin_group = Unix. getgrnam vyos_admin_group_name in
224- let user_groups = Unix. getgroups () in
225- match (Array. find_opt ((= ) admin_group.gr_gid) user_groups) with
226- | Some _ -> true
227- | None -> false
223+ if Unix. getuid () = 0 then
224+ let () = Logs. debug @@ fun m -> m " The user is root, permission checks will be skipped" in
225+ true
226+ else begin
227+ (* Otherwise, check if the user is a VyOS admin *)
228+ let admin_group = Unix. getgrnam vyos_admin_group_name in
229+ let user_groups = Unix. getgroups () in
230+ match (Array. find_opt ((= ) admin_group.gr_gid) user_groups) with
231+ | Some _ ->
232+ let () = Logs. debug @@ fun m -> m " The user is a VyOS admin, permission checks will be skipped" in
233+ true
234+ | None ->
235+ let () = Logs. debug @@ fun m -> m " The user does not have VyOS admin permissions" in
236+ false
237+ end
228238
229239let has_unsafe_characters cmd =
230240 (* XXX: this function is highly restrictive now,
@@ -244,6 +254,7 @@ let has_unsafe_characters cmd =
244254 - 'add system image': requires non-alphanumeric characters
245255 for URLs.
246256 *)
257+ let () = Logs. debug @@ fun m -> m " Checking the command for unsafe characters" in
247258 try
248259 let _ = Pcre2. exec ~pat: {| [^ a- zA- Z0 -9_ \- \.\s]| } cmd in
249260 let () =
@@ -270,10 +281,13 @@ let is_admin_only_command cmd =
270281 if p = t then prefix_matches ps ts
271282 else false
272283 in
284+ let () = Logs. debug @@ fun m -> m " Checking if the command is admin-only" in
273285 let res = List. find_opt (fun p -> prefix_matches p cmd) admin_only_commands in
274286 match res with
275287 | None -> false
276- | Some _ -> true
288+ | Some _ ->
289+ let () = Logs. debug @@ fun m -> m " Commandis reserved for admins" in
290+ true
277291
278292let check_command_permissions perms cmd =
279293 let rec aux perms groups cmd =
@@ -283,6 +297,7 @@ let check_command_permissions perms cmd =
283297 if group_perms_match perms g cmd then ()
284298 else aux perms gs cmd
285299 in
300+ let () = Logs. debug @@ fun m -> m " Checking if the user is allowed to execute the command" in
286301 (* VyOS admins can execute any commands without restrictions *)
287302 if is_admin () then () else
288303 (* Operators are not allowed to execute commands
@@ -321,7 +336,6 @@ let render_command opts env command_tmpl =
321336let run_external_command opts env command_tmpl =
322337 let cmd = render_command opts env command_tmpl in
323338 if opts.dry_run then Printf. printf " %s\n %!" cmd else
324- let () = Logs. debug @@ fun m -> m " Command to be executed %s" cmd in
325339 (* Get the user database entry to populate the basic environment from:
326340 we cannot trust an unprivileged user to supply $SHELL
327341 or allow them to impersonate someone else by setting custom $LOGNAME, etc.
@@ -354,6 +368,7 @@ let run_external_command opts env command_tmpl =
354368 so that a user trying to do PATH=/bad/place vyos-op-run
355369 cannot achieve anything with that trick.
356370 *)
371+ let () = Logs. debug @@ fun m -> m " Executing Unix command: %s" cmd in
357372 let res = Unix. execve shell [|shell; " -c" ; cmd|] env in
358373 match res with
359374 | Unix. WEXITED 0 -> ()
@@ -487,7 +502,7 @@ let () =
487502 let () = setup_logging debug in
488503 let op_defs = read_command_definitions () in
489504 let permissions = read_permissions () in
490- let () = Logs .debug @@ fun m -> m " Executing VyOS command [%s]" ( String. concat " " args) in
505+ let () = Logs .debug @@ fun m -> m " Executing VyOS command [%s]" options.vyos_command in
491506 try
492507 check_command_permissions permissions args;
493508 Unix. setuid 0 ;
@@ -505,6 +520,12 @@ let () =
505520 | Incomplete_command ->
506521 Printf. fprintf stderr " Incomplete command: %s\n " options.vyos_command;
507522 exit 2
523+ | Sys_error msg ->
524+ Printf. fprintf stderr " System error: %s" msg;
525+ exit 255
526+ | Unix. Unix_error (err , func , _ ) ->
527+ Printf. fprintf stderr " Failed to execute Unix call %s: %s" func (Unix. error_message err);
528+ exit 255
508529 | Internal_error msg ->
509530 Printf. fprintf stderr " Internal error: %s\n " msg;
510531 exit 255
0 commit comments