#
# \brief  Test for assigning custom UIDs and GIDs to Genode processes
# \author Norman Feske
# \date   2012-11-21
#

build "core init test/printf"

assert_spec linux

create_boot_directory

install_config {
	<config>
		<parent-provides>
			<service name="LOG"/>
			<service name="RAM"/>
			<service name="CAP"/>
			<service name="PD"/>
			<service name="RM"/>
			<service name="CPU"/>
			<service name="ROM"/>
		</parent-provides>
		<default-route>
			<any-service><parent/></any-service>
		</default-route>

		<start name="init_55_66" uid="55" gid="66">
			<binary name="init" />
			<resource name="RAM" quantum="1M"/>
			<config/>
		</start>

		<!-- we expect the GID of init_77 to equal the UID -->
		<start name="init_77" uid="77">
			<binary name="init" />
			<resource name="RAM" quantum="1M"/>
			<config>
				<parent-provides>
					<service name="LOG"/>
					<service name="CAP"/>
					<service name="ROM"/>
				</parent-provides>
				<default-route>
					<any-service><parent/></any-service>
				</default-route>

				<!-- we expect the GID and UID of init_sub_77 to inherit
				     its UID and GIDs from its parent policy. -->
				<start name="init_sub_77">
					<binary name="init" />
					<resource name="RAM" quantum="1M"/>
					<config/>
				</start>
			</config>
		</start>
	</config>
}

#
# Copy boot modules into run directory
#
# We cannot use the predefined 'build_boot_image' function here because
# this would create mere symlinks. However, we need to enable the setuid
# and setgid capabilities for core, which won't work if core were a symlink.
#
foreach binary { core init } {
	exec cp -H  bin/$binary [run_dir] }

#
# Allow core to set arbitrary UIDs and GIDs
#
exec sudo setcap cap_setuid,cap_setgid=ep [run_dir]/core

#
# Execute Genode until the point where init_sub_77 is up
#
run_genode_until {\[init -> init_77 -> init_sub_77\].*No children to start.*\n} 10

#
# Obtain the list of Genode user processes starting with the name 'init'
#
set ps_output [exec ps -eo uid,gid,cmd | grep Genode | grep init]

puts "Genode user processes:\n$ps_output"

#
# Validate output of ps
#
# We are only interested in the lines for the init instances with the
# customized UIDs and GIDs.
#
if {![regexp {55\s*66 \[Genode\] init_55_66}             $ps_output]
 || ![regexp {77\s*77 \[Genode\] init_77}                $ps_output]
 || ![regexp {77\s*77 \[Genode\] init_77 -> init_sub_77} $ps_output]} {
	puts stderr "Unexpected output of ps"
	exit 1
}

puts "Test succeeded"