postfix not substituting %s - mysql

Postfix 3.1.4 on Debian Stretch appears to be failing to substitute the address it's attempting to resolve with mysql_table.
I have /etc/postfix/sasl/smtpd.conf configured (below), but it never authenticates. When I check the MySQL log table, I see:
| 2017-08-28 23:19:54 | postfix[postfix] # localhost [127.0.0.1] | 834 | 0 | Query | START TRANSACTION |
| 2017-08-28 23:19:54 | postfix[postfix] # localhost [127.0.0.1] | 834 | 0 | Query | SELECT password FROM mailbox WHERE username = '%s' |
| 2017-08-28 23:19:54 | postfix[postfix] # localhost [127.0.0.1] | 834 | 0 | Query | SELECT password FROM mailbox WHERE username = '%s' |
| 2017-08-28 23:19:54 | postfix[postfix] # localhost [127.0.0.1] | 834 | 0 | Query | COMMIT
When %s is a postfix template, not a MySQL / MariaDB one. It should be filling in the email address, or the user here, but it appears to just be copying this from the configs verbatim.
Here is the content of /etc/postfix/sasl/smtpd.conf:
autheck_method: saslauthd
mech_list: plain login
allow_plaintext: true
auxprop_plugin: sql
sql_hostnames: 127.0.0.1
sql_user: [redacted]
sql_passwd: [redacted]
sql_database: [redacted]
sql_select: SELECT password FROM mailbox WHERE username = '%s'
log_level:10

Seems this works: select password from users where email = '%u#%r', but %s does not.

Related

find_in_set and find_in_set unexpected result

USE mysql;
DROP PROCEDURE IF EXISTS ShowUsers;
DELIMITER $
CREATE PROCEDURE `ShowUsers`(IN KnownUsers varchar(500), IN KnownHosts varchar(500))
BEGIN
SELECT
user,host
FROM
user
WHERE
NOT FIND_IN_SET(host, KnownHosts)
AND
NOT FIND_IN_SET(user, KnownUsers)
ORDER BY user, host ASC;
END $
DELIMITER ;
Example complete data to work with:
+-------------+-------------+
| user | host |
+-------------+-------------+
| knownuser1 | 192.168.1.5 |
| knownuser2 | 192.168.1.5 |
| unknownuser | 192.168.1.5 | # I want this result to show
| someuser1 | 192.168.1.6 |
| someuser2 | 192.168.1.6 |
| someuser3 | 192.168.1.6 |
| root | localhost |
+-------------+-------------+
I have marked the result I would want to show from running the procedure, basically the two IN parameters are known users, and known hosts those that should be have a user record on this database.
Calling the function like this
# users and hostnames(ips) to match for exclusion from results.
SET #Usernames = 'knownuser1,knownuser2';
SET #Hostnames = '192.168.1.5';
CALL ShowUsers(#Usernames, #Hostnames);
Expected Result:
+-------------+-------------+
| user | host |
+-------------+-------------+
| unknownuser | 192.168.1.5 | # I want this result to show
| someuser1 | 192.168.1.6 |
| someuser2 | 192.168.1.6 |
| someuser3 | 192.168.1.6 |
| root | localhost |
+-------------+-------------+
Actual Result:
+-------------+-------------+
| user | host |
+-------------+-------------+
| someuser1 | 192.168.1.6 |
| someuser2 | 192.168.1.6 |
| someuser3 | 192.168.1.6 |
| root | localhost |
+-------------+-------------+
Explanation (off this topic but I think I should clarify) The reason I want this procedure to work, I have a master server with multiple remote slaves, the slaves need to have access to the masters database which means they also have to have "root" access, they can create/reconfigure their own access credentials. The problem with this is if one of those servers were ever compromised it would leave open the chance to have a new user added with credentials to basically all of the database. Wide open and free to take.
I could lock the slaves out after initial configuration and manually open up the door, run an update and then lock it again which would be pretty laborious for the application and make the application virtually useless.
The idea I'm going with right now is to run this procedure via cron run script and check for unknown users/hosts and lock that slave server out of the database until I accept or reject the user from the main application.
The condition in the WHERE clause is:
NOT FIND_IN_SET(host, KnownHosts) AND NOT FIND_IN_SET(user, KnownUsers)
which is equivalent to:
NOT (FIND_IN_SET(host, KnownHosts) OR FIND_IN_SET(user, KnownUsers))
which means that you want to exclude the rows for which:
host is included in KnownHosts or user is included in KnownUsers.
So for your sample data, the row:
unknownuser | 192.168.1.5
will not be returned, because host = '192.168.1.5' and it is included in KnownHosts (= '192.168.1.5').
Maybe change the logical operator to OR, if this is the logic that you want to apply:
NOT FIND_IN_SET(host, KnownHosts) OR NOT FIND_IN_SET(user, KnownUsers)

MaxScale blocks direct connect to database

I have a 2 nodes mariadb cluster with one maxscale load balancer.
maxscale blocks connection if i want to connect directly to a database: so for example:
mysql -h 35.300.208.100 -u finn -p works and if i then do a USE test i can do everything with the database "test". so the rights are correct.
but if a do a mysql -h 35.300.208.100 -u finn -p test i get the error:
ERROR 1045 (28000): Access denied for user 'finn'#'188.68.43.150' (using password: YES) to database 'test'
So if i do the same on the nodes with localhost, everything works fine.
This is my maxscale.cnf
Most of the time you will receive ERROR 1045 (28000): Access denied when the grants on the database do not contain matching grants for both the client IP and the MaxScale IP.
The usual way of solving this is to:
Execute SHOW GRANTS on the database from the client server
Execute SHOW GRANTS on the database from the MaxScale server
Compare the output of the two queries and make sure they are identical
This is usually enough to spot any problems with grants in the database.
Another way to resolve these sorts of errors is to execute the query that MaxScale uses to load the database users. The exact SQL for these queries can be found on the MaxScale wiki on GitHub. For MaxScale 2.1 and newer, this would be:
SELECT u.user, u.host, d.db, u.select_priv, u.password
FROM mysql.user AS u LEFT JOIN mysql.db AS d
ON (u.user = d.user AND u.host = d.host)
UNION
SELECT u.user, u.host, t.db, u.select_priv, u.password
FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t
ON (u.user = t.user AND u.host = t.host);
This should return a result set containing the authentication data that MaxScale uses. Here's an example of what the query can return:
+---------------+-----------+------+-------------+-------------------------------------------+
| user | host | db | select_priv | password |
+---------------+-----------+------+-------------+-------------------------------------------+
| root | localhost | NULL | Y | |
| maxuser | 127.0.0.1 | NULL | Y | *5EDBD32E469DAE0CE10E6999C3899DEFCB9F12E0 |
| root | % | NULL | Y | |
| maxuser | % | NULL | Y | *5EDBD32E469DAE0CE10E6999C3899DEFCB9F12E0 |
| skysql | 127.0.0.1 | NULL | Y | *85058F5DEAD82AE3507664C2C11BDA7B1827B80D |
| skysql | % | NULL | Y | *85058F5DEAD82AE3507664C2C11BDA7B1827B80D |
| test | % | NULL | Y | *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 |
| stackoverflow | % | test | N | *5635C63172887A7D7C0828876228A5E4DC523969 |
| stackoverflow | % | NULL | N | *5635C63172887A7D7C0828876228A5E4DC523969 |
+---------------+-----------+------+-------------+-------------------------------------------+
The select_priv tells whether the user is allowed to connect with any default database. If it is set to N, then the value in the db column is the only database that the client is allowed to use. As we can see from the example result, the 'stackoverflow'#'%' user is either allowed to connect without a default database or with the test default database.

Unable to INSERT into an Amazon RDS database

I setup my website on AWS.
Now, the problem is: I am able to select data from my DB but I am not able to insert it. But, my root is having "Insert" privileges.
I did create another user and provided the same privileges but the same problem persists.
Here is my configuration:
mysql - "select" and "insert" privileges for "root" user.
+-------------+-------------+
| Select_priv | Insert_priv |
| Y | Y |
+-------------+-------------+
mysql - "host" and "user" details
+----------------+------+
| host | user |
| % | root |
| 127.0.0.1 | root |
| (my ip) | root |
| ::1 | root |
| ip-(my ip) | |
| ip-(my ip) | root |
| localhost | |
| localhost | root |
+----------------+------+
php - I am connecting using "username" as "root", "host" as "localhost" and "port" as 3306
Inbound security group
Outbound security group
Table names in insert query are case sensitive when deployed in aws RDS mysql. So, make sure to have same table names i.e. same case in insert query and in database. I hope this will work.

mysql - show processlist

When I run the command show processlist; I get details of the connections made to the server. Here are the connection details of my MySQL server,
mysql> show processlist;
+------+-----------------+----------------------+-------------+---------+----------+------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+------+-----------------+----------------------+-------------+---------+----------+------------------------+------------------+
| 1 | event_scheduler | localhost | NULL | Daemon | 13200075 | Waiting on empty queue | NULL |
| 4212 | root | localhost | NULL | Query | 0 | init | show processlist |
| 4214 | root | xxx.xx.xxx.xxx:50197 | testmysqldb | Sleep | 1 | | NULL |
| 4215 | root | xxx.xx.xxx.xxx:50198 | testmysqldb | Sleep | 3 | | NULL |
+------+-----------------+----------------------+-------------+---------+----------+------------------------+------------------+
What does the "number" after the term hostname and a colon (:) mean? It generally appears when a remote connection is made, on Linux and appears even for local connection on Windows.
Thanks in Advance!!
It's the client's port number used for the connection.
"xxx.xx.xxx.xxx:50197" means that there's an open connection from IP address "xxx.xx.xxx.xxx" and port 50197, towards your MySQL server (probably on port 3306.)
This is the client's TCP Port.
You connect to the server for example on default port 3306 but the client uses a different port on its side of the connection. This port is listed there.
It's client port number i.e. a connection gets open between two processes (on the same host or physically apart) using sockets - Socket is host_ip:port_num
So when we connect to a mysql (on same machine - localhost or remote server) a connection is opened i.e.
client_ip:xxxxx --> mysql_ip:3306 (3306 is default for Mysql, can use other port as well)
Example:
xxx.xx.xxx.xxx:50197
We send query and receive response from the mysql (mysql_ip:3306) at client_ip:50197

mysql duplicate root users on mac pro

I just set up mysql my Yosemite by following the directions here:
http://coolestguidesontheplanet.com/get-apache-mysql-php-phpmyadmin-working-osx-10-10-yosemite/
I tried to set the password for root with the mysqladmin command. The result is that now I can log in mysql with the new password or no password. I think it's because one root user (root#localhost) has no password and the other root user has the new passwor.
Should I drop any root users here? I don't understand why 2 root users exist for both localhost and macbook-pro.local.
+------+-------------------+
| User | Host |
+------+-------------------+
| root | 127.0.0.1 |
| root | ::1 |
| | localhost |
| root | localhost |
| | macbook-pro.local |
| root | macbook-pro.local |
+------+-------------------+
So I got another representation by add the password field:
mysql> select User,Host,password from mysql.user;
+------+-------------------+-------------------------------------------+
| User | Host | password |
+------+-------------------+-------------------------------------------+
| root | localhost | *xxx |
| root | macbook-pro.local | |
| root | 127.0.0.1 | |
| root | ::1 | |
| | localhost | |
| | macbook-pro.local | |
+------+-------------------+-------------------------------------------+
So this made me understand that there are users with empty strings and I guess there's no duplicate after all. But then how do I NOT let users log in with just:
mysql -u root
Set password for all root user:
SET PASSWORD FOR 'root'#'localhost' = PASSWORD('cleartext password');
SET PASSWORD FOR 'root'#'macbook-pro.local' = PASSWORD('cleartext password');
SET PASSWORD FOR 'root'#'127.0.0.1' = PASSWORD('cleartext password');
SET PASSWORD FOR 'root'#'::1' = PASSWORD('cleartext password');
And if you don't want any user can log into your mysql without username and password, drop any user from the list:
DROP USER ''#'localhost';
DROP USER ''#'macbook-pro.local';
Note that '' (blank) user is any user. If you don't set a password for them, any user(human, machine) can log into your mysql with any (means anything,any word,any phrase) as username without a password.
But, your 2 blank users here is used by mysql (itself) during installation of mysql service, and it doesn't have granted access. If you have installed mysql service, you can safely drop them.
see reference1
see reference2