summaryrefslogtreecommitdiff
path: root/libs/exec-reauth.c
blob: 74ad99e1fc2361c9b808950644b3bb343bc49a16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

#include <hurd.h>
#include <mach.h>
#include <unistd.h>
#include <hurd/auth.h>
#include <hurd/io.h>
#include <hurd/process.h>
#include <stdio.h>

pid_t
helper_exec_reauth (auth_t newauth, int secure,
		    mach_port_t * ports, unsigned num_ports,
		    mach_port_t * fds, unsigned num_fds,
		    int is_empty, uid_t uid)
{
  pid_t pid = fork ();

  if (pid == 0)
    {
      pid_t parent = getppid ();
      task_t parent_task = pid2task (parent);
      unsigned int i;
      mach_msg_type_name_t foo;
      mach_port_t new_ports[num_ports];
      mach_port_t new_fds[num_fds];
      mach_port_t newauth_new;

      for (i = 0; i < num_ports; ++i)
	{
	  if (ports[i] == MACH_PORT_NULL)
	    continue;
	  mach_port_extract_right (parent_task, ports[i],
				   MACH_MSG_TYPE_MOVE_SEND, &new_ports[i],
				   &foo);
	}

      for (i = 0; i < num_fds; ++i)
	{
	  if (fds[i] == MACH_PORT_NULL)
	    continue;
	  mach_port_extract_right (parent_task, fds[i],
				   MACH_MSG_TYPE_MOVE_SEND, &new_fds[i],
				   &foo);
	}

      mach_port_extract_right (parent_task, newauth, MACH_MSG_TYPE_MOVE_SEND,
			       &newauth_new, &foo);

      error_t err =
	exec_reauth (newauth_new, secure, 0, new_ports, num_ports, new_fds,
		     num_fds);

      proc_setowner (new_ports[INIT_PORT_PROC], uid, is_empty);

      mach_port_insert_right (parent_task, newauth, newauth_new,
			      MACH_MSG_TYPE_MOVE_SEND);

      for (i = 0; i < num_ports; ++i)
	{
	  if (ports[i] == MACH_PORT_NULL)
	    continue;
		   strerror (mach_port_insert_right
			     (parent_task, new_ports[i], ports[i],
			      MACH_MSG_TYPE_MOVE_SEND)));
	}

      for (i = 0; i < num_fds; ++i)
	{
	  if (fds[i] == MACH_PORT_NULL)
	    continue;
		   strerror (mach_port_insert_right
			     (parent_task, new_fds[i], fds[i],
			      MACH_MSG_TYPE_MOVE_SEND)));
	}

      exit (err);
    }

  return (pid);
}

int
exec_reauth_finished (pid_t pid)
{
  int status;
  int ret = waitpid (pid, &status, WNOHANG);

  if (ret > 0)
    {
      status = WEXITSTATUS (status);
    }

  return (ret > 0);
}