X-Git-Url: https://git.hcoop.net/hcoop/domtool2.git/blobdiff_plain/7af7d4cb58acc571a75b51c0dd0f1b4d9c92e619..411a85f26421358c20b11839310cce6caff8cf77:/src/main.sml diff --git a/src/main.sml b/src/main.sml index 19162a3..9204159 100644 --- a/src/main.sml +++ b/src/main.sml @@ -58,7 +58,9 @@ fun basis () = if !ErrorMsg.anyErrors then Env.empty else - foldl (fn (fname, G) => check' G fname) Env.empty files + (Tycheck.allowExterns (); + foldl (fn (fname, G) => check' G fname) Env.empty files + before Tycheck.disallowExterns ()) end fun check fname = @@ -72,6 +74,7 @@ fun check fname = raise ErrorMsg.Error else let + val _ = Tycheck.disallowExterns () val _ = ErrorMsg.reset () val prog = Parse.parse fname in @@ -122,33 +125,33 @@ fun eval fname = val dispatcher = Config.dispatcher ^ ":" ^ Int.toString Config.dispatcherPort -fun hostname () = - let - val inf = TextIO.openIn "/etc/hostname" - in - case TextIO.inputLine inf of - NONE => (TextIO.closeIn inf; raise Fail "No line in /etc/hostname") - | SOME line => (TextIO.closeIn inf; String.substring (line, 0, size line - 1)) - end - -fun request fname = +fun requestContext f = let val uid = Posix.ProcEnv.getuid () val user = Posix.SysDB.Passwd.name (Posix.SysDB.getpwuid uid) - + val () = Acl.read Config.aclFile val () = Domain.setUser user - - val _ = check fname - - val uid = Posix.ProcEnv.getuid () - val user = Posix.SysDB.Passwd.name (Posix.SysDB.getpwuid uid) + + val () = f () val context = OpenSSL.context (Config.certDir ^ "/" ^ user ^ ".pem", Config.keyDir ^ "/" ^ user ^ "/key.pem", Config.trustStore) + in + (user, context) + end + +fun requestBio f = + let + val (user, context) = requestContext f + in + (user, OpenSSL.connect (context, dispatcher)) + end - val bio = OpenSSL.connect (context, dispatcher) +fun request fname = + let + val (user, bio) = requestBio (fn () => ignore (check fname)) val inf = TextIO.openIn fname @@ -172,6 +175,36 @@ fun request fname = end handle ErrorMsg.Error => () +fun requestGrant acl = + let + val (user, bio) = requestBio (fn () => ()) + in + Msg.send (bio, MsgGrant acl); + case Msg.recv bio of + NONE => print "Server closed connection unexpectedly.\n" + | SOME m => + case m of + MsgOk => print "Grant succeeded.\n" + | MsgError s => print ("Grant failed: " ^ s ^ "\n") + | _ => print "Unexpected server reply.\n"; + OpenSSL.close bio + end + +fun requestRevoke acl = + let + val (user, bio) = requestBio (fn () => ()) + in + Msg.send (bio, MsgRevoke acl); + case Msg.recv bio of + NONE => print "Server closed connection unexpectedly.\n" + | SOME m => + case m of + MsgOk => print "Revoke succeeded.\n" + | MsgError s => print ("Revoke failed: " ^ s ^ "\n") + | _ => print "Unexpected server reply.\n"; + OpenSSL.close bio + end + fun service () = let val () = Acl.read Config.aclFile @@ -212,22 +245,71 @@ fun service () = TextIO.closeOut outf; (eval outname; Msg.send (bio, MsgOk)) - handle ErrorMsg.Error => - (print "Compilation error\n"; + handle ErrorMsg.Error => + (print "Compilation error\n"; + Msg.send (bio, + MsgError "Error during configuration evaluation")) + | OpenSSL.OpenSSL s => + (print "OpenSSL error\n"; + Msg.send (bio, + MsgError + ("Error during configuration evaluation: " + ^ s))); + OS.FileSys.remove outname; + (ignore (OpenSSL.readChar bio); + OpenSSL.close bio) + handle OpenSSL.OpenSSL _ => (); + loop () + end + + | MsgGrant acl => + if Acl.query {user = user, class = "group", value = "root"} then + ((Acl.grant acl; + Acl.write Config.aclFile; + Msg.send (bio, MsgOk); + print ("Granted permission " ^ #value acl ^ " to " ^ #user acl ^ " in " ^ #class acl ^ ".\n")) + handle OpenSSL.OpenSSL s => + (print "OpenSSL error\n"; Msg.send (bio, - MsgError "Error during configuration evaluation")) - | OpenSSL.OpenSSL s => + MsgError + ("Error during granting: " + ^ s))); + (ignore (OpenSSL.readChar bio); + OpenSSL.close bio) + handle OpenSSL.OpenSSL _ => (); + loop ()) + else + ((Msg.send (bio, MsgError "Not authorized to grant privileges"); + print "Unauthorized user asked to grant a permission!\n"; + ignore (OpenSSL.readChar bio); + OpenSSL.close bio) + handle OpenSSL.OpenSSL _ => (); + loop ()) + + | MsgRevoke acl => + if Acl.query {user = user, class = "group", value = "root"} then + ((Acl.revoke acl; + Acl.write Config.aclFile; + Msg.send (bio, MsgOk); + print ("Revoked permission " ^ #value acl ^ " from " ^ #user acl ^ " in " ^ #class acl ^ ".\n")) + handle OpenSSL.OpenSSL s => (print "OpenSSL error\n"; Msg.send (bio, MsgError - ("Error during configuration evaluation: " + ("Error during revocation: " ^ s))); - OS.FileSys.remove outname; (ignore (OpenSSL.readChar bio); OpenSSL.close bio) handle OpenSSL.OpenSSL _ => (); - loop () - end + loop ()) + else + ((Msg.send (bio, MsgError "Not authorized to revoke privileges"); + print "Unauthorized user asked to revoke a permission!\n"; + ignore (OpenSSL.readChar bio); + OpenSSL.close bio) + handle OpenSSL.OpenSSL _ => (); + loop ()) + | _ => (Msg.send (bio, MsgError "Unexpected command") handle OpenSSL.OpenSSL _ => (); @@ -237,6 +319,16 @@ fun service () = in cmdLoop () end + handle OpenSSL.OpenSSL s => + (print ("OpenSSL error: " ^ s ^ "\n"); + OpenSSL.close bio + handle OpenSSL.OpenSSL _ => (); + loop ()) + | OS.SysErr (s, _) => + (print ("System error: " ^ s ^ "\n"); + OpenSSL.close bio + handle OpenSSL.OpenSSL _ => (); + loop ()) in print "Listening for connections....\n"; loop (); @@ -245,7 +337,7 @@ fun service () = fun slave () = let - val host = hostname () + val host = Slave.hostname () val context = OpenSSL.context (Config.certDir ^ "/" ^ host ^ ".pem", Config.keyDir ^ "/" ^ host ^ "/key.pem",