2011-09-23 14:54:13

by justinmattock

[permalink] [raw]
Subject: [refpolicy] [RFC V2 2/2] Rebase systemd for mainline policy.

>From 6bc3327eee3ba5070b1f3beb424e2539727a7042 Mon Sep 17 00:00:00 2001
From: "Justin P. Mattock" <[email protected]>
Date: Fri, 23 Sep 2011 07:03:33 -0700
Subject: [RFC V2 2/2]Rebase systemd for mainline policy CONTRIB

NOTE: I pulled this directory, rather than using the regular commands for the contrib files.

The patch below is a try at trying to adopt(rebase) systemd from fedoras policy to the mainline policy.
I am able to build all the way through this time(NOTE: the first patch I sent out, I was able to build through only once,
telling me that I must have done something wrong along the way).

NOTE:Keep in mind that this is a _work in progress_ I am able to compile all the way, and install, but am hit with an error while loading the policy:

?libsepol.permission_copy_callback: Module abrt depends on permission all_service_perms in class service, not satisfied (No such file or directory).
libsemanage.semanage_link_sandbox: Link packages failed (No such file or directory).
/usr/sbin/semodule:? Failed!
make: *** [load] Error 1

once I finish other tasks, and have the time I will have a try at this build error.
If you are interested, feel free to hack away at this, and add anything that gets this working properly.

Signed-off-by: Justin P. Mattock <[email protected]>

---
?apache.fc???? |??? 2 ++
?apache.if???? |?? 27 +++++++++++++++++++++++++++
?apache.te???? |?? 10 ++++++++++
?apt.te??????? |??? 6 +++++-
?chronyd.fc??? |??? 2 ++
?chronyd.if??? |?? 22 ++++++++++++++++++++++
?chronyd.te??? |??? 3 +++
?consolekit.te |??? 2 ++
?cron.if?????? |?? 21 +++++++++++++++++++++
?cron.te?????? |??? 5 +++++
?dbus.te?????? |??? 9 +++++++++
?gnomeclock.te |??? 9 +++++++++
?logrotate.te? |??? 2 ++
?nis.fc??????? |??? 5 +++++
?nis.if??????? |?? 21 +++++++++++++++++++++
?nis.te??????? |??? 6 ++++++
?ntp.fc??????? |??? 2 ++
?ntp.if??????? |?? 40 ++++++++++++++++++++++++++++++++++++++++
?ntp.te??????? |??? 3 +++
?prelink.te??? |??? 2 ++
?readahead.fc? |??? 4 ++++
?readahead.if? |?? 23 +++++++++++++++++++++++
?readahead.te? |??? 3 +++
?shutdown.if?? |??? 5 +++++
?24 files changed, 233 insertions(+), 1 deletions(-)

diff --git a/apache.fc b/apache.fc
index 9e39aa5..0a7a941 100644
--- a/apache.fc
+++ b/apache.fc
@@ -16,6 +16,8 @@ HOME_DIR/((www)|(web)|(public_html))(/.+)? gen_context(system_u:object_r:httpd_u
?/etc/vhosts??? ??? ??? --??? gen_context(system_u:object_r:httpd_config_t,s0)
?/etc/zabbix/web(/.*)???? ??? ??? gen_context(system_u:object_r:httpd_sys_rw_content_t,s0)
?
+/lib/systemd/system/httpd.?\.service? --????????????? gen_context(system_u:object_r:httpd_unit_t,s0)
+
?/srv/([^/]*/)?www(/.*)???? ??? ??? gen_context(system_u:object_r:httpd_sys_content_t,s0)
?/srv/gallery2(/.*)???? ??? ??? gen_context(system_u:object_r:httpd_sys_content_t,s0)
?
diff --git a/apache.if b/apache.if
index 6480167..6cc0792 100644
--- a/apache.if
+++ b/apache.if
@@ -1216,3 +1216,30 @@ interface(`apache_admin',`
???? admin_pattern($1, httpd_php_tmp_t)
???? admin_pattern($1, httpd_suexec_tmp_t)
?')
+
+########################################
+## <summary>
+##??? Allow the specified domain to delete
+##??? apache system content rw files.
+## </summary>
+## <param name="domain">
+##??? <summary>
+##??? Domain allowed access.
+##??? </summary>
+## </param>
+## <rolecap/>
+#
+interface(`apache_delete_sys_content_rw',`
+??? gen_require(`
+??? ??? type httpd_sys_rw_content_t;
+??? ')
+
+??? files_search_tmp($1)
+??? delete_dirs_pattern($1, httpd_sys_rw_content_t, httpd_sys_rw_content_t)
+??? delete_files_pattern($1, httpd_sys_rw_content_t, httpd_sys_rw_content_t)
+??? delete_lnk_files_pattern($1, httpd_sys_rw_content_t, httpd_sys_rw_content_t)
+??? delete_fifo_files_pattern($1, httpd_sys_rw_content_t, httpd_sys_rw_content_t)
+??? delete_sock_files_pattern($1, httpd_sys_rw_content_t, httpd_sys_rw_content_t)
+')
+
+
diff --git a/apache.te b/apache.te
index 5b02edb..b492d17 100644
--- a/apache.te
+++ b/apache.te
@@ -177,6 +177,9 @@ role system_r types httpd_helper_t;
?type httpd_initrc_exec_t;
?init_script_file(httpd_initrc_exec_t)
?
+type httpd_unit_t;
+systemd_unit_file(httpd_unit_t)
+
?type httpd_lock_t;
?files_lock_file(httpd_lock_t)
?
@@ -899,3 +902,10 @@ tunable_policy(`httpd_enable_homedirs',`
???? userdom_search_user_home_dirs(httpd_suexec_t)
???? userdom_search_user_home_dirs(httpd_user_script_t)
?')
+
+########################################
+#
+# httpd_passwd local policy
+#
+
+systemd_passwd_agent_dev_template(httpd)
diff --git a/apt.te b/apt.te
index 4044710..4bfdda8 100644
--- a/apt.te
+++ b/apt.te
@@ -7,7 +7,11 @@ policy_module(apt, 1.6.0)
?
?type apt_t;
?type apt_exec_t;
-init_system_domain(apt_t, apt_exec_t)
+#init_system_domain(apt_t, apt_exec_t)
+
+# not sure why I was hitting an error here to make me do the below.
+init_daemon_domain(apt_t, apt_exec_t)
+
?domain_system_change_exemption(apt_t)
?role system_r types apt_t;
?
diff --git a/chronyd.fc b/chronyd.fc
index fd8cd0b..68fc39d 100644
--- a/chronyd.fc
+++ b/chronyd.fc
@@ -2,6 +2,8 @@
?
?/etc/rc\.d/init\.d/chronyd??? --??? gen_context(system_u:object_r:chronyd_initrc_exec_t,s0)
?
+/etc/rc\.d/init\.d/chronyd??? --??? gen_context(system_u:object_r:chronyd_initrc_exec_t,s0)
+
?/usr/sbin/chronyd??? ??? --??? gen_context(system_u:object_r:chronyd_exec_t,s0)
?
?/var/lib/chrony(/.*)???? ??? ??? gen_context(system_u:object_r:chronyd_var_lib_t,s0)
diff --git a/chronyd.if b/chronyd.if
index 9a0da94..95b7f32 100644
--- a/chronyd.if
+++ b/chronyd.if
@@ -103,3 +103,25 @@ interface(`chronyd_admin',`
???? files_search_tmp($1)
???? admin_pattern($1, chronyd_tmp_t)
?')
+
+########################################
+## <summary>
+##??? Execute chronyd server in the chronyd domain.
+## </summary>
+## <param name="domain">
+##??? <summary>
+##??? Domain allowed to transition.
+##??? </summary>
+## </param>
+#
+interface(`chronyd_systemctl',`
+??? gen_require(`
+??? ??? type chronyd_unit_t;
+??? ')
+
+??? systemd_exec_systemctl($1)
+??? systemd_search_unit_dirs($1)
+??? allow $1 chronyd_unit_t:file read_file_perms;
+??? allow $1 chronyd_unit_t:service all_service_perms;
+')
+
diff --git a/chronyd.te b/chronyd.te
index fa82327..d36ad29 100644
--- a/chronyd.te
+++ b/chronyd.te
@@ -18,6 +18,9 @@ files_type(chronyd_keys_t)
?type chronyd_var_lib_t;
?files_type(chronyd_var_lib_t)
?
+type chronyd_unit_t;
+systemd_unit_file(chronyd_unit_t)
+
?type chronyd_var_log_t;
?logging_log_file(chronyd_var_log_t)
?
diff --git a/consolekit.te b/consolekit.te
index 42ed6a6..046514c 100644
--- a/consolekit.te
+++ b/consolekit.te
@@ -69,6 +69,8 @@ logging_send_audit_msgs(consolekit_t)
?
?miscfiles_read_localization(consolekit_t)
?
+systemd_exec_systemctl(consolekit_t)
+
?userdom_dontaudit_read_user_home_content_files(consolekit_t)
?userdom_read_user_tmp_files(consolekit_t)
?
diff --git a/cron.if b/cron.if
index 35241ed..f73d8c1 100644
--- a/cron.if
+++ b/cron.if
@@ -377,6 +377,27 @@ interface(`cron_read_pipes',`
?
?########################################
?## <summary>
+##??? Send and receive messages from
+##??? crond over dbus.
+## </summary>
+## <param name="domain">
+##??? <summary>
+##??? Domain allowed access.
+##??? </summary>
+## </param>
+#
+interface(`cron_dbus_chat_crond',`
+??? gen_require(`
+??? ??? type crond_t;
+??? ??? class dbus send_msg;
+??? ')
+
+??? allow $1 crond_t:dbus send_msg;
+??? allow crond_t $1:dbus send_msg;
+')
+
+########################################
+## <summary>
?##??? Do not audit attempts to write cron daemon unnamed pipes.
?## </summary>
?## <param name="domain">
diff --git a/cron.te b/cron.te
index f22d27c..4733c0a 100644
--- a/cron.te
+++ b/cron.te
@@ -286,6 +286,11 @@ optional_policy(`
?')
?
?optional_policy(`
+??? systemd_use_fds_logind(crond_t)
+??? systemd_write_inherited_logind_sessions_pipes(crond_t)
+')
+
+optional_policy(`
???? udev_read_db(crond_t)
?')
?
diff --git a/dbus.te b/dbus.te
index 7ef5158..e4b3226 100644
--- a/dbus.te
+++ b/dbus.te
@@ -151,12 +151,21 @@ optional_policy(`
?')
?
?optional_policy(`
+??? systemd_use_fds_logind(system_dbusd_t)
+??? systemd_write_inherited_logind_sessions_pipes(system_dbusd_t)
+')
+
+optional_policy(`
???? udev_read_db(system_dbusd_t)
?')
?
+
+
?########################################
?#
?# Unconfined access to this module
?#
?
?allow dbusd_unconfined session_bus_type:dbus all_dbus_perms;
+
+
diff --git a/gnomeclock.te b/gnomeclock.te
index 4fde46b..db21911 100644
--- a/gnomeclock.te
+++ b/gnomeclock.te
@@ -9,6 +9,8 @@ type gnomeclock_t;
?type gnomeclock_exec_t;
?dbus_system_domain(gnomeclock_t, gnomeclock_exec_t)
?
+systemd_systemctl_domain(gnomeclock)
+
?########################################
?#
?# gnomeclock local policy
@@ -44,3 +46,10 @@ optional_policy(`
???? policykit_read_lib(gnomeclock_t)
???? policykit_read_reload(gnomeclock_t)
?')
+
+#######################################
+#
+# gnomeclock systemctl local policy
+#
+
+systemd_dontaudit_read_unit_files(gnomeclock_systemctl_t)
diff --git a/logrotate.te b/logrotate.te
index 7090dae..eb62def 100644
--- a/logrotate.te
+++ b/logrotate.te
@@ -116,6 +116,8 @@ miscfiles_read_localization(logrotate_t)
?
?seutil_dontaudit_read_config(logrotate_t)
?
+systemd_exec_systemctl(logrotate_t)
+
?userdom_use_user_terminals(logrotate_t)
?userdom_list_user_home_dirs(logrotate_t)
?userdom_use_unpriv_users_fds(logrotate_t)
diff --git a/nis.fc b/nis.fc
index 15448d5..7b1b312 100644
--- a/nis.fc
+++ b/nis.fc
@@ -19,3 +19,8 @@
?/var/run/ypbind.*??? --??? gen_context(system_u:object_r:ypbind_var_run_t,s0)
?/var/run/ypserv.*??? --??? gen_context(system_u:object_r:ypserv_var_run_t,s0)
?/var/run/yppass.*??? --??? gen_context(system_u:object_r:yppasswdd_var_run_t,s0)
+
+/lib/systemd/system/ypbind\.service??? --??? gen_context(system_u:object_r:ypbind_unit_t,s0)
+/lib/systemd/system/ypserv\.service??? --??? gen_context(system_u:object_r:nis_unit_t,s0)
+/lib/systemd/system/yppasswdd\.service??? --??? gen_context(system_u:object_r:nis_unit_t,s0)
+/lib/systemd/system/ypxfrd\.service??? --??? gen_context(system_u:object_r:nis_unit_t,s0)
diff --git a/nis.if b/nis.if
index abe3f7f..493b74e 100644
--- a/nis.if
+++ b/nis.if
@@ -337,6 +337,27 @@ interface(`nis_initrc_domtrans_ypbind',`
?
?########################################
?## <summary>
+##??? Execute ypbind server in the ypbind domain.
+## </summary>
+## <param name="domain">
+##??? <summary>
+##??? Domain allowed to transition.
+##??? </summary>
+## </param>
+#
+interface(`nis_systemctl_ypbind',`
+??? gen_require(`
+??? ??? type ypbind_unit_t;
+??? ')
+
+??? systemd_exec_systemctl($1)
+??? systemd_search_unit_dirs($1)
+??? allow $1 ypbind_unit_t:file read_file_perms;
+??? allow $1 ypbind_unit_t:service all_service_perms;
+')
+
+########################################
+## <summary>
?##??? All of the rules required to administrate
?##??? an nis environment
?## </summary>
diff --git a/nis.te b/nis.te
index 4876cae..d56cccf 100644
--- a/nis.te
+++ b/nis.te
@@ -24,6 +24,9 @@ files_tmp_file(ypbind_tmp_t)
?type ypbind_var_run_t;
?files_pid_file(ypbind_var_run_t)
?
+type ypbind_unit_t;
+systemd_unit_file(ypbind_unit_t)
+
?type yppasswdd_t;
?type yppasswdd_exec_t;
?init_daemon_domain(yppasswdd_t, yppasswdd_exec_t)
@@ -52,6 +55,9 @@ init_daemon_domain(ypxfr_t, ypxfr_exec_t)
?type ypxfr_var_run_t;
?files_pid_file(ypxfr_var_run_t)
?
+type nis_unit_t;
+systemd_unit_file(nis_unit_t)
+
?########################################
?#
?# ypbind local policy
diff --git a/ntp.fc b/ntp.fc
index e79dccc..50202ef 100644
--- a/ntp.fc
+++ b/ntp.fc
@@ -10,6 +10,8 @@
?
?/etc/rc\.d/init\.d/ntpd??? ??? --??? gen_context(system_u:object_r:ntpd_initrc_exec_t,s0)
?
+/lib/systemd/system/ntpd\.service?????????????? --????? gen_context(system_u:object_r:ntpd_unit_file_t,s0)
+
?/usr/sbin/ntpd??? ??? ??? --??? gen_context(system_u:object_r:ntpd_exec_t,s0)
?/usr/sbin/ntpdate??? ??? --??? gen_context(system_u:object_r:ntpdate_exec_t,s0)
?
diff --git a/ntp.if b/ntp.if
index e80f8c0..1bfce3d 100644
--- a/ntp.if
+++ b/ntp.if
@@ -163,3 +163,43 @@ interface(`ntp_admin',`
???? files_list_pids($1)
???? admin_pattern($1, ntpd_var_run_t)
?')
+
+#####################################
+## <summary>
+##????? Allow domain to read ntpd systemd unit files.
+## </summary>
+## <param name="domain">
+##????? <summary>
+##????? Domain allowed access.
+##????? </summary>
+## </param>
+#
+interface(`ntp_read_unit_file',`
+??????? gen_require(`
+??????????????? type ntpd_unit_file_t;
+??????? ')
+
+??????? files_search_var_lib($1)
+??????? allow $1 ntpd_unit_file_t:file read_file_perms;
+')
+
+########################################
+## <summary>
+##??? Execute ntpd server in the ntpd domain.
+## </summary>
+## <param name="domain">
+##??? <summary>
+##??? Domain allowed to transition.
+##??? </summary>
+## </param>
+#
+interface(`ntp_systemctl',`
+??? gen_require(`
+??? ??? type ntpd_unit_t;
+??? ')
+
+??? systemd_exec_systemctl($1)
+??? systemd_search_unit_dirs($1)
+??? allow $1 ntpd_unit_t:file read_file_perms;
+??? allow $1 ntpd_unit_t:service all_service_perms;
+')
diff --git a/ntp.te b/ntp.te
index c61adc8..7ba1783 100644
--- a/ntp.te
+++ b/ntp.te
@@ -15,6 +15,9 @@ init_daemon_domain(ntpd_t, ntpd_exec_t)
?type ntpd_initrc_exec_t;
?init_script_file(ntpd_initrc_exec_t)
?
+type ntpd_unit_file_t;
+systemd_unit_file(ntpd_unit_file_t)
+
?type ntpd_key_t;
?files_type(ntpd_key_t)
?
diff --git a/prelink.te b/prelink.te
index af55369..1e2a468 100644
--- a/prelink.te
+++ b/prelink.te
@@ -98,6 +98,8 @@ libs_delete_lib_symlinks(prelink_t)
?
?miscfiles_read_localization(prelink_t)
?
+systemd_read_unit_files(prelink_t)
+
?userdom_use_user_terminals(prelink_t)
?
?optional_policy(`
diff --git a/readahead.fc b/readahead.fc
index 7077413..6bc0fa8 100644
--- a/readahead.fc
+++ b/readahead.fc
@@ -1,3 +1,7 @@
?/usr/sbin/readahead.*??? --??? gen_context(system_u:object_r:readahead_exec_t,s0)
?/sbin/readahead.*??? --??? gen_context(system_u:object_r:readahead_exec_t,s0)
?/var/lib/readahead(/.*)???? gen_context(system_u:object_r:readahead_var_lib_t,s0)
+/lib/systemd/systemd-readahead.*??? --??? gen_context(system_u:object_r:readahead_exec_t,s0)
+
+/dev/\.systemd/readahead(/.*)???? gen_context(system_u:object_r:readahead_var_run_t,s0)
+/var/run/systemd/readahead(/.*)?? gen_context(system_u:object_r:readahead_var_run_t,s0)
diff --git a/readahead.if b/readahead.if
index 47c4723..9a0b9d1 100644
--- a/readahead.if
+++ b/readahead.if
@@ -1 +1,24 @@
?## <summary>Readahead, read files into page cache for improved performance</summary>
+########################################
+## <summary>
+##??? Manage readahead var_run files.
+## </summary>
+## <param name="domain">
+##??? <summary>
+##??? Domain allowed access.
+##??? </summary>
+## </param>
+#
+interface(`readahead_manage_pid_files',`
+??? gen_require(`
+??? ??? type readahead_var_run_t;
+??? ')
+
+??? manage_dirs_pattern($1, readahead_var_run_t, readahead_var_run_t)
+??? manage_files_pattern($1, readahead_var_run_t, readahead_var_run_t)
+??? dev_filetrans($1, readahead_var_run_t, { dir? file })
+??? init_pid_filetrans($1, readahead_var_run_t, { dir file })
+??? files_search_pids($1)???
+??? init_search_pid_dirs($1)
+')
+
diff --git a/readahead.te b/readahead.te
index b4ac57e..0adb060 100644
--- a/readahead.te
+++ b/readahead.te
@@ -82,11 +82,14 @@ auth_dontaudit_read_shadow(readahead_t)
?init_use_fds(readahead_t)
?init_use_script_ptys(readahead_t)
?init_getattr_initctl(readahead_t)
+# needs to write to /run/systemd/notify
+init_write_pid_socket(readahead_t)
?
?logging_send_syslog_msg(readahead_t)
?logging_set_audit_parameters(readahead_t)
?logging_dontaudit_search_audit_config(readahead_t)
?
+
?miscfiles_read_localization(readahead_t)
?
?userdom_dontaudit_use_unpriv_user_fds(readahead_t)
diff --git a/shutdown.if b/shutdown.if
index d0604cf..329a7f1 100644
--- a/shutdown.if
+++ b/shutdown.if
@@ -18,6 +18,11 @@ interface(`shutdown_domtrans',`
???? corecmd_search_bin($1)
???? domtrans_pattern($1, shutdown_exec_t, shutdown_t)
?
+??? optional_policy(`
+??? ??? systemd_exec_systemctl($1)
+??? ??? init_stream_connect($1)
+??? ')
+
???? ifdef(`hide_broken_symptoms', `
???? ??? dontaudit shutdown_t $1:socket_class_set { read write };
???? ??? dontaudit shutdown_t $1:fifo_file { read write };
--
1.7.6.2


2011-11-05 00:54:31

by Russell Coker

[permalink] [raw]
Subject: [refpolicy] [RFC V2 2/2] Rebase systemd for mainline policy.

On Sat, 24 Sep 2011, Justin Mattock <[email protected]> wrote:
> >From 6bc3327eee3ba5070b1f3beb424e2539727a7042 Mon Sep 17 00:00:00 2001
>
> From: "Justin P. Mattock" <[email protected]>
> Date: Fri, 23 Sep 2011 07:03:33 -0700
> Subject: [RFC V2 2/2]Rebase systemd for mainline policy CONTRIB
>
> NOTE: I pulled this directory, rather than using the regular commands for
> the contrib files.
>
> The patch below is a try at trying to adopt(rebase) systemd from fedoras
> policy to the mainline policy. I am able to build all the way through this
> time(NOTE: the first patch I sent out, I was able to build through only
> once, telling me that I must have done something wrong along the way).
>
> NOTE:Keep in mind that this is a work in progress I am able to compile all
> the way, and install, but am hit with an error while loading the policy:
>
> libsepol.permission_copy_callback: Module abrt depends on permission
> all_service_perms in class service, not satisfied (No such file or
> directory). libsemanage.semanage_link_sandbox: Link packages failed (No
> such file or directory). /usr/sbin/semodule: Failed!
> make: *** [load] Error 1

How is the work going on this? Do you have any newer patches to share?

--
My Main Blog http://etbe.coker.com.au/
My Documents Blog http://doc.coker.com.au/

2011-11-07 02:05:30

by justinmattock

[permalink] [raw]
Subject: [refpolicy] [RFC V2 2/2] Rebase systemd for mainline policy.





----- Original Message -----
From: Russell Coker <[email protected]>
To: refpolicy at oss.tresys.com; Justin Mattock <[email protected]>
Cc:
Sent: Friday, November 4, 2011 5:54 PM
Subject: Re: [refpolicy] [RFC V2 2/2] Rebase systemd for mainline policy.

On Sat, 24 Sep 2011, Justin Mattock <[email protected]> wrote:
> >From 6bc3327eee3ba5070b1f3beb424e2539727a7042 Mon Sep 17 00:00:00 2001
>
> From: "Justin P. Mattock" <[email protected]>
> Date: Fri, 23 Sep 2011 07:03:33 -0700
> Subject: [RFC V2 2/2]Rebase systemd for mainline policy CONTRIB
>
> NOTE: I pulled this directory, rather than using the regular commands for
> the contrib files.
>
> The patch below is a try at trying to adopt(rebase) systemd from fedoras
> policy to the mainline policy. I am able to build all the way through this
> time(NOTE: the first patch I sent out, I was able to build through only
> once, telling me that I must have done something wrong along the way).
>
> NOTE:Keep in mind that this is a work in progress I am able to compile all
> the way, and install, but am hit with an error while loading the policy:
>
>? libsepol.permission_copy_callback: Module abrt depends on permission
> all_service_perms in class service, not satisfied (No such file or
> directory). libsemanage.semanage_link_sandbox: Link packages failed (No
> such file or directory). /usr/sbin/semodule:? Failed!
> make: *** [load] Error 1

How is the work going on this?? Do you have any newer patches to share?


Long are the days of having a space to do any kind of development for the kernel and SELinux..
(I have been kicked to the curb..) :-(
?
I had planned to look at this over the weekend, but found myself doing other important tasks.?
if you are interested with building upon these patches please feel free!

keep in mind I just grepped from dans tree and copied over. I did hit an issue with:
interface(`systemd_config_all_services which is different(if I remember correctly)from dans tree.

(then there is the?all_service_perms in class service, not satisfied (No such file... error as well)).

let me know what you decide!

Justin P. Mattock



--
My Main Blog? ? ? ? http://etbe.coker.com.au/
My Documents Blog? ? http://doc.coker.com.au/