MySQL password changing
authorAdam Chlipala <adamc@hcoop.net>
Sat, 10 Feb 2007 21:47:03 +0000 (21:47 +0000)
committerAdam Chlipala <adamc@hcoop.net>
Sat, 10 Feb 2007 21:47:03 +0000 (21:47 +0000)
12 files changed:
configDefault/mysql.cfg
configDefault/mysql.csg
src/dbms.sig
src/dbms.sml
src/main-dbtool.sml
src/main.sig
src/main.sml
src/msg.sml
src/msgTypes.sml
src/plugins/domtool-mysql
src/plugins/mysql.sml
src/plugins/postgres.sml

index c199248..1058bee 100644 (file)
@@ -1,6 +1,7 @@
 structure MySQL :> MYSQL_CONFIG = struct
 
 val adduser = "/usr/bin/sudo /usr/local/sbin/domtool-mysql adduser "
 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
 val createdb = "/usr/bin/sudo /usr/local/sbin/domtool-mysql createdb "
 
 end
index 7a05d02..39004ff 100644 (file)
@@ -1,6 +1,7 @@
 signature MYSQL_CONFIG = sig
 
 val adduser : string
 signature MYSQL_CONFIG = sig
 
 val adduser : string
+val passwd : string
 val createdb : string
 
 end
 val createdb : string
 
 end
index 1107c5e..deb2127 100644 (file)
@@ -24,6 +24,7 @@ signature DBMS = sig
 
     type handler = {getpass : (unit -> Client.passwd_result) option,
                    adduser : {user : string, passwd : string option} -> string option,
 
     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
                    createdb : {user : string, dbname : string} -> string option}
 
     val register : string * handler -> unit
index a1f44d7..fd04fd7 100644 (file)
@@ -26,6 +26,7 @@ val validDbname = CharVector.all Char.isAlpha
 
 type handler = {getpass : (unit -> Client.passwd_result) option,
                adduser : {user : string, passwd : string option} -> string option,
 
 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
                createdb : {user : string, dbname : string} -> string option}
               
 val dbmses : handler StringMap.map ref = ref StringMap.empty
index 32793d7..a571159 100644 (file)
@@ -40,6 +40,19 @@ val _ =
                        NONE => ()
                      | SOME pass => Main.requestDbUser {dbtype = dbtype, passwd = pass}
                end
                        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}
              | ["createdb", dbname] =>
                if Dbms.validDbname dbname then
                    Main.requestDbTable {dbtype = dbtype, dbname = dbname}
index c4f9b19..ca699b8 100644 (file)
@@ -49,6 +49,7 @@ signature MAIN = sig
     val autodocBasis : string -> unit
 
     val requestDbUser : {dbtype : string, passwd : string option} -> unit
     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
     val requestDbTable : {dbtype : string, dbname : string} -> unit
 
     val requestListMailboxes : string -> Vmail.listing
index f9b2c9f..7403743 100644 (file)
@@ -401,6 +401,21 @@ fun requestDbUser dbtype =
        OpenSSL.close bio
     end
 
        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 () => ())
 fun requestDbTable p =
     let
        val (user, bio) = requestBio (fn () => ())
@@ -805,6 +820,20 @@ fun service () =
                                                  SOME ("Error adding user: " ^ msg)))
                                     (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
                              | MsgCreateDbTable {dbtype, dbname} =>
                                doIt (fn () =>
                                         if Dbms.validDbname dbname then
index cf7edbf..a9063aa 100644 (file)
@@ -166,6 +166,9 @@ fun send (bio, m) =
                                 OpenSSL.writeString (bio, domain))
       | MsgSmtpLogRes domain => (OpenSSL.writeInt (bio, 27);
                                 OpenSSL.writeString (bio, domain))
                                 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
 
 fun checkIt v =
     case v of
@@ -256,6 +259,10 @@ fun recv bio =
                              | _ => NONE)
                   | 26 => Option.map MsgSmtpLogReq (OpenSSL.readString bio)
                   | 27 => Option.map MsgSmtpLogRes (OpenSSL.readString bio)
                              | _ => 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
                   | _ => NONE)
         
 end
index efcbefa..445f8af 100644 (file)
@@ -79,5 +79,7 @@ datatype msg =
        (* Request all current SMTP log lines about a domain *)
        | MsgSmtpLogRes of string
        (* One line of a response to MsgSmtpLogReq *)
        (* 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
 
 end
index 02dcefa..d2c5298 100755 (executable)
@@ -17,6 +17,12 @@ case $1 in
 
                sudo -H mysql -e "CREATE USER '$USERNAME'@'localhost' IDENTIFIED BY '$PASSWORD';"
        ;;
 
                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
        createdb)
                USERNAME=$2
                DBNAME_BASE=$3
@@ -40,6 +46,6 @@ case $1 in
                sudo -H mysql -e "FLUSH PRIVILEGES;"
        ;;
        *)
                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
        ;;
 esac
index 7da242b..dae75cc 100644 (file)
@@ -38,6 +38,15 @@ fun adduser {user, passwd} =
        else
            SOME "Password contains characters besides letters, digits, and !.-_"
 
        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
 fun createdb {user, dbname} =
     if Slave.shell [Config.MySQL.createdb, user, " ", dbname] then
        NONE
@@ -46,6 +55,7 @@ fun createdb {user, dbname} =
 
 val _ = Dbms.register ("mysql", {getpass = SOME Client.getpass,
                                 adduser = adduser,
 
 val _ = Dbms.register ("mysql", {getpass = SOME Client.getpass,
                                 adduser = adduser,
+                                passwd = passwd,
                                 createdb = createdb})
 
 end
                                 createdb = createdb})
 
 end
index c2539eb..1689840 100644 (file)
@@ -26,6 +26,8 @@ fun adduser {user, passwd} =
     else
        SOME "Error executing CREATE USER script"
 
     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
 fun createdb {user, dbname} =
     if Slave.shell [Config.Postgres.createdb, user, " ", dbname] then
        NONE
@@ -34,6 +36,7 @@ fun createdb {user, dbname} =
 
 val _ = Dbms.register ("postgres", {getpass = NONE,
                                    adduser = adduser,
 
 val _ = Dbms.register ("postgres", {getpass = NONE,
                                    adduser = adduser,
+                                   passwd = passwd,
                                    createdb = createdb})
 
 end
                                    createdb = createdb})
 
 end