Updated security settings to handle multiple machines
authoradamch <adamch>
Sun, 25 Feb 2007 22:04:58 +0000 (22:04 +0000)
committeradamch <adamch>
Sun, 25 Feb 2007 22:04:58 +0000 (22:04 +0000)
sec.mlt
sec.sig
sec.sml
tables.sql

diff --git a/sec.mlt b/sec.mlt
index 2983077..8885eaa 100644 (file)
--- a/sec.mlt
+++ b/sec.mlt
@@ -1,14 +1,19 @@
 <% val you = Init.getUserId ();
 val yourname = Init.getUserName ();
 
+val nodeNum = case $"node" of
+                 "" => 2
+               | node => Web.stoi node;
+val nodeName = Init.nodeName nodeNum;
+
 val uname = case $"uname" of
          "" => yourname
        | uname => uname;
 
-val socks = Sec.socketPerms uname;
-val tpe = Sec.isTpe uname;
-val cron = Sec.cronAllowed uname;
-val ftp = Sec.ftpAllowed uname;
+val socks = Sec.socketPerms {node = nodeNum, uname = uname};
+val tpe = Sec.isTpe {node = nodeNum, uname = uname};
+val cron = Sec.cronAllowed {node = nodeNum, uname = uname};
+val ftp = Sec.ftpAllowed {node = nodeNum, uname = uname};
 
 ref showNormal = true;
 
@@ -17,10 +22,10 @@ ref showNormal = true;
 if $"cmd" = "socks" then
        showNormal := false;
        val socks = $"socks";
-       %>Are you sure you want to request that socket permissions for <b><% Web.html uname %></b> be changed to <b><% Web.html socks %></b>?<br>
-       <a href="sec?cmd=socks2&uname=<% Web.urlEncode uname %>&socks=<% Web.urlEncode socks %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
+       %>Are you sure you want to request that socket permissions for <b><% Web.html uname %></b> on <b><% Web.html nodeName %></b> be changed to <b><% Web.html socks %></b>?<br>
+       <a href="sec?cmd=socks2&node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&socks=<% Web.urlEncode socks %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
 elseif $"cmd" = "socks2" then
-       val id = Sec.Req.add (you, String.concat [uname, ": change socket permissions to ", $"socks"], $"msg");
+       val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat [uname, ": change socket permissions to ", $"socks"], msg = $"msg"};
        if not (Sec.Req.notifyNew id) then
                %><h3>Error sending e-mail notification</h3><%
        end
@@ -29,10 +34,10 @@ elseif $"cmd" = "socks2" then
 elseif $"cmd" = "tpe" then
        showNormal := false;
        val tpe = iff $"tpe" = "yes" then "on" else "off";
-       %>Are you sure you want to request that trusted-path-executables-only for <b><% Web.html uname %></b> be turned <b><% tpe %></b>?<br>
-       <a href="sec?cmd=tpe2&uname=<% Web.urlEncode uname %>&tpe=<% tpe %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
+       %>Are you sure you want to request that trusted-path-executables-only for <b><% Web.html uname %></b> on <b><% Web.html nodeName %></b> be turned <b><% tpe %></b>?<br>
+       <a href="sec?cmd=tpe2&node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&tpe=<% tpe %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
 elseif $"cmd" = "tpe2" then
-       val id = Sec.Req.add (you, String.concat [uname, ": turn tpe ", $"tpe"], $"msg");
+       val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat [uname, ": turn tpe ", $"tpe"], msg = $"msg"};
        if not (Sec.Req.notifyNew id) then
                %><h3>Error sending e-mail notification</h3><%
        end
@@ -41,11 +46,11 @@ elseif $"cmd" = "tpe2" then
 elseif $"cmd" = "cron" then
        showNormal := false;
        val cron = iff $"cron" = "yes" then "enabled" else "disabled";
-       %>Are you sure you want to request that <tt>cron</tt> permissions for <b><% Web.html uname %></b> be <b><% cron %></b>?<br>
-       <a href="sec?cmd=cron2&uname=<% Web.urlEncode uname %>&cron=<% cron %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
+       %>Are you sure you want to request that <tt>cron</tt> permissions for <b><% Web.html uname %></b> on <b><% Web.html nodeName %></b> be <b><% cron %></b>?<br>
+       <a href="sec?cmd=cron2&node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&cron=<% cron %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
 elseif $"cmd" = "cron2" then
        val cron = iff $"cron" = "enabled" then "enable" else "disable";
-       val id = Sec.Req.add (you, String.concat [uname, ": ", cron, " cron access"], $"msg");
+       val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat [uname, ": ", cron, " cron access"], msg = $"msg"};
        if not (Sec.Req.notifyNew id) then
                %><h3>Error sending e-mail notification</h3><%
        end
@@ -54,11 +59,11 @@ elseif $"cmd" = "cron2" then
 elseif $"cmd" = "ftp" then
        showNormal := false;
        val ftp = iff $"ftp" = "yes" then "enabled" else "disabled";
-       %>Are you sure you want to request that FTP permissions for <b><% Web.html uname %></b> be <b><% ftp %></b>?<br>
-       <a href="sec?cmd=ftp2&uname=<% Web.urlEncode uname %>&ftp=<% ftp %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
+       %>Are you sure you want to request that FTP permissions for <b><% Web.html uname %></b> on <b><% Web.html nodeName %></b> be <b><% ftp %></b>?<br>
+       <a href="sec?cmd=ftp2&node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&ftp=<% ftp %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
 elseif $"cmd" = "ftp2" then
        val ftp = iff $"ftp" = "enabled" then "enable" else "disable";
-       val id = Sec.Req.add (you, String.concat [uname, ": ", ftp, " FTP access"], $"msg");
+       val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat [uname, ": ", ftp, " FTP access"], msg = $"msg"};
        if not (Sec.Req.notifyNew id) then
                %><h3>Error sending e-mail notification</h3><%
        end
@@ -67,10 +72,10 @@ elseif $"cmd" = "ftp2" then
 elseif $"cmd" = "rule" then
        showNormal := false;
        val rule = $"rule";
-       %>Are you sure you want to request the firewall rule <b><% Web.html uname %>&nbsp;<% Web.html rule %></b>?<br>
-       <a href="sec?cmd=rule2&uname=<% Web.urlEncode uname %>&rule=<% Web.urlEncode rule %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
+       %>Are you sure you want to request the firewall rule <b><% Web.html uname %>&nbsp;<% Web.html rule %></b> on <b><% Web.html nodeName %></b>?<br>
+       <a href="sec?cmd=rule2&node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&rule=<% Web.urlEncode rule %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
 elseif $"cmd" = "rule2" then
-       val id = Sec.Req.add (you, String.concat ["Add firewall rule \"", uname, " ", $"rule", "\""], $"msg");
+       val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat ["Add firewall rule \"", uname, " ", $"rule", "\""], msg = $"msg"};
        if not (Sec.Req.notifyNew id) then
                %><h3>Error sending e-mail notification</h3><%
        end
@@ -83,11 +88,11 @@ elseif $"modRule" <> "" then
        if oldRule = rule then
                %>You didn't modify the textbox for this rule before clicking the button, so there is no request to be made.<%
        else
-               %>Are you sure you want to request that firewall rule <b><% Web.html uname %>&nbsp;<% Web.html oldRule %></b> be replaced by <b><% Web.html uname %>&nbsp;<% Web.html rule %></b>?<br>
-               <a href="sec?uname=<% Web.urlEncode uname %>&modRule2=<% Web.urlEncode oldRule %>&rule=<% Web.urlEncode rule %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
+               %>Are you sure you want to request that firewall rule <b><% Web.html uname %>&nbsp;<% Web.html oldRule %></b> be replaced by <b><% Web.html uname %>&nbsp;<% Web.html rule %></b> on <b><% Web.html nodeName %></b>?<br>
+               <a href="sec?node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&modRule2=<% Web.urlEncode oldRule %>&rule=<% Web.urlEncode rule %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
        end
 elseif $"modRule2" <> "" then
-       val id = Sec.Req.add (you, String.concat ["Change firewall rule \"", uname, " ", $"modRule2", "\" to \"", uname, " ", $"rule", "\""], $"msg");
+       val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat ["Change firewall rule \"", uname, " ", $"modRule2", "\" to \"", uname, " ", $"rule", "\""], msg = $"msg"};
        if not (Sec.Req.notifyNew id) then
                %><h3>Error sending e-mail notification</h3><%
        end
@@ -96,10 +101,10 @@ elseif $"modRule2" <> "" then
 elseif $"delRule" <> "" then
        showNormal := false;
        val oldRule = $"delRule";
-       %>Are you sure you want to request that firewall rule <b><% Web.html uname %>&nbsp;<% Web.html oldRule %></b> be <b>deleted</b>?<br>
-       <a href="sec?uname=<% Web.urlEncode uname %>&delRule2=<% Web.urlEncode oldRule %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
+       %>Are you sure you want to request that firewall rule <b><% Web.html uname %>&nbsp;<% Web.html oldRule %></b> on <b><% Web.html nodeName %></b> be <b>deleted</bD>?<br>
+       <a href="sec?node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&delRule2=<% Web.urlEncode oldRule %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
 elseif $"delRule2" <> "" then
-       val id = Sec.Req.add (you, String.concat ["Delete firewall rule \"", uname, " ", $"delRule2", "\""], $"msg");
+       val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat ["Delete firewall rule \"", uname, " ", $"delRule2", "\""], msg = $"msg"};
        if not (Sec.Req.notifyNew id) then
                %><h3>Error sending e-mail notification</h3><%
        end
@@ -116,6 +121,7 @@ elseif $"cmd" = "open" then
 <table class="blanks">
 <tr> <td>By:</td> <td><a href="user?id=<% #usr req %>"><% name %></a></td> </tr>
 <tr> <td>Time:</td> <td><% #stamp req %></td> </tr>
+<tr> <td>Node:</td> <td><% Web.html (Init.nodeName (#node req)) %></td> </tr>
 <tr> <td>Request:</td> <td><% #data req %></td> </tr>
 <tr> <td>Msg:</td> <td colspan="2"><% Web.html (#msg req) %></td> </tr>
 </table>
@@ -136,6 +142,7 @@ elseif $"cmd" = "list" then
 <table class="blanks">
 <tr> <td>By:</td> <td colspan="2"><a href="user?id=<% #usr req %>"><% name %></a></td> </tr>
 <tr> <td>Time:</td> <td colspan="2"><% #stamp req %></td> </tr>
+<tr> <td>Node:</td> <td><% Web.html (Init.nodeName (#node req)) %></td> </tr>
 <tr> <td>Request:</td> <td><% #data req %></td> </tr>
 <tr> <td>Reason:</td> <td colspan="2"><% Web.html (#msg req) %></td> </tr>
 </table>
@@ -164,6 +171,10 @@ elseif $"mod" <> "" then
        <option value="1"<% if #status req = Sec.Req.INSTALLED then %> selected<% end %>>Installed</option>
        <option value="2"<% if #status req = Sec.Req.REJECTED then %> selected<% end %>>Rejected</option>
 </select></td> </tr>
+<tr> <td>Node:</td> <td><select name="node">
+<% foreach node in Init.listNodes () do %>
+       <option value="<% #id node %>"<% if nodeNum = #node req then %> selected<% end %>><% Web.html (#name node) %> (<% Web.html (#descr node) %>)</option>
+<% end %></select></td> </tr>
 <tr> <td>Request:</td> <td><input name="req" value="<% #data req %>"></td> </tr>
 <tr> <td>Message:</td> <td><textarea name="msg" rows="10" cols="80" wrap="soft"><% Web.html (#msg req) %></textarea></td> </tr>
 <tr> <td><input type="submit" value="Save"></td> </tr>
@@ -177,9 +188,9 @@ elseif $"mod" <> "" then
        val req = Sec.Req.lookup id;
        val oldStatus = #status req;
        val newStatus = Sec.Req.statusFromInt (Web.stoi ($"status"));
-       Sec.Req.modify {req with data = $"req", msg = $"msg", status = newStatus};
+       Sec.Req.modify {req with node = nodeNum, data = $"req", msg = $"msg", status = newStatus};
        if oldStatus <> newStatus then
-               if not (Sec.Req.notifyMod (oldStatus, newStatus, Init.getUserName(), id)) then
+               if not (Sec.Req.notifyMod {old = oldStatus, new = newStatus, changer = Init.getUserName(), req = id}) then
                        %><h3>Error sending e-mail notification</h3><%
                end
        end
@@ -192,7 +203,7 @@ elseif $"mod" <> "" then
        val id = Web.stoi ($"del");
        val req = Sec.Req.lookup id;
        val user = Init.lookupUser (#usr req)
-       %><h3>Are you sure you want to delete request by <% #name user %> for "<% #data req %>"?</h3>
+       %><h3>Are you sure you want to delete request by <% #name user %> for "<% #data req %>" on <% Web.html (Init.nodeName (#node req)) %>?</h3>
        <a href="sec?del2=<% id %>">Yes, I'm sure!</a>
 
 <% elseif $"del2" <> "" then
@@ -207,15 +218,29 @@ elseif $"mod" <> "" then
 
 if showNormal then %>
 
+<table class="blanks">
+<form action="sec" method="post">
+<input type="hidden" name="uname" value="<% Web.html uname %>">
+<tr> <td>Machines:</td> <td><select name="node">
+<% foreach node in Init.listNodes () do %>
+       <option value="<% #id node %>"<% if nodeNum = #id node then %> selected<% end %>><% Web.html (#name node) %> (<% Web.html (#descr node) %>)</option>
+<% end %></select></td>
+<td><input type="submit" value="Switch"></td> </tr>
+</form>
 <form action="sec" method="post">
-<b>Your users:</b> <select name="uname">
+<input type="hidden" name="node" value="<% nodeNum %>">
+<tr> <td>Your users:</td> <td><select name="uname">
 <% foreach name in (yourname :: Sec.findSubusers yourname) do %>
        <option value="<% name %>"<% if uname = name then %> selected<% end %>><% name %></option>
-<% end %></select> <input type="submit" value="Switch"> </form>
+<% end %></select></td>
+<td><input type="submit" value="Switch"></td> </tr>
+</form>
+</table>
 
 <h3>Request socket permissions change</h3>
 
 <form action="sec" method="post">
+<input type="hidden" name="node" value="<% nodeNum %>">
 <input type="hidden" name="uname" value="<% uname %>">
 <input type="hidden" name="cmd" value="socks">
 <table class="blanks">
@@ -233,6 +258,7 @@ if showNormal then %>
 <h3>Request change to your execute permissions</h3>
 
 <form action="sec" method="post">
+<input type="hidden" name="node" value="<% nodeNum %>">
 <input type="hidden" name="uname" value="<% uname %>">
 <input type="hidden" name="cmd" value="tpe">
 <table class="blanks">
@@ -248,6 +274,7 @@ if showNormal then %>
 <h3>Request change to your <tt>cron</tt> permissions</h3>
 
 <form action="sec" method="post">
+<input type="hidden" name="node" value="<% nodeNum %>">
 <input type="hidden" name="uname" value="<% uname %>">
 <input type="hidden" name="cmd" value="cron">
 <table class="blanks">
@@ -265,6 +292,7 @@ if showNormal then %>
 <p>Please read <a href="http://wiki.hcoop.net/wiki/FileTransfer">our wiki instructions on file transfer</a> before requesting FTP access. Almost everyone should use alternative protocols to FTP that provide superior security benefits.</p>
 
 <form action="sec" method="post">
+<input type="hidden" name="node" value="<% nodeNum %>">
 <input type="hidden" name="uname" value="<% uname %>">
 <input type="hidden" name="cmd" value="ftp">
 <table class="blanks">
@@ -277,13 +305,14 @@ if showNormal then %>
 </table>
 </form>
 
-<% val rules = Sec.findFirewallRules uname;
+<% val rules = Sec.findFirewallRules {node = nodeNum, uname = uname};
 switch rules of
   _::_ => %>
 <h3>Your firewall rules</h3>
 
 <% foreach rule in rules do %>
 <form action="sec" method="post">
+<input type="hidden" name="node" value="<% nodeNum %>">
 <input type="hidden" name="uname" value="<% uname %>">
 <input type="hidden" name="modRule" value="<% Web.html rule %>">
 <input name="rule" value="<% Web.html rule %>">
@@ -300,6 +329,7 @@ end%>
 <p>Please note that <b>your firewall rule will be useless</b> if you don't first request the corresponding socket privileges at the top of this page.</p>
 
 <form action="sec" method="post">
+<input type="hidden" name="node" value="<% nodeNum %>">
 <input type="hidden" name="uname" value="<% uname %>">
 <input type="hidden" name="cmd" value="rule">
 <table class="blanks">
diff --git a/sec.sig b/sec.sig
dissimilarity index 63%
index 29882ad..a282b37 100644 (file)
--- a/sec.sig
+++ b/sec.sig
@@ -1,19 +1,18 @@
-signature SEC = sig
-    structure Req : REQUEST_OUT
-
-    val findSubusers : string -> string list
-
-    datatype socket_perms =
-            ANY
-          | CLIENT_ONLY
-          | SERVER_ONLY
-          | NADA
-
-    val inGroup : string * string -> bool
-    val socketPerms : string -> socket_perms
-    val isTpe : string -> bool
-    val cronAllowed : string -> bool
-    val ftpAllowed : string -> bool
-
-    val findFirewallRules : string -> string list
-end
+signature SEC = sig
+    structure Req : REQUESTH_OUT
+
+    val findSubusers : string -> string list
+
+    datatype socket_perms =
+            ANY
+          | CLIENT_ONLY
+          | SERVER_ONLY
+          | NADA
+
+    val socketPerms : {node : int, uname : string} -> socket_perms
+    val isTpe : {node : int, uname : string} -> bool
+    val cronAllowed : {node : int, uname : string} -> bool
+    val ftpAllowed : {node : int, uname : string} -> bool
+
+    val findFirewallRules : {node : int, uname : string} -> string list
+end
diff --git a/sec.sml b/sec.sml
dissimilarity index 69%
index af3f813..782fdf7 100644 (file)
--- a/sec.sml
+++ b/sec.sml
-structure Sec :> SEC = struct
-
-open Init Util Sql
-
-structure Req = Request(struct
-                       val table = "Sec"
-                       val adminGroup = "server"
-                       fun subject _ = "Security permissions change request"
-                       val template = "sec"
-                       val descr = "change"
-                       fun body (mail, req) =
-                           (Mail.mwrite (mail, req);
-                            Mail.mwrite (mail, "\n"))
-                       end)
-
-fun findSubusers uname =
-    let
-       val uname_under = uname ^ "_"
-       val inf = TextIO.openIn "/etc/passwd"
-
-       fun loop subs =
-           case TextIO.inputLine inf of
-               NONE => ListMergeSort.sort (fn (x, y) => String.compare (x, y) = GREATER) subs
-             | SOME line =>
-               case String.fields (fn ch => ch = #":") line of
-                   uname'::_ =>
-                   if size uname' >= size uname_under
-                      andalso String.substring (uname', 0, size uname_under) = uname_under then
-                       loop (uname' :: subs)
-                   else
-                       loop subs
-                 | _ => loop subs
-    in
-       loop []
-       before TextIO.closeIn inf
-    end
-
-datatype socket_perms =
-        ANY
-       | CLIENT_ONLY
-       | SERVER_ONLY
-       | NADA
-
-fun inGroup (uname, grp) =
-    let
-       val uname_under = uname ^ "_"
-       val inf = TextIO.openIn "/etc/group"
-
-       fun loop () =
-           case TextIO.inputLine inf of
-               NONE => false
-             | SOME line =>
-               case String.fields (fn ch => ch = #":") line of
-                   [gname, _, _, members]  =>
-                   if gname = grp then
-                       mem (uname, String.fields (fn ch => ch = #",") members)
-                   else
-                       loop ()
-                 | _ => loop ()
-    in
-       loop ()
-       before TextIO.closeIn inf
-    end    
-
-fun socketPerms uname =
-    if inGroup (uname, "no-sockets") then
-       NADA
-    else if inGroup (uname, "no-cli-sockets") then
-       if inGroup (uname, "no-serv-sockets") then
-           NADA
-       else
-           SERVER_ONLY
-    else if inGroup (uname, "no-serv-sockets") then
-       CLIENT_ONLY
-    else
-       ANY
-
-fun isTpe uname = inGroup (uname, "only-tpe")
-
-fun findFirewallRules uname =
-    let
-       val inf = TextIO.openIn "/etc/firewall/users.rules"
-
-       fun loop rules =
-           case TextIO.inputLine inf of
-               NONE => List.rev rules
-             | SOME line =>
-               if String.sub (line, 0) = #"#" then
-                   loop rules
-               else case String.tokens Char.isSpace line of
-                   uname'::rest =>
-                   if uname = uname' then
-                       loop (String.concatWith " " rest :: rules)
-                   else
-                       loop rules
-                 | _ => loop rules
-    in
-       loop []
-       before TextIO.closeIn inf
-    end
-
-fun somethingAllowed fname uname =
-    let
-       val inf = TextIO.openIn fname
-       val uname' = uname ^ "\n"
-
-       fun loop () =
-           case TextIO.inputLine inf of
-               NONE => false
-             | SOME line => line = uname' orelse loop ()
-    in
-       loop ()
-       before TextIO.closeIn inf
-    end
-
-val cronAllowed = somethingAllowed "/etc/cron.allow"
-val ftpAllowed = somethingAllowed "/etc/ftpusers"
-
-end
+structure Sec :> SEC = struct
+
+open Init Util Sql
+
+structure Req = RequestH(struct
+                        val table = "Sec"
+                        val adminGroup = "server"
+                        fun subject _ = "Security permissions change request"
+                        val template = "sec"
+                        val descr = "change"
+                        fun body {node, mail, data = req} =
+                            (Mail.mwrite (mail, req);
+                             Mail.mwrite (mail, "\n"))
+                        end)
+
+fun findSubusers uname =
+    let
+       val uname_under = uname ^ "_"
+       val inf = TextIO.openIn "/etc/passwd"
+
+       fun loop subs =
+           case TextIO.inputLine inf of
+               NONE => ListMergeSort.sort (fn (x, y) => String.compare (x, y) = GREATER) subs
+             | SOME line =>
+               case String.fields (fn ch => ch = #":") line of
+                   uname'::_ =>
+                   if size uname' >= size uname_under
+                      andalso String.substring (uname', 0, size uname_under) = uname_under then
+                       loop (uname' :: subs)
+                   else
+                       loop subs
+                 | _ => loop subs
+    in
+       loop []
+       before TextIO.closeIn inf
+    end
+
+datatype socket_perms =
+        ANY
+       | CLIENT_ONLY
+       | SERVER_ONLY
+       | NADA
+
+fun socketPerms {node, uname} =
+    let
+       val proc = Unix.execute ("/bin/sh",
+                                ["-c",
+                                 "DOMTOOL_USER=apache2.deleuze.hcoop.net /usr/local/bin/domtool-admin sockperm "
+                                 ^ Init.nodeName node ^ " " ^ uname])
+                  
+       val inf = Unix.textInstreamOf proc
+
+       val p = case TextIO.inputLine inf of
+                   SOME "Any\n" => ANY
+                 | SOME "Client\n" => CLIENT_ONLY
+                 | SOME "Server\n" => SERVER_ONLY
+                 | _ => NADA
+    in
+       TextIO.closeIn inf;
+       if OS.Process.isSuccess (Unix.reap proc) then
+           p
+       else
+           NADA
+    end
+
+fun checkIt cmd {node, uname} =
+    OS.Process.isSuccess (OS.Process.system
+                             ("DOMTOOL_USER=apache2.deleuze.hcoop.net /usr/local/bin/domtool-admin "
+                              ^ cmd ^ " " ^ Init.nodeName node ^ " " ^ uname ^ " >/dev/null 2>/dev/null"))
+
+val isTpe = checkIt "tpe"
+val cronAllowed = checkIt "cron"
+val ftpAllowed = checkIt "ftp"
+
+fun findFirewallRules {node, uname} =
+    let
+       val proc = Unix.execute ("/bin/sh",
+                                ["-c",
+                                 "DOMTOOL_USER=apache2.deleuze.hcoop.net /usr/local/bin/domtool-admin firewall "
+                                 ^ Init.nodeName node ^ " " ^ uname])
+                  
+       val inf = Unix.textInstreamOf proc
+
+       fun readEm lines =
+           case TextIO.inputLine inf of
+                   SOME line => readEm (String.substring (line, 0, size line - 1) :: lines)
+                 | NONE => rev lines
+
+       val lines = readEm []
+    in
+       TextIO.closeIn inf;
+       if OS.Process.isSuccess (Unix.reap proc) then
+           lines
+       else
+           []
+    end
+
+end
index 35cfb29..cc2ff98 100644 (file)
@@ -298,6 +298,7 @@ CREATE TABLE RollCallEntry(
 CREATE TABLE Sec(
        id INTEGER PRIMARY KEY,
        usr INTEGER NOT NULL,
+       node INTEGER NOT NULL,
        data TEXT NOT NULL,
        msg TEXT NOT NULL,
        status INTEGER NOT NULL,