<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>The world of TOMOYO Linux&nbsp;&nbsp;The third installment: "Let's master domain transitions."</title>
<link rel="stylesheet" href="http://tomoyo.sourceforge.jp/tomoyo.css" media="all" type="text/css">
</head>
<body>
<p style="text-align:right;"><a href="tutorial-3.html.ja">Japanese Page</a></p>
<p style="text-align:right;">Last modified: $Date: 2011-07-01 13:55:23 +0900 (Fri, 01 Jul 2011) $</p>

<h1>The world of TOMOYO Linux<br>The third installment: "Let's master domain transitions."</h1>

<h2>Contents of this installment.</h2>

<p>In the second installment, I explained access control modes and profiles in TOMOYO Linux and steps for restricting access using access control modes and profiles. You might felt that too quick to catch up on, but to your surprise, all basic usage of TOMOYO Linux is covered by now. From now on, I explain detailed and applicable usage of TOMOYO Linux with expanded information. Please stay with me. In this installment, I explain TOMOYO Linux's domain transitions.</p>

<h2>Mastering domain transitions</h2>

<h3>General rule on TOMOYO Linux's domain transitions</h3>

<p>As I explained in the first installment, TOMOYO Linux performs domain transition whenever a program is executed as a rule. (Fig. 1)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 1&nbsp;&nbsp;Domain transitions in TOMOYO Linux<br>(Transits to new domain by program execution)<br>
<img src="tutorial/fig-3-1.png" alt="fig-3-1.png" width="800" height="600">
</td></tr>
</table>

<p>Thereby, each program has mutually independent domains. The name of domain is a string representation of concatenation of all program's pathnames ever executed by now starting from &lt;kernel&gt;. On the contrary, domains in SELinux do not have hierarchical structure and distributed in a flat manner. The relationship between programs and domains are defined by policy developer, but usually several programs corresponds to one domain. SELinux performs domain transition only if predefined programs are executed from specific domains. (Fig. 2. As a result, access control rules changes.)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 2&nbsp;&nbsp;Domain transitions in SELinux<br>
<img src="tutorial/fig-3-2.png" alt="fig-3-2.png" width="720" height="270">
</td></tr>
</table>

<h3>Exceptions for TOMOYO Linux's domain transition rules</h3>

<p>You can reinitialize or suppress TOMOYO Linux's domain transition as you need.</p>

<h4>&diams;Unconditionally reinitialize domain transition</h4>

<p>When "program" specified by "initialize_domain program from any" is executed, the process unconditionally transits to the child domain of "&lt;kernel&gt;" domain. (Fig. 3)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 3&nbsp;&nbsp;Effect of initialize_domain keyword<br>(Unconditionally transits to "&lt;kernel&gt; /some/where/baz" domain when /some/where/baz is executed.)<br>
<img src="tutorial/fig-3-3.png" alt="fig-3-3.png" width="800" height="500">
</td></tr>
</table>

<h4>&diams;Conditionally reinitialize domain transition</h4>

<p>As I noted above, if a "program" specified as "initialize_domain program from any" is executed, the process transits to "&lt;kernel&gt; program" domain. (Fig. 4)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 4&nbsp;&nbsp;Unconditionally reinitialize domain transition<br>
<img src="tutorial/fig-3-4.png" alt="fig-3-4.png" width="800" height="420">
</td></tr>
</table>

<p>But if a "program" specified with a "domainname" as "initialize_domain program from domainname" is executed, the process transits to "&lt;kernel&gt; program" domain only when "program" is executed from "domainname" domain. (Fig. 5)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 5&nbsp;&nbsp;Reinitialize domain transition only when executed from specific domain<br>
( The process transits to "&lt;kernel&gt; /usr/sbin/sshd" domain only when /usr/sbin/sshd is executed from "&lt;kernel&gt; /etc/rc.d/init.d/sshd" domain because of "initialize_domain /usr/sbin/sshd from &lt;kernel&gt; /etc/rc.d/init.d/sshd".)<br>
<img src="tutorial/fig-3-5.png" alt="fig-3-5.png" width="800" height="480">
</td></tr>
</table>

<p>You may specify only the last part of domainname (e.g. /bin/bash ) instead of a complete domainname (e.g. "&lt;kernel&gt; /usr/sbin/sshd /bin/bash").</p>

<h4>&diams;Conditionally not reinitialize domain transition</h4>

<p>If a "program" specified with a "domainname" as "no_initialize_domain program from domainname" is executed, the process ignores "initialize_domain" keyword when "program" is executed from "domainname" domain.</p>

<p>For example, /bin/mail (which is used for sending mails) executes /usr/sbin/sendmail.sendmail for sending mails. But if you want to give different permissions to "/usr/sbin/sendmail.sendmail for sending mails" and "/usr/sbin/sendmail.sendmail for receiving mails", you can specify "no_initialize_domain /usr/sbin/sendmail.sendmail from /bin/mail" so that /usr/sbin/sendmail.sendmail executed by /bin/mail won't transit to "&lt;kernel&gt; /usr/sbin/sendmail.sendmail" domain. (Fig. 6) (Note that this works for only domains which domainname ends with /bin/mail . If /bin/mail is executed from a shell domain specified with "keep_domain" keyword, you need to specify domain of the shell rather than /bin/mail .)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 6&nbsp;&nbsp;Combination with no_initialize_domain keyword<br>
<img src="tutorial/fig-3-6.png" alt="fig-3-6.png" width="800" height="500">
</td></tr>
</table>

<h4>&diams;Unconditionally suppress domain transition</h4>

<p>Any processes which belong to "domainname" specified by "keep_domain any from domainname" remains in the same domain unless programs specified by "initialize_domain" keyword is executed. (Fig. 7) This resembles SELinux's domain because multiple programs belong to the same domain.</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 7&nbsp;&nbsp;Effect of keep_domain keyword<br>(Since "&lt;kernel&gt; /sbin/init &sdot;&sdot;&sdot; foo bar" domain is specified using "keep_domain" keyword, domain transition does not occur when programs are executed. Domain transition to "&lt;kernel&gt; /some/where/baz" occurs when /some/where/baz (which is specified using "initialize_domain" keyword) is executed.)<br>
<img src="tutorial/fig-3-7.png" alt="fig-3-7.png" width="800" height="600">
</td></tr>
</table>

<p>You may specify only the last part of domainname (e.g. /bin/bash ) instead of a complete domainname (e.g. "&lt;kernel&gt; /usr/sbin/sshd /bin/bash"). For example, if you specify /bin/bash as a "domainname", "keep_domain" is applied to all domains which domainname ends with /bin/bash . (Fig. 8)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 8&nbsp;&nbsp;Effect of keep_domain keyword<br>
<img src="tutorial/fig-3-8.png" alt="fig-3-8.png" width="800" height="420">
</td></tr>
</table>

<h4>&diams;Conditionally suppress domain transition</h4>

<p>As I noted above, if a "domainname" is specified as "keep_domain any from domainname" , the process once reached to "domainname" remains in the same domain unless programs specified by "initialize_domain" keyword is executed. (Fig. 9)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 9&nbsp;&nbsp;Unconditionally suppress domain transition<br>
<img src="tutorial/fig-3-9.png" alt="fig-3-9.png" width="800" height="350">
</td></tr>
</table>

<p>But if a "domainname" is specified with a "program" as "keep_domain program from domainname", the process remains in the same domain only when "program" is executed from "domainname" domain. (Fig. 10)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 10&nbsp;&nbsp;Suppress domain transition only when specific programs are executed<br>
<img src="tutorial/fig-3-10.png" alt="fig-3-10.png" width="800" height="430">
</td></tr>
</table>

<h4>&diams;Conditionally resume domain transition</h4>

<p>You can suppress domain transition for login session using "keep_domain" keyword because it is unlikely possible to understand what commands in what order users will execute from login session beforehand. But there are cases you want to resume domain transition, such as allowing access to password files for changing passwords and restarting applications that run as daemon processes.</p>

<p>By specifying "no_keep_domain program from domainname", "keep_domain" keyword is ignored when "program" is executed from "domainname" domain.</p>

<p>For example, by specifying "no_keep_domain /bin/cat from &lt;kernel&gt; /usr/sbin/sshd /bin/bash" when "keep_domain &lt;kernel&gt; /usr/sbin/sshd /bin/bash" is specified, the process transits to "&lt;kernel&gt; /usr/sbin/sshd /bin/bash /bin/cat" domain when /bin/cat is executed from "&lt;kernel&gt; /usr/sbin/sshd /bin/bash" domain while the process remains in the same domain when other programs are executed from "&lt;kernel&gt; /usr/sbin/sshd /bin/bash" domain. (Fig. 11)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 11&nbsp;&nbsp;Combination with no_keep_domain keyword<br>
<img src="tutorial/fig-3-11.png" alt="fig-3-11.png" width="800" height="400">
</td></tr>
</table>

<h4>&diams;Do domain transition without program execution</h4>

<p>As a rule, domain transition is performed when a program is executed. But by calling procedure for domain transition from programs, you can perform domain transition without executing a program.</p>

<p>For example, Apache supports CGI programs. Some CGI programs are processed outside Apache (i.e. need program execution) and others are processed inside Apache (i.e. don't need program execution). By performing domain transition based on virtual host's name and requested CGI's pathnames before Apache processes the request, you can give different permissions for CGI programs which are processed inside Apache. Steps for doing this are explained in the tenth installment.</p>

<h3>Grouping a series of operations</h3>

<p>You can flexibly specify access control using "initialize_domain" keyword and "keep_domain" keyword. I explain how to use them using an example. Login as root user and run ccs-editpolicy command. Then, find the domain for /etc/rc.d/init.d/network (i.e. "&lt;kernel&gt; /etc/rc.d/init.d/network" domain). You will see that many programs such as /etc/sysconfig/network-scripts/ifup and /bin/touch are executed from /etc/rc.d/init.d/network . (Fig. 12)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 12&nbsp;&nbsp;Domain transition before specifying keep_domain keyword<br>
<img src="tutorial/fig-3-12.png" alt="fig-3-12.png" width="850" height="998">
</td></tr>
</table>

<p>Press "Tab" key. You will see that the screen titled "&lt;&lt;&lt; Domain Transition Editor &gt;&gt;&gt;" changed to the screen titled "&lt;&lt;&lt; Exception Policy Editor &gt;&gt;&gt;". You can find lines starting with "initialize_domain" keyword by scrolling the screen. Scroll down to the bottom, and press "A" key and enter "keep_domain any from &lt;kernel&gt; /etc/rc.d/init.d/network" and press "Enter" key. Then, you will see what you entered. (Fig. 13)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 13&nbsp;&nbsp;Specify keep_domain keyword<br>
<img src="tutorial/fig-3-13.png" alt="fig-3-13.png" width="572" height="322">
</td></tr>
</table>

<p>Press "Tab" key again. You will see that the screen titled "&lt;&lt;&lt; Exception Policy Editor &gt;&gt;&gt;" changed to the screen titled "&lt;&lt;&lt; Domain Transition Editor &gt;&gt;&gt;". Find "&lt;kernel&gt; /etc/rc.d/init.d/network" domain by scrolling the screen. (Fig. 14)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 14&nbsp;&nbsp;Domain transition after specifying keep_domain keyword<br>
<img src="tutorial/fig-3-14.png" alt="fig-3-14.png" width="850" height="998">
</td></tr>
</table>

<p>The mark changed from "*" to "#*". The "#" mark indicates that "multiple programs may belong to this domain because this domain is specified by keep_domain keyword". The "*" mark indicates that "multiple domains may transit to this domain because this domain is specified by initialize_domain keyword". Now, since you specified /etc/rc.d/init.d/network domain using "keep_domain" keyword, you need to re-learn policy for this domain. Lines with the "!" mark (from 95 to 156 in Fig. 14) indicates that these domains became unreachable due to "keep_domain any from &lt;kernel&gt; /etc/rc.d/init.d/network", thus delete these lines. Move the cursor and press "Space" key, and you will see that "&amp;" mark appeared. Then, press "D" key and a prompt like Fig. 15 will appear, thus press "Y" key.</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 15&nbsp;&nbsp;Confirmation message for deleting domains<br>
<img src="tutorial/fig-3-15.png" alt="fig-3-15.png" width="850" height="998">
</td></tr>
</table>

<p>Then, domains marked with "&amp;" are deleted. Press "Q" key to quit ccs-editpolicy command. Execute "/etc/rc.d/init.d/network restart" to re-learn. Execute ccs-editpolicy command again and find "&lt;kernel&gt; /etc/rc.d/init.d/network" domain. This time, you won't see programs like /etc/sysconfig/network-scripts/ifup and  /bin/touch . (Fig. 16)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 16&nbsp;&nbsp;Domain transition after re-learning<br>
<img src="tutorial/fig-3-16.png" alt="fig-3-16.png" width="556" height="332">
</td></tr>
</table>

<p>TOMOYO Linux's automatic domain dividing feature is powerful. But if you want to restrict execution of programs and access by these programs but you don't know the order of program execution (login session is a typical case), it is difficult to define domains. By grouping domains for login session using keywords explained in this installment and assign profiles for enforcing mode, you can restrict execution of programs and access by these programs while you don't restrict the order of program execution. Also, by not assigning profiles for enforcing mode, you can let login session behave freely like normal Linux.</p>

<h2>Trailer</h2>

<p>In this installment, I explained TOMOYO Linux's domain transitions. In the next installment, I explain tuning TOMOYO Linux's policy. Don't miss it!</p>

<p><a href="tutorial-2.html.en">Go back to the second installment.</a>&nbsp;&nbsp;<a href="tutorial-4.html.en">Proceed to the fourth installment.</a></p>

<hr>

<p><a href="index.html.en#tutorial">Return to index page.</a></p>
<p><a href="http://sourceforge.jp/"><img src="http://sourceforge.jp/sflogo.php?group_id=1973" width="96" height="31" alt="sflogo.php" title="SourceForge.jp"></a></p>
</body>
</html>
