This task has three parts:

 Connect to a MySQL database (connect_db)
 Create user/password records in the following table (create_user)
 Authenticate login requests against the table (authenticate_user)
This is the table definition:

CREATE TABLE users (
    userid INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(32) UNIQUE KEY NOT NULL,
    pass_salt tinyblob NOT NULL,
            -- a string of 16 random bytes
    pass_md5 tinyblob NOT NULL
            -- binary MD5 hash of pass_salt concatenated with the password
);
(pass_salt and pass_md5 would be binary(16) values, but MySQL versions before 5.0.15 strip trailing spaces when selecting them.)

package require tdbc
 
proc connect_db {handleName dbname host user pass} {
    package require tdbc::mysql
    tdbc::mysql::connection create $handleName -user $user -passwd $pass \
        -host $host -database $dbname
    return $handleName
}
 
# A simple helper to keep code shorter
proc r64k {} {
    expr int(65536*rand())
}
 
proc create_user {handle user pass} {
    set salt [binary format ssssssss \
        [r64k] [r64k] [r64k] [r64k] [r64k] [r64k] [r64k] [r64k]]
    # Note that we are using named parameters below, :user :salt :pass
    # They are bound automatically to local variables with the same name
    $handle allrows {
        INSERT IGNORE INTO users (username, pass_salt, pass_md5)
            VALUES (:user, :salt, unhex(md5(concat(:salt, :pass))))
    }
    return   ;# Ignore the result of the allrows method
}
 
proc authenticate_user {handle user pass} {
    $handle foreach row {
        SELECT userid FROM users WHERE
            username=:user AND pass_md5=unhex(md5(concat(pass_salt, :pass)))
    } {
        return [dict get $row userid]
    }
    # Only get here if no rows selected
    error "authentication failed for user \"$user\""
}