context Vhost;
{{A WWW virtual host}}
+extern type suexec_flag;
+extern val suexec_flag : bool -> suexec_flag;
+{{Whether or not to use Suexec with a vhost.
+[suexec_flag] fails when passed [false] by a user without the 'www' privilege.}}
+
extern val vhost : host -> Vhost => [Domain]
{WebNodes : [web_node],
SSL : bool,
User : your_user,
Group : your_group,
DocumentRoot : your_path,
- ServerAdmin : email};
+ ServerAdmin : email,
+ SuExec : suexec_flag};
{{Add a new named Apache virtual host, specifying which nodes' Apache servers
should answer requests for this host, whether it should use SSL, what UNIX
user and group dynamic content generators should be run as, the filesystem
Env.string
(CharVector.all Char.isAlphaNum)
+val _ = Env.type_one "suexec_flag"
+ Env.bool
+ (fn b => b orelse Domain.hasPriv "www")
+
fun validLocation s =
size s > 0 andalso size s < 1000 andalso CharVector.all
(fn ch => Char.isAlphaNum ch
(TBase "email", dl),
(fn () => (EString (Domain.getUser () ^ "@" ^ Config.defaultDomain), dl)))
+val _ = Defaults.registerDefault ("SuExec",
+ (TBase "suexec_flag", dl),
+ (fn () => (EApp ((EVar "suexec_flag", dl),
+ (EVar "true", dl)), dl)))
val redirect_code = fn (EVar "temp", _) => SOME "temp"
| (EVar "permanent", _) => SOME "permanent"
case TextIO.inputLine inf of
NONE => NONE
| SOME line =>
- case String.tokens Char.isSpace line of
- ["SuexecUserGroup", user, _] => SOME user
- | _ => loop ()
+ if String.isPrefix "# Owner: " line then
+ case String.tokens Char.isSpace line of
+ [_, _, user] => SOME user
+ | _ => NONE
+ else
+ loop ()
in
loop ()
before TextIO.closeIn inf
aliaser := (fn x => (old x; f x))
end
+fun suexec_flag (EApp ((EVar "suexec_flag", _), e), _) = Env.bool e
+ | suexec_flag _ = NONE
+
val () = Env.containerV_one "vhost"
("host", Env.string)
(fn (env, host) =>
val group = Env.env Env.string (env, "Group")
val docroot = Env.env Env.string (env, "DocumentRoot")
val sadmin = Env.env Env.string (env, "ServerAdmin")
+ val suexec = Env.env suexec_flag (env, "SuExec")
val fullHost = host ^ "." ^ Domain.currentDomain ()
val vhostId = fullHost ^ (if ssl then ".ssl" else "")
val file = Domain.domainFile {node = node,
name = confFile}
in
- TextIO.output (file, "<VirtualHost ");
+ TextIO.output (file, "# Owner: ");
+ TextIO.output (file, user);
+ TextIO.output (file, "\n<VirtualHost ");
TextIO.output (file, Domain.nodeIp node);
TextIO.output (file, ":");
TextIO.output (file, if ssl then
nodes;
write "\tServerName ";
write fullHost;
- write "\n\tSuexecUserGroup ";
- write user;
- write " ";
- write group;
+ if suexec then
+ (write "\n\tSuexecUserGroup ";
+ write user;
+ write " ";
+ write group)
+ else
+ ();
write "\n\tDocumentRoot ";
write docroot;
write "\n\tServerAdmin ";