mysql jdbc apply exceeding username max length (16 char) - java

I have a system that mostly written in java. This system has a simple MySQL user permission administrator. But now we getting started to work with more users and the length for the username is now over 16 chars. I modified all username length property in all mysql system tables. In Webmin and PhPMyAdmin modifying the password and table <=> user relations works correctly. But in this java program all operation witch associated with long usernames will be stopped with throwned SQLException with message: String ' ...long username...' is too long for user name (should be no longer than 16).
So looks like the problem is in jdbc. How can i force to apply long usernames in SQL operations?
(com.mysql.jdbc (5.1.24))
Query String:
st.execute("CREATE USER '"+user+"'#'localhost' IDENTIFIED BY 'nothing';");
st.execute("SET PASSWORD FOR '"+user+"'#'localhost' = PASSWORD('"+passwd+"');");
Stack Trace:
java.sql.SQLException: String '...long username...' is too long for user name (should be no longer than 16)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.ja$
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4120)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2809)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2758)
at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:894)
at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:732)

You can't change the MySQL username length without recompiling the MySQL source. See this note in the 5.1 documentation. This is also the case with MySQL 5.7.
Warning
The limit on MySQL user name length is hard-coded in the MySQL servers
and clients, and trying to circumvent it by modifying the definitions
of the tables in the mysql database does not work.

I found a better solution:
Use
"INSERT mysql.user (Host,user,Password) VALUES 'localhost','"+user+"',PASSWORD('"+passwd+"');");
instread of
SET PASSWORD FOR '"+user+"'#'localhost' = PASSWORD('"+passwd+"');
The MySQL will not know, that you modify the password or create user, just run the statement.

Related

utf8_unicode_ci String is inserted incorrectly?

I have java application through which I do different operations on MySQL DB. The probleam is that when inserting utf8 String it is not inserted correctly. The charset of DB is utf8 and I have set collation to utf8_unicode_ci. Server connection collation is also utf8_unicode_ci. Furthermore when I insert data from phpMyAdmin it is inserted correctly, but when I do it from Java application using JOOQ - it is not. Example:
Result<ExecutorsRecord> executorsRecord =
context.insertInto(EXECUTORS, EXECUTORS.ID, EXECUTORS.NAME, EXECUTORS.SURNAME, EXECUTORS.REGION, EXECUTORS.PHONE, EXECUTORS.POINTS, EXECUTORS.E_TYPE)
.values(id, name, surname, region, phone, 0, type)
.returning(EXECUTORS.ID)
.fetch();
where name = "Бобр" and surname = "Добр", produces tuple with ???? as a name and ???? as surname. I have checked both strings, they are passed correctly to the method correctly.
As #spencer7593 suggested the problem could be in JDBC connector. So I added into url of connection following: ?characterEncoding=utf8 so that final url was "jdbc:mysql://localhost:3306/mydb?characterEncoding=utf8", where mydb is a name of database. This has sorted out my problem. Also I would like to add the following statement (again by #spencer7593):
When we've got things configured correctly, and things aren't working, our goto suspect is the JDBC driver. To get timezone differences between the JVM and the MySQL database sorted out, to prevent the JDBC driver from "helping" by doing an illogical combination of various operations, we had to add two extra obscurely documented settings to the connection string.
Further reading

Sql query error in java program

I have developed a java program and I need to update and insert the login details of users. I have two textfields created and two buttons name add user and edit the user. when I type the username and password in the two textfields the user added to the database successfully, the error is in the edit user, I want to update the password of the user based on username,
I'm getting SQL error when trying to update the user,
here is my SQL query for updating the password of a user based on his username,
String sql = "UPDATE Admin SET password='"+JT_pass1.getText()+"' WHERE
username = "+JT_username1.getText();
when i execute im getting this error,
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column
'sss' in 'where clause'
"sss" is what I entered to username field,
Mysql database I have admin table which consists of two columns admin and username,
I cannot figure out where am I getting wrong, please any help would be highly appreciated.
Your immediate problem is that you forgot to place single quotes around the username in your query. Hence, the database is interpreting sss as a column. But you should really be using prepared statements:
String query = "UPDATE Admin SET password=? WHERE username = ?";
PreparedStatement update = con.prepareStatement(query);
update.setString(JT_pass1.getText());
update.setString(JT_username1.getText());
update.executeUpdate();
There are many advantages to using prepared statements. First, it will automatically take care of proper escaping of strings and other types of data. In addition, it will prevent SQL injection from happening.
To get this to work, you need to add quotes around the username like so:
String sql = "UPDATE Admin SET password='"+JT_pass1.getText()+"' WHERE
username = '"+JT_username1.getText()+"'";
However, updating the database this way is vulnerable to SQL injection, so it would be much better to use Prepared Statements.
To consider "JT_username1.getText()" as a part of you query string, you have to enclose it under proper quotation.
Same like added "JT_pass1.getText()" between single and double quote, you have to add "JT_username1.getText()" as well.
String sql = "UPDATE Admin SET password='" + JT_pass1.getText() + "' WHERE username = '"+JT_username1.getText()+"'";

Is there a method to get the Total JDBC connections?

I have a jabber bot that connects to a database to gather data and report it. In case a connection goes down it is re-established and DB connection is re-initiated. Is there a method that I can call to list all the JDBC open and closed connections?
If your database is Oracle, you can query the database sessions using the v$session view. For example with this query:
column sid format 9999
column serial# format 9999999
column username format a8
column machine format a15
column osuser format a6
column program format a12
SELECT sid, serial#, username, machine, osuser, status, program, TO_CHAR(logon_time, 'MM-DD HH24:MI') logon_time
FROM v$session
WHERE username IS NOT NULL AND machine IS NOT NULL
ORDER BY logon_time;
The rows starting with column are not significant if you run the query from Java. They are formatting the result table if you test the query using Sql*Plus before incorporating it into Java.

Alter user password via jdbc. Problems with passes containing question marks

I have a problem with altering a users password when the password contains a question mark char. I do not encounter this problem with any other char so far, it seems specific to the question mark char.
If i alter a users password in sqlplus using the following sql:
Alter user Stephen identifed by "NewPassword?" REPLACE "OldPassword";
Then it changes the pass successfully and I can login using the new pass 'NewPassword?'.
However if I execute the same SQL via jdbc:
final String query = "ALTER user Stephen identified by \"NewPassword?\" REPLACE \"OldPassword\"";
stmt.executeUpdate(query);
I then cannot log in using the pass 'NewPassword?'.
Checking the hashcodes for the password when entered via sqlplus and jdbc show that they are different.
Somehow when I run the statement in jdbc it is entering something other than 'NewPassword?'.
I don't seem to have any problems with the following passwords:
NewPassword, NewPassword\, NewPassword'. It just seems to be the question mark that is causing problems.
Debugging shows the code point (dec) is 63 for the question mark so it doesn't look like its being changed midway.
Does anyone have any idea what could be causing this behaviour?
I'm at a loss at the moment, I'm considering preventing passes with question marks to bypass this problem for now.
To use JDBC to change the password of an Oracle user you need to do two things:
put the password directly in the SQL string (bind parameters cannot be used),
disable escape processing.
You can't use bind variables because the username and password are not sent to the database as single-quoted strings.
The ? in the SQL string is being taken as a bind variable placeholder, and because of this the SQL string is getting mangled at some point by Oracle JDBC. Disabling escape processing on the statement stops this from happening. Try:
Statement s = conn.createStatement();
s.setEscapeProcessing(false);
s.executeUpdate("ALTER user Stephen identified by \"newPassword?\" replace \"oldPassword\"");
If you are setting the password programmatically, your code should also ensure that the new and old passwords do not contain any " characters, to avoid SQL injection.
Try implementing it using a PreparedStatement and see if you get the same problem. Question marks are used in PreparedStatements as placeholders, so maybe the JDBC driver is getting confused. It shouldn't, but might be worth checking.
PreparedStatement p = conn.prepareStatement("ALTER user Stephen identified by ? replace ?");
p.setString(1, "NewPassword?");
p.setString(2, "OldPassword");
p.execute();
If this works then it's probably a bug in the driver.

JDBC connect string and Oracle synonyms

we have a Java program connecting via JDBC thin client to an Oracle 10g database.
Everything was working fine, but now the DBA wants us to connect with a different username/password, which is supposed to have access to the same tables using public synonyms.
Unfortunately the Java program no longer sees the tables (see error below when I try to do "select * from tablename").
I have tried to connect using the same username/password with Oracle SQL Developer and in this case I can run "select * from tablename" without problems.
Is there a specific Parameter I need to put in the connect string?
Many thanks!
Exception in thread "main" java.sql.SQLException: ORA-00942: table or view does not exist
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:207)
at oracle.jdbc.driver.T4CStatement.executeForDescribe(T4CStatement.java:790)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1037)
at oracle.jdbc.driver.T4CStatement.executeMaybeDescribe(T4CStatement.java:830)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1132)
at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:1687)
at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:1653)
Edited by: user555817 on 08-Oct-2010 04:55
You have to append Schema Name along with the table name and make it in capital letters (I dont remember if that is case-sensitive or just caps).
Example:
If there is an Employee Table in SCH1 and the synonym is created in SCH2 as Emp for SCH2.Employee, then the below statement is valid,
SELECT * FROM SCH2.emp
Where,
emp: Synonym Name
SCH2: Schema Name where this synonym is created, not the Schema Name of the actual table.

Categories