val defaultPhpVersion = 4
+val waklogUserFile = "/var/domtool/waklog.conf"
+
end
val defaultPhpVersion : int
+ val waklogUserFile : string
+
end
file = ".domtool"}
val worldReadable = ["/usr/share/moin", "/usr/share/apache/icons"]
+
+val publish_reusers = "/usr/bin/sudo " ^ domtool_publish ^ " users"
val domtoolDir : string -> string
val worldReadable : string list
+
+val publish_reusers : string
apache1.3-fixperms)
/bin/chown -R domtool.domtool /var/log/apache/user
;;
+ users)
+ /bin/cp /var/domtool/waklog.conf /etc/apache2/
+ /etc/init.d/apache2 reload
+ ;;
*)
- echo "Usage: domtool-publish [apache|bind|courier|exim|mailman|smtplog STRING]"
+ echo "Usage: domtool-publish [apache|bind|courier|exim|mailman|smtplog STRING|users]"
;;
esac
val considerAll : description list -> subject -> string
(* Find files in a domain directory matching some patterns and generate
* headings and contents listings for them. *)
+
+ (* Callbacks to run whenever the set of Domtool users has changed *)
+ val registerOnUsersChange : (unit -> unit) -> unit
+ val onUsersChange : unit -> unit
end
(EString (host ^ "." ^ currentDomain ()), dl))
| (_, args) => Env.badArgs ("domainHost", args))
+val ouc = ref (fn () => ())
+
+fun registerOnUsersChange f =
+ let
+ val f' = !ouc
+ in
+ ouc := (fn () => (f' (); f ()))
+ end
+
+fun onUsersChange () = !ouc ()
+
end
| ["users"] =>
(Acl.read Config.aclFile;
app (fn s => (print s; print "\n")) (Acl.users ()))
+ | ["reusers"] => Main.requestReUsers ()
| _ => (print "Invalid command-line arguments\n";
print "See the documentation: http://wiki.hcoop.net/DomTool/AdminProcedures\n"))
val requestRegenTc : unit -> unit
val requestRmuser : string -> unit
val requestDescribe : string -> unit
+ val requestReUsers : unit -> unit
val requestSlavePing : unit -> OS.Process.status
val requestSlaveShutdown : unit -> unit
(* HCoop Domtool (http://hcoop.sourceforge.net/)
- * Copyright (c) 2006-2007, Adam Chlipala
+ * Copyright (c) 2006-2009, Adam Chlipala
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
val (_, files) = Order.order (SOME b) files
val _ = if !ErrorMsg.anyErrors then
- (print "J\n";raise ErrorMsg.Error)
+ raise ErrorMsg.Error
else
()
OpenSSL.close bio
end
+fun requestReUsers () =
+ let
+ val (_, bio) = requestBio (fn () => ())
+ in
+ Msg.send (bio, MsgReUsers);
+ case Msg.recv bio of
+ NONE => print "Server closed connection unexpectedly.\n"
+ | SOME m =>
+ case m of
+ MsgOk => print "Callbacks run.\n"
+ | MsgError s => print ("Failed: " ^ s ^ "\n")
+ | _ => print "Unexpected server reply.\n";
+ OpenSSL.close bio
+ end
+
structure SS = StringSet
fun domainList dname =
(fn G => fn evs => fn file =>
(#1 (check G file), evs))
+fun usersChanged () =
+ (Domain.onUsersChange ();
+ ignore (OS.Process.system Config.publish_reusers))
+
fun rmuser user =
let
val doms = Acl.class {user = user, class = "domain"}
| _ => false) (StringSet.listItems doms)
in
Acl.rmuser user;
- Domain.rmdom doms
+ Domain.rmdom doms;
+ usersChanged ()
end
fun now () = Date.toString (Date.fromTimeUniv (Time.now ()))
if Acl.query {user = user, class = "priv", value = "all"} then
(Acl.grant acl;
Acl.write Config.aclFile;
+ if #class acl = "user" then
+ usersChanged ()
+ else
+ ();
("Granted permission " ^ #value acl ^ " to " ^ #user acl ^ " in " ^ #class acl ^ ".",
NONE))
else
NONE)))
(fn () => ())
+ | MsgReUsers =>
+ doIt (fn () => (usersChanged ();
+ ("Users change callbacks run", NONE)))
+ (fn () => ())
+
| _ =>
doIt (fn () => ("Unexpected command",
SOME "Unexpected command"))
OpenSSL.writeString (bio, dom))
| MsgDescription s => (OpenSSL.writeInt (bio, 40);
OpenSSL.writeString (bio, s))
+ | MsgReUsers => OpenSSL.writeInt (bio, 41)
fun checkIt v =
case v of
| 38 => SOME MsgMysqlFixperms
| 39 => Option.map MsgDescribe (OpenSSL.readString bio)
| 40 => Option.map MsgDescription (OpenSSL.readString bio)
+ | 41 => SOME MsgReUsers
| _ => NONE)
end
(* Ask for a listing of all of a domain's real configuration *)
| MsgDescription of string
(* Reply to MsgDescribe *)
+ | MsgReUsers
+ (* Rerun all callbacks for cases where the set of users has changed *)
end
val () = Env.action_none "testNoHtaccess"
(fn path => write "\tAllowOverride None\n")
+fun writeWaklogUserFile () =
+ let
+ val users = Acl.users ()
+ val outf = TextIO.openOut Config.Apache.waklogUserFile
+ in
+ app (fn user => if String.isSuffix "_admin" user then
+ ()
+ else
+ (TextIO.output (outf, "<Location /~");
+ TextIO.output (outf, user);
+ TextIO.output (outf, ">\n\tWaklogEnabled on\n\tWaklogLocationPrincipal ");
+ TextIO.output (outf, user);
+ TextIO.output (outf, "/daemon@HCOOP.NET /etc/keytabs/user.daemon/");
+ TextIO.output (outf, user);
+ TextIO.output (outf, "\n</Location>\n\n"))) users;
+ TextIO.closeOut outf
+ end
+
+val () = Domain.registerOnUsersChange writeWaklogUserFile
+
end