structure MySQL :> MYSQL_CONFIG = struct
val adduser = "/usr/bin/sudo /usr/local/sbin/domtool-mysql adduser "
+val passwd = "/usr/bin/sudo /usr/local/sbin/domtool-mysql passwd "
val createdb = "/usr/bin/sudo /usr/local/sbin/domtool-mysql createdb "
end
signature MYSQL_CONFIG = sig
val adduser : string
+val passwd : string
val createdb : string
end
type handler = {getpass : (unit -> Client.passwd_result) option,
adduser : {user : string, passwd : string option} -> string option,
+ passwd : {user : string, passwd : string} -> string option,
createdb : {user : string, dbname : string} -> string option}
val register : string * handler -> unit
type handler = {getpass : (unit -> Client.passwd_result) option,
adduser : {user : string, passwd : string option} -> string option,
+ passwd : {user : string, passwd : string} -> string option,
createdb : {user : string, dbname : string} -> string option}
val dbmses : handler StringMap.map ref = ref StringMap.empty
NONE => ()
| SOME pass => Main.requestDbUser {dbtype = dbtype, passwd = pass}
end
+ | ["passwd"] =>
+ let
+ val pass = case getpass of
+ NONE => NONE
+ | SOME f =>
+ case f () of
+ Client.Passwd pass => SOME pass
+ | _ => NONE
+ in
+ case pass of
+ NONE => ()
+ | SOME pass => Main.requestDbPasswd {dbtype = dbtype, passwd = pass}
+ end
| ["createdb", dbname] =>
if Dbms.validDbname dbname then
Main.requestDbTable {dbtype = dbtype, dbname = dbname}
val autodocBasis : string -> unit
val requestDbUser : {dbtype : string, passwd : string option} -> unit
+ val requestDbPasswd : {dbtype : string, passwd : string} -> unit
val requestDbTable : {dbtype : string, dbname : string} -> unit
val requestListMailboxes : string -> Vmail.listing
OpenSSL.close bio
end
+fun requestDbPasswd rc =
+ let
+ val (_, bio) = requestBio (fn () => ())
+ in
+ Msg.send (bio, MsgDbPasswd rc);
+ case Msg.recv bio of
+ NONE => print "Server closed connection unexpectedly.\n"
+ | SOME m =>
+ case m of
+ MsgOk => print "Your password has been changed.\n"
+ | MsgError s => print ("Password set failed: " ^ s ^ "\n")
+ | _ => print "Unexpected server reply.\n";
+ OpenSSL.close bio
+ end
+
fun requestDbTable p =
let
val (user, bio) = requestBio (fn () => ())
SOME ("Error adding user: " ^ msg)))
(fn () => ())
+ | MsgDbPasswd {dbtype, passwd} =>
+ doIt (fn () =>
+ case Dbms.lookup dbtype of
+ NONE => ("Database passwd request with unknown datatype type " ^ dbtype,
+ SOME ("Unknown database type " ^ dbtype))
+ | SOME handler =>
+ case #passwd handler {user = user, passwd = passwd} of
+ NONE => ("Changed " ^ dbtype ^ " password of user " ^ user ^ ".",
+ NONE)
+ | SOME msg =>
+ ("Error setting " ^ dbtype ^ " password of user " ^ user ^ ": " ^ msg,
+ SOME ("Error adding user: " ^ msg)))
+ (fn () => ())
+
| MsgCreateDbTable {dbtype, dbname} =>
doIt (fn () =>
if Dbms.validDbname dbname then
OpenSSL.writeString (bio, domain))
| MsgSmtpLogRes domain => (OpenSSL.writeInt (bio, 27);
OpenSSL.writeString (bio, domain))
+ | MsgDbPasswd {dbtype, passwd} => (OpenSSL.writeInt (bio, 28);
+ OpenSSL.writeString (bio, dbtype);
+ OpenSSL.writeString (bio, passwd))
fun checkIt v =
case v of
| _ => NONE)
| 26 => Option.map MsgSmtpLogReq (OpenSSL.readString bio)
| 27 => Option.map MsgSmtpLogRes (OpenSSL.readString bio)
+ | 28 => (case (OpenSSL.readString bio, OpenSSL.readString bio) of
+ (SOME dbtype, SOME passwd) =>
+ SOME (MsgDbPasswd {dbtype = dbtype, passwd = passwd})
+ | _ => NONE)
| _ => NONE)
end
(* Request all current SMTP log lines about a domain *)
| MsgSmtpLogRes of string
(* One line of a response to MsgSmtpLogReq *)
+ | MsgDbPasswd of {dbtype : string, passwd : string}
+ (* Change a DBMS user's password *)
end
sudo -H mysql -e "CREATE USER '$USERNAME'@'localhost' IDENTIFIED BY '$PASSWORD';"
;;
+ passwd)
+ USERNAME=$2
+ PASSWORD=$3
+
+ sudo -H mysql -e "SET PASSWORD FOR '$USERNAME'@'localhost' = PASSWORD('$PASSWORD');"
+ ;;
createdb)
USERNAME=$2
DBNAME_BASE=$3
sudo -H mysql -e "FLUSH PRIVILEGES;"
;;
*)
- echo "Usage: domtool-mysql [adduser <user> <password> | createdb <user> <table>]"
+ echo "Usage: domtool-mysql [adduser <user> <password> | passwd <user> <password> | createdb <user> <table>]"
;;
esac
else
SOME "Password contains characters besides letters, digits, and !.-_"
+fun passwd {user, passwd} =
+ if validPasswd passwd then
+ if Slave.shell [Config.MySQL.passwd, user, " ", passwd] then
+ NONE
+ else
+ SOME "Error executing SET PASSWORD script"
+ else
+ SOME "Password contains characters besides letters, digits, and !.-_"
+
fun createdb {user, dbname} =
if Slave.shell [Config.MySQL.createdb, user, " ", dbname] then
NONE
val _ = Dbms.register ("mysql", {getpass = SOME Client.getpass,
adduser = adduser,
+ passwd = passwd,
createdb = createdb})
end
else
SOME "Error executing CREATE USER script"
+fun passwd _ = SOME "We don't use PostgreSQL passwords."
+
fun createdb {user, dbname} =
if Slave.shell [Config.Postgres.createdb, user, " ", dbname] then
NONE
val _ = Dbms.register ("postgres", {getpass = NONE,
adduser = adduser,
+ passwd = passwd,
createdb = createdb})
end