]> granicus.if.org Git - postgresql/blob - doc/src/sgml/sepgsql.sgml
5ee08e1dee2b36553c39f9c9af5b9c16ed1bc932
[postgresql] / doc / src / sgml / sepgsql.sgml
1 <!-- doc/src/sgml/sepgsql.sgml -->
2
3 <sect1 id="sepgsql" xreflabel="sepgsql">
4  <title>sepgsql</title>
5
6  <indexterm zone="sepgsql">
7   <primary>sepgsql</primary>
8  </indexterm>
9
10  <para>
11   <filename>sepgsql</> is a loadable module that supports label-based
12   mandatory access control (MAC) based on <productname>SELinux</> security
13   policy.
14  </para>
15
16  <warning>
17    <para>
18      The current implementation has significant limitations, and does not
19      enforce mandatory access control for all actions.  See
20      <xref linkend="sepgsql-limitations">.
21    </para>
22  </warning>
23
24  <sect2 id="sepgsql-overview">
25   <title>Overview</title>
26
27   <para>
28    This module integrates with <productname>SELinux</> to provide an
29    additional layer of security checking above and beyond what is normally
30    provided by <productname>PostgreSQL</productname>.  From the perspective of
31    <productname>SELinux</>, this module allows
32    <productname>PostgreSQL</productname> to function as a user-space object
33    manager.  Each table or function access initiated by a DML query will be
34    checked against the system security policy.  This check is in addition to
35    the usual SQL permissions checking performed by
36    <productname>PostgreSQL</productname>.
37   </para>
38
39   <para>
40    <productname>SELinux</productname> access control decisions are made using
41    security labels, which are represented by strings such as
42    <literal>system_u:object_r:sepgsql_table_t:s0</>.  Each access control
43    decision involves two labels: the label of the subject attempting to
44    perform the action, and the label of the object on which the operation is
45    to be performed.  Since these labels can be applied to any sort of object,
46    access control decisions for objects stored within the database can be
47    (and, with this module, are) subjected to the same general criteria used
48    for objects of any other type, such as files.  This design is intended to
49    allow a centralized security policy to protect information assets
50    independent of the particulars of how those assets are stored.
51   </para>
52
53   <para>
54    The <xref linkend="sql-security-label"> statement allows assignment of
55    a security label to a database object.
56   </para>
57
58  </sect2>
59  <sect2 id="sepgsql-installation">
60   <title>Installation</title>
61
62   <para>
63     <filename>sepgsql</> can only be used on <productname>Linux</productname>
64     2.6.28 or higher with <productname>SELinux</productname> enabled.
65     It is not available on any other platform.  You will also need
66     <productname>libselinux</> 2.0.99 or higher and
67     <productname>selinux-policy</> 3.9.13 or higher (although some
68     distributions may backport the necessary rules into older policy
69     versions).
70   </para>
71
72   <para>
73    The <command>sestatus</> command allows you to check the status of
74    <productname>SELinux</productname>.  A typical display is:
75 <screen>
76 $ sestatus
77 SELinux status:                 enabled
78 SELinuxfs mount:                /selinux
79 Current mode:                   enforcing
80 Mode from config file:          enforcing
81 Policy version:                 24
82 Policy from config file:        targeted
83 </screen>
84    If <productname>SELinux</> is disabled or not installed, you must set
85    that product up first before installing this module.
86   </para>
87
88   <para>
89    To build this module, include the option <literal>--with-selinux</> in
90    your PostgreSQL <literal>configure</> command.  Be sure that the
91    <filename>libselinux-devel</> RPM is installed at build time.
92   </para>
93
94   <para>
95    To use this module, you must include <literal>sepgsql</>
96    in the <xref linkend="guc-shared-preload-libraries"> parameter in
97    <filename>postgresql.conf</>.  The module will not function correctly
98    if loaded in any other manner.  Once the module is loaded, you
99    should execute <filename>sepgsql.sql</filename> in each database.
100    This will install functions needed for security label management, and
101    assign initial security labels.
102   </para>
103
104   <para>
105    Here is an example showing how to initialize a fresh database cluster
106    with <filename>sepgsql</> functions and security labels installed.
107    Adjust the paths shown as appropriate for your installation:
108   </para>
109
110 <screen>
111 $ export PGDATA=/path/to/data/directory
112 $ initdb
113 $ vi $PGDATA/postgresql.conf
114   change
115     #shared_preload_libraries = ''                # (change requires restart)
116   to
117     shared_preload_libraries = 'sepgsql'          # (change requires restart)
118 $ for DBNAME in template0 template1 postgres; do
119     postgres --single -F -c exit_on_error=true $DBNAME \
120       &lt;/usr/local/pgsql/share/contrib/sepgsql.sql &gt;/dev/null
121   done
122 </screen>
123
124   <para>
125    Please note that you may see some or all of the following notifications
126    depending on the particular versions you have of
127    <productname>libselinux</> and <productname>selinux-policy</>:
128 <screen>
129 /etc/selinux/targeted/contexts/sepgsql_contexts:  line 33 has invalid object type db_blobs
130 /etc/selinux/targeted/contexts/sepgsql_contexts:  line 36 has invalid object type db_language
131 /etc/selinux/targeted/contexts/sepgsql_contexts:  line 37 has invalid object type db_language
132 /etc/selinux/targeted/contexts/sepgsql_contexts:  line 38 has invalid object type db_language
133 /etc/selinux/targeted/contexts/sepgsql_contexts:  line 39 has invalid object type db_language
134 /etc/selinux/targeted/contexts/sepgsql_contexts:  line 40 has invalid object type db_language
135 </screen>
136    These messages are harmless and should be ignored.
137   </para>
138
139   <para>
140    If the installation process completes without error, you can now start the
141    server normally.
142   </para>
143  </sect2>
144
145  <sect2 id="sepgsql-regression">
146   <title>Regression Tests</title>
147
148   <para>
149    Due to the nature of <productname>SELinux</productname>, running the
150    regression tests for <filename>sepgsql</> requires several extra
151    configuration steps, some of which must be done as root.
152    The regression tests will not be run by an ordinary
153    <literal>make check</> or <literal>make installcheck</> command; you must
154    set up the configuration and then invoke the test script manually.
155    The tests must be run in the <filename>contrib/sepgsql</> directory
156    of a configured PostgreSQL build tree.  Although they require a build tree,
157    the tests are designed to be executed against an installed server,
158    that is they are comparable to <literal>make installcheck</> not
159    <literal>make check</>.
160   </para>
161
162   <para>
163    First, set up <filename>sepgsql</filename> in a working database
164    according to the instructions in <xref linkend="sepgsql-installation">.
165    Note that the current operating system user must be able to connect to the
166    database as superuser without password authentication.
167   </para>
168
169   <para>
170    Second, build and install the policy package for the regression test.
171    The <filename>sepgsql-regtest</> policy is a special purpose policy package
172    which provides a set of rules to be allowed during the regression tests.
173    It should be built from the policy source file
174    <filename>sepgsql-regtest.te</>, which is done using
175    <command>make</command> with a Makefile supplied by SELinux.
176    You will need to locate the appropriate
177    Makefile on your system; the path shown below is only an example.
178    Once built, install this policy package using the
179    <command>semodule</> command, which loads supplied policy packages
180    into the kernel.  If the package is correctly installed,
181    <literal><command>semodule</> -l</> should list <literal>sepgsql-regtest</literal> as an
182    available policy package:
183   </para>
184
185 <screen>
186 $ cd .../contrib/sepgsql
187 $ make -f /usr/share/selinux/devel/Makefile
188 $ sudo semodule -u sepgsql-regtest.pp
189 $ sudo semodule -l | grep sepgsql
190 sepgsql-regtest 1.04
191 </screen>
192
193   <para>
194    Third, turn on <literal>sepgsql_regression_test_mode</>.
195    For security reasons, the rules in <filename>sepgsql-regtest</>
196    are not enabled by default;
197    the <literal>sepgsql_regression_test_mode</literal> parameter enables
198    the rules needed to launch the regression tests.
199    It can be turned on using the <command>setsebool</> command:
200   </para>
201
202 <screen>
203 $ sudo setsebool sepgsql_regression_test_mode on
204 $ getsebool sepgsql_regression_test_mode
205 sepgsql_regression_test_mode --> on
206 </screen>
207
208   <para>
209    Fourth, verify your shell is operating in the <literal>unconfined_t</>
210    domain:
211   </para>
212 <screen>
213 $ id -Z
214 unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
215 </screen>
216
217   <para>
218    See <xref linkend="sepgsql-resources"> for details on adjusting your
219    working domain, if necessary.
220   </para>
221
222   <para>
223    Finally, run the regression test script:
224   </para>
225 <screen>
226 $ ./test_sepgsql
227 </screen>
228
229   <para>
230    This script will attempt to verify that you have done all the configuration
231    steps correctly, and then it will run the regression tests for the
232    <filename>sepgsql</> module.
233   </para>
234
235   <para>
236    After completing the tests, it's recommended you disable
237    the <literal>sepgsql_regression_test_mode</literal> parameter:
238   </para>
239
240 <screen>
241 $ sudo setsebool sepgsql_regression_test_mode off
242 </screen>
243
244   <para>
245    You might prefer to remove the <filename>sepgsql-regtest</> policy
246    entirely:
247   </para>
248
249 <screen>
250 $ sudo semodule -r sepgsql-regtest
251 </screen>
252  </sect2>
253
254  <sect2 id="sepgsql-parameters">
255   <title>GUC Parameters</title>
256
257   <variablelist>
258    <varlistentry id="guc-sepgsql-permissive" xreflabel="sepgsql.permissive">
259     <term><varname>sepgsql.permissive</> (<type>boolean</type>)</term>
260     <indexterm>
261      <primary><varname>sepgsql.permissive</> configuration parameter</primary>
262     </indexterm>
263     <listitem>
264      <para>
265       This parameter enables <filename>sepgsql</> to function
266       in permissive mode, regardless of the system setting.
267       The default is off.
268       This parameter can only be set in the <filename>postgresql.conf</>
269       file or on the server command line.
270      </para>
271
272      <para>
273       When this parameter is on, <filename>sepgsql</> functions
274       in permissive mode, even if SELinux in general is working in enforcing
275       mode.  This parameter is primarily useful for testing purposes.
276      </para>
277     </listitem>
278
279    </varlistentry>
280    <varlistentry id="guc-sepgsql-debug-audit" xreflabel="sepgsql.debug_audit">
281     <term><varname>sepgsql.debug_audit</> (<type>boolean</>)</>
282     <indexterm>
283      <primary><varname>sepgsql.debug_audit</> configuration parameter</>
284     </indexterm>
285     <listitem>
286      <para>
287       This parameter enables the printing of audit messages regardless of
288       the system policy settings.
289       The default is off, which means that messages will be printed according
290       to the system settings.
291      </para>
292
293      <para>
294       The security policy of <productname>SELinux</> also has rules to
295       control whether or not particular accesses are logged.
296       By default, access violations are logged, but allowed
297       accesses are not.
298      </para>
299
300      <para>
301       This parameter forces all possible logging to be turned on, regardless
302       of the system policy.
303      </para>
304     </listitem>
305    </varlistentry>
306   </variablelist>
307  </sect2>
308
309  <sect2 id="sepgsql-features">
310   <title>Features</title>
311   <sect3>
312    <title>Controlled Object Classes</title>
313    <para>
314     The security model of <productname>SELinux</> describes all the access
315     control rules as relationships between a subject entity (typically,
316     a client of the database) and an object entity (such as a database
317     object), each of which is
318     identified by a security label.  If access to an unlabelled object is
319     attempted, the object is treated as if it were assigned the label
320     <literal>unlabeled_t</>.
321    </para>
322
323    <para>
324     Currently, <filename>sepgsql</filename> allows security labels to be
325     assigned to schemas, tables, columns, sequences, views, and functions.
326     When <filename>sepgsql</filename> is in use, security labels are
327     automatically assigned to supported database objects at creation time.
328     This label is called a default security label, and is decided according
329     to the system security policy, which takes as input the creator's label
330     and the label assigned to the new object's parent object.
331    </para>
332
333    <para>
334     A new database object basically inherits the security label of the parent
335     object, except when the security policy has special rules known as
336     type-transition rules, in which case a different label may be applied.
337     For schemas, the parent object is the current database; for tables,
338     sequences, views, and functions, it is the containing schema; for columns,
339     it is the containing table.
340    </para>
341   </sect3>
342
343   <sect3>
344    <title>DML Permissions</title>
345
346    <para>
347     For tables, <literal>db_table:select</>, <literal>db_table:insert</>,
348     <literal>db_table:update</> or <literal>db_table:delete</> are
349     checked for all the referenced target tables depending on the kind of
350     statement; in addition, <literal>db_table:select</> is also checked for
351     all the tables that contain columns referenced in the
352     <literal>WHERE</> or <literal>RETURNING</> clause, as a data source
353     for <literal>UPDATE</>, and so on.
354    </para>
355
356    <para>
357     Column-level permissions will also be checked for each referenced column.
358     <literal>db_column:select</> is checked on not only the columns being
359     read using <literal>SELECT</>, but those being referenced in other DML
360     statements; <literal>db_column:update</> or <literal>db_column:insert</>
361     will also be checked for columns being modified by <literal>UPDATE</> or
362     <literal>INSERT</>.
363    </para>
364
365    <para>
366    For example, consider:
367 <synopsis>
368 UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100;
369 </synopsis>
370
371     Here, <literal>db_column:update</> will be checked for
372     <literal>t1.x</>, since it is being updated,
373     <literal>db_column:{select update}</> will be checked for
374     <literal>t1.y</>, since it is both updated and referenced, and
375     <literal>db_column:select</> will be checked for <literal>t1.z</>, since
376     it is only referenced.
377     <literal>db_table:{select update}</> will also be checked
378     at the table level.
379    </para>
380
381    <para>
382     For sequences, <literal>db_sequence:get_value</> is checked when we
383     reference a sequence object using <literal>SELECT</>; however, note that we
384     do not currently check permissions on execution of corresponding functions
385     such as <literal>lastval()</>.
386    </para>
387
388    <para>
389     For views, <literal>db_view:expand</> will be checked, then any other
390     required permissions will be checked on the objects being
391     expanded from the view, individually.
392    </para>
393
394    <para>
395     For functions, <literal>db_procedure:{execute}</> is defined, but is not
396     checked in this version.
397    </para>
398
399    <para>
400     The client must be allowed to access all referenced tables and
401     columns, even if they originated from views which were then expanded,
402     so that we apply consistent access control rules independent of the manner
403     in which the table contents are referenced.
404    </para>
405
406    <para>
407     The default database privilege system allows database superusers to
408     modify system catalogs using DML commands, and reference or modify
409     toast tables.  These operations are prohibited when
410     <filename>sepgsql</> is enabled.
411    </para>
412   </sect3>
413
414   <sect3>
415    <title>DDL Permissions</title>
416    <para>
417     <productname>SELinux</> defines several permissions to control common
418     operations for each object type; such as creation, alter, drop and
419     relabel of security label. In addition, several object types have
420     special permissions to control their characteristic operations; such as
421     addition or deletion of name entries within a particular schema.
422    </para>
423    <para>
424     When a <literal>CREATE</> command is executed, <literal>create</> will
425     be checked on the object being constructed for each object types.
426     A default security label will be assigned to the new database object,
427     and the <literal>create</> permission will be checked on the pair
428     of security label of the client and the new object itself.
429     We consider <xref linkend="sql-createtable"> to construct a table and
430     underlying columns at the same time, so it requires the users to have
431     permission to create both the table and its columns.
432    </para>
433    <para>
434     A few additional checks are applied depending on object types.
435     On <xref linkend="sql-createdatabase">, <literal>getattr</> permission
436     will be checked on the source or template database of the new database,
437     not only <literal>create</> on the new database.
438     On creation of objects within a particular schema (tables, views,
439     sequences and procedures), <literal>add_name</> will be also checked
440     on the schema, not only <literal>create</> on the new object itself.
441     On <xref linkend="sql-createfunction">, <literal>install</> permission
442     will be checked if <literal>leakproof</> attribute was given, not only
443     <literal>create</> on the new function. This permission will be also
444     checked when user tries to turn on <literal>leakproof</> attribute
445     using <xref linkend="sql-alterfunction"> command, with
446     <literal>setattr</> permission on the function being altered.
447    </para>
448
449    <para>
450     When <literal>DROP</> command is executed, <literal>drop</> will be
451     checked on the object being removed for each object types.  Permissions
452     will be also checked for objects dropped indirectly via <literal>CASCADE</>.
453     Deletion of objects contained within a particular schema (tables, views,
454     sequences and procedures) additionally requires
455     <literal>remove_name</> on the schema.
456    </para>
457
458    <para>
459     When <literal>ALTER</> command is executed, <literal>setattr</> will be
460     checked on the object being modified for each object types. 
461     In addition, <literal>remove_name</> and <literal>add_name</>
462     will be checked on the old and new schemas, respectively, when an
463     object is moved to a new schema.
464     For certain object types, additional checks are performed.
465    </para>
466
467    <para>
468     When objects that are subsidiary of other objects (such as a table's
469     indexes or triggers) are created, dropped or altered,
470     <literal>setattr</> permission will be checked on the main object,
471     instead of the subsidiary object itself.
472    </para>
473
474    <para>
475     When <xref linkend="sql-security-label"> is executed, <literal>setattr</>
476     and <literal>relabelfrom</> will be checked on the object being relabeled
477     with its old security label, then <literal>relabelto</> with the supplied
478     new security label.
479    </para>
480
481    <para>
482     In the case where multiple label providers are installed and the user tries
483     to set a security label, but it is not managed by <productname>SELinux</>,
484     only <literal>setattr</> should be checked here.
485     This is currently not done due to implementation restrictions.
486    </para>
487   </sect3>
488
489   <sect3>
490    <title>Trusted Procedures</title>
491    <para>
492     Trusted procedures are similar to security definer functions or setuid
493     commands. <productname>SELinux</> provides a feature to allow trusted
494     code to run using a security label different from that of the client,
495     generally for the purpose of providing highly controlled access to
496     sensitive data (e.g. rows might be omitted, or the precision of stored
497     values might be reduced).  Whether or not a function acts as a trusted
498     procedure is controlled by its security label and the operating system
499     security policy.  For example:
500    </para>
501
502 <screen>
503 postgres=# CREATE TABLE customer (
504                cid     int primary key,
505                cname   text,
506                credit  text
507            );
508 CREATE TABLE
509 postgres=# SECURITY LABEL ON COLUMN customer.credit
510                IS 'system_u:object_r:sepgsql_secret_table_t:s0';
511 SECURITY LABEL
512 postgres=# CREATE FUNCTION show_credit(int) RETURNS text
513              AS 'SELECT regexp_replace(credit, ''-[0-9]+$'', ''-xxxx'', ''g'')
514                         FROM customer WHERE cid = $1'
515            LANGUAGE sql;
516 CREATE FUNCTION
517 postgres=# SECURITY LABEL ON FUNCTION show_credit(int)
518                IS 'system_u:object_r:sepgsql_trusted_proc_exec_t:s0';
519 SECURITY LABEL
520 </screen>
521
522    <para>
523     The above operations should be performed by an administrative user.
524    </para>
525
526 <screen>
527 postgres=# SELECT * FROM customer;
528 ERROR:  SELinux: security policy violation
529 postgres=# SELECT cid, cname, show_credit(cid) FROM customer;
530  cid | cname  |     show_credit
531 -----+--------+---------------------
532    1 | taro   | 1111-2222-3333-xxxx
533    2 | hanako | 5555-6666-7777-xxxx
534 (2 rows)
535 </screen>
536
537    <para>
538     In this case, a regular user cannot reference <literal>customer.credit</>
539     directly, but a trusted procedure <literal>show_credit</> allows him
540     to print the credit card numbers of customers with some of the digits
541     masked out.
542    </para>
543   </sect3>
544
545   <sect3>
546    <title>Dynamic Domain Transitions</title>
547    <para>
548     It is possible to use SELinux's dynamic domain transition feature
549     to switch the security label of the client process, the client domain,
550     to a new context, if that is allowed by the security policy.
551     The client domain needs the <literal>setcurrent</> permission and also
552     <literal>dyntransition</> from the old to the new domain.
553    </para>
554    <para>
555     Dynamic domain transitions should be considered carefully, because they
556     allow users to switch their label, and therefore their privileges,
557     at their option, rather than (as in the case of a trusted procedure)
558     as mandated by the system.
559     Thus, the <literal>dyntransition</literal> permission is only considered
560     safe when used to switch to a domain with a smaller set of privileges than
561     the original one. For example:
562    </para>
563 <screen>
564 regression=# select sepgsql_getcon();
565                     sepgsql_getcon
566 -------------------------------------------------------
567  unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
568 (1 row)
569
570 regression=# SELECT sepgsql_setcon('unconfined_u:unconfined_r:unconfined_t:s0-s0:c1.c4');
571  sepgsql_setcon 
572 ----------------
573  t
574 (1 row)
575
576 regression=# SELECT sepgsql_setcon('unconfined_u:unconfined_r:unconfined_t:s0-s0:c1.c1023');
577 ERROR:  SELinux: security policy violation
578 </screen>
579    <para>
580     In this example above we were allowed to switch from the larger MCS
581     range <literal>c1.c1023</> to the smaller range <literal>c1.c4</>, but
582     switching back was denied.
583    </para>
584    <para>
585     A combination of dynamic domain transition and trusted procedure
586     enables an interesting use case that fits the typical process life-cycle
587     of connection pooling software.
588     Even if your connection pooling software is not allowed to run most
589     of SQL commands, you can allow it to switch the security label
590     of the client using the <literal>sepgsql_setcon()</literal> function
591     from within a trusted procedure; that should take some
592     credential to authorize the request to switch the client label.
593     After that, this session will have the privileges of the target user,
594     rather than the connection pooler.
595     The connection pooler can later revert the security label change by
596     again using <literal>sepgsql_setcon()</literal> with
597     <literal>NULL</literal> argument, again invoked from within a trusted
598     procedure with appropriate permissions checks.
599     The point here is that only the trusted procedure actually has permission
600     to change the effective security label, and only does so when given proper
601     credentials.  Of course, for secure operation, the credential store
602     (table, procedure definition, or whatever) must be protected from
603     unauthorized access.
604    </para>
605   </sect3>
606
607   <sect3>
608    <title>Miscellaneous</title>
609    <para>
610     We reject the <xref linkend="sql-load"> command across the board, because
611     any module loaded could easily circumvent security policy enforcement.
612    </para>
613
614   </sect3>
615 </sect2>
616
617  <sect2 id="sepgsql-functions">
618   <title>Sepgsql Functions</title>
619   <para>
620    <xref linkend="sepgsql-functions-table"> shows the available functions.
621   </para>
622
623   <table id="sepgsql-functions-table">
624    <title>Sepgsql Functions</title>
625    <tgroup cols="2">
626     <tbody>
627      <row>
628       <entry><literal>sepgsql_getcon() returns text</literal></entry>
629       <entry>
630        Returns the client domain, the current security label of the client.
631       </entry>
632      </row>
633      <row>
634       <entry><literal>sepgsql_setcon(text) returns bool</literal></entry>
635       <entry>
636        Switches the client domain of the current session to the new domain,
637        if allowed by the security policy.
638        It also accepts <literal>NULL</literal> input as a request to transition
639        to the client's original domain.
640       </entry>
641      </row>
642      <row>
643       <entry><literal>sepgsql_mcstrans_in(text) returns text</literal></entry>
644       <entry>Translates the given qualifies MLS/MCS range into raw format if
645       the mcstrans daemon is running.
646       </entry>
647      </row>
648      <row>
649       <entry><literal>sepgsql_mcstrans_out(text) returns text</literal></entry>
650       <entry>Translates the given raw MCS/MCS range into qualified format if
651       the mcstrans daemon is running.
652       </entry>
653      </row>
654      <row>
655       <entry><literal>sepgsql_restorecon(text) returns bool</literal></entry>
656       <entry>
657        Sets up initial security labels for all objects within the
658        current database. The argument may be NULL, or the name of a specfile
659        to be used as alternative of the system default.
660       </entry>
661      </row>
662     </tbody>
663    </tgroup>
664   </table>
665  </sect2>
666
667  <sect2 id="sepgsql-limitations">
668   <title>Limitations</title>
669
670   <variablelist>
671    <varlistentry>
672     <term>Data Definition Language (DDL) Permissions</term>
673     <listitem>
674      <para>
675       Due to implementation restrictions, some DDL operations do not
676       check permissions.
677      </para>
678     </listitem>
679    </varlistentry>
680
681    <varlistentry>
682     <term>Data Control Language (DCL) Permissions</term>
683     <listitem>
684      <para>
685       Due to implementation restrictions, DCL operations do not check
686       permissions.
687      </para>
688     </listitem>
689    </varlistentry>
690
691    <varlistentry>
692     <term>Row-level access control</term>
693     <listitem>
694      <para>
695       <productname>PostgreSQL</> does not support row-level access; therefore,
696       <filename>sepgsql</filename> does not support it either.
697      </para>
698     </listitem>
699    </varlistentry>
700
701    <varlistentry>
702     <term>Covert channels</term>
703     <listitem>
704      <para>
705       <filename>sepgsql</> does not try to hide the existence of
706       a certain object, even if the user is not allowed to reference it.
707       For example, we can infer the existence of an invisible object as
708       a result of primary key conflicts, foreign key violations, and so on,
709       even if we cannot obtain the contents of the object.  The existence
710       of a top secret table cannot be hidden; we only hope to conceal its
711       contents.
712      </para>
713     </listitem>
714    </varlistentry>
715   </variablelist>
716  </sect2>
717
718  <sect2 id="sepgsql-resources">
719   <title>External Resources</title>
720   <variablelist>
721    <varlistentry>
722     <term><ulink url="http://wiki.postgresql.org/wiki/SEPostgreSQL">SE-PostgreSQL Introduction</ulink></term>
723     <listitem>
724      <para>
725       This wiki page provides a brief overview, security design, architecture,
726       administration and upcoming features.
727      </para>
728     </listitem>
729    </varlistentry>
730    <varlistentry>
731     <term><ulink url="http://docs.fedoraproject.org/selinux-user-guide/">Fedora SELinux User Guide</ulink></term>
732     <listitem>
733      <para>
734       This document provides a wide spectrum of knowledge to administer
735       <productname>SELinux</> on your systems.
736       It focuses primarily on Fedora, but is not limited to Fedora.
737      </para>
738     </listitem>
739    </varlistentry>
740    <varlistentry>
741     <term><ulink url="http://docs.fedoraproject.org/selinux-faq">Fedora SELinux FAQ</ulink></term>
742     <listitem>
743      <para>
744       This document answers frequently asked questions about
745       <productname>SELinux</productname>.
746       It focuses primarily on Fedora, but is not limited to Fedora.
747      </para>
748     </listitem>
749    </varlistentry>
750   </variablelist>
751  </sect2>
752
753  <sect2 id="sepgsql-author">
754   <title>Author</title>
755   <para>
756    KaiGai Kohei <email>kaigai@ak.jp.nec.com</email>
757   </para>
758  </sect2>
759 </sect1>