Create alias with all users from mysql table in postfix/dovecot - mysql

I have a table with users for my mail server. This table for imap authenfication in dovecot
+-------------+------------------+-------------------+------------------+------+------+---------------------------------------+--------+---------+---------------------------+
| user_name | domain_name | passwd | pwd_hash | uid | gid | mailbox_basepath | enable | quota | desc_rec |
+-------------+------------------+-------------------+------------------+------+------+---------------------------------------+--------+---------+---------------------------+
| logistic | piduna.pp.ua | loG-1990M | _no_hash_passwd_ | 2000 | 2000 | /home/maildir/piduna.pp.ua/ | 1 | 2048000 | box for logistic |
| 1c | piduna.pp.ua | 1c_user_1c | _no_hash_passwd_ | 2000 | 2000 | /home/maildir/piduna.pp.ua | 1 | 2048000 | Denisyuk V.V. |
| admin | piduna.pp.ua | AAddMmM1N | _no_hash_passwd_ | 2000 | 2000 | /home/maildir/piduna.pp.ua | 1 | 2048000 | Admin |
| al.service | piduna.pp.ua | Alumo_Serv4321 | _no_hash_passwd_ | 2000 | 2000 | /home/maildir/piduna.pp.ua | 1 | 2048000 | Alumo Service |
I need create aliases. For example, on it#vpiduna.pp.ua, i need to send email on admin#vpiduna.pp.ua and al.service#vpiduna.pp.ua.
I do it. This table:
+------------------------+-------------------------------------------------+
| source | destination |
+------------------------+-------------------------------------------------+
| it#piduna.pp.ua | admin#piduna.pp.ua, al.service#piduna.pp.ua |
+------------------------+-------------------------------------------------+
In main.cf, i added this option:
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual_aliases.cf
In mysql-virtual_aliases.cf:
user = root
password = myPassword
dbname = mail_db
query = SELECT destination FROM virtual_aliases WHERE source='%s'
hosts = 127.0.0.1
And this working. But, in my organization, i have alias for all users. It name is all#piduna.pp.ua. And, when i created new user, i need add it in alias all#piduna.pp.ua. How to create alias, that take all user accounts from my first table automatically?

Related

Check for multiple duplicates in MySQL database

I've currently got 3 different queries to check for multiple users in database, I was wondering if there is a way to combine then all in a single query.
Based on email:
SELECT
user_email,
COUNT(user_email)
FROM
users
GROUP BY user_email
HAVING COUNT(user_email) > 1;
Based on last name:
SELECT
user_lastname,
COUNT(user_lastname)
FROM
users
GROUP BY user_lastname
HAVING COUNT(user_lastname) > 1;
Based on phone:
SELECT
user_phone,
COUNT(user_phone)
FROM
users
GROUP BY user_phone
HAVING COUNT(user_phone) > 1;
For each query I am showing a list of email|last name|phone number and the number of multiple users there are.
My final plan is to make a list with just the duplicate users containing just the information they got caught on (for example user X / Y duplicate based on U email etc).
User_ID | user_email | user_firstname | user_lastname | user_phone
1 | snow#asd.com | John | Snow | 123456
2 | user#asd.com | George | Smith | 546632
3 | usr#asd.com | Maria | Coal | 553211
4 | snow#asd.com | Jack | Black | 752210
5 | bin#asd.com | Tom | Bing | 856332
6 | col#asd.com | Storm | Snow | 325412
7 | ding#asd.com | Mairy | Call | 123456
8 | user23#asd.com | Kim | Loren | 351200
9 | user44#asd.com | Dot | Honey | 546632
10 | user11#asd.com | Jack | Smithson | 455871
The end result must show users 1+4 (same email) +7 (same phone number with 1) +6 (same last name with 1) + 2+9 (same phone number)
User_ID | user_email | user_firstname | user_lastname | user_phone
1 | snow#asd.com | John | Snow | 123456
4 | snow#asd.com | Jack | Black | 752210
6 | col#asd.com | Storm | Snow | 325412
7 | ding#asd.com | Mairy | Call | 123456
2 | user#asd.com | George | Smith | 546632
9 | user44#asd.com | Dot | Honey | 546632
For this case I think that EXISTS is the best solution:
select u.* from users u
where exists (
select 1 from users
where user_id <> u.user_id
and (user_lastname = u.user_lastname or user_email = u.user_email or user_phone = u.user_phone)
)
See the demo.
Results:
| User_ID | user_email | user_firstname | user_lastname | user_phone |
| ------- | -------------- | -------------- | ------------- | ---------- |
| 1 | snow#asd.com | John | Snow | 123456 |
| 2 | user#asd.com | George | Smith | 546632 |
| 4 | snow#asd.com | Jack | Black | 752210 |
| 6 | col#asd.com | Storm | Snow | 325412 |
| 7 | ding#asd.com | Mairy | Call | 123456 |
| 9 | user44#asd.com | Dot | Honey | 546632 |

SQL join: selecting last records from duplicates

I am working on python project "Linux Server Monitor". When you load monitoring website you create your servers and table look like this:
Servers:
+-----------+-----------+---------+-------------+
| server_id | auth_code | user_id | server_name |
+-----------+-----------+---------+-------------+
| 0 | xyz123 | 1 | My Server 1 |
| 1 | aabb | 45 | BlaBlaUser |
| 2 | asdfh1 | 1 | My Server 5 |
+-----------+-----------+---------+-------------+
After the server is created, you start python script and it starts to upload monitoring data to this table (where all data is stored, from all users):
Monitoring Data:
+----+-----------+---------+---------+------------+-----------------+------------------+
| id | auth_code | user_id | os_name | os_version | external_ip | some_other_table |
+----+-----------+---------+---------+------------+-----------------+------------------+
| 0 | aabb | 45 | Ubuntu | 16.04 | 77.88.99.100 | dynamic data |
| 1 | aabb | 45 | Ubuntu | 16.04 | 77.88.99.100 | dynamic data 2 |
| 2 | aabb | 45 | Ubuntu | 16.04 | 10.10.10.10 | dynamic data 3 |
| 3 | xyz123 | 1 | Fedora | 27 | 92.94.95.99 | different data 1 |
| 4 | xyz123 | 1 | Fedora | 27 | 92.94.95.99 | different data 2 |
| 5 | xyz123 | 1 | Fedora | 27 | 92.94.95.99 | different data 3 |***
| 6 | asdfh1 | 1 | CentOS | 7 | 5.5.5.5 | some new data 1 |
| 7 | asdfh1 | 1 | CentOS | 7 | 5.5.5.5 | some new data 2 |
| 8 | asdfh1 | 1 | CentOS | 7 | 2.2.2.2 | some new data 3 |###
+----+-----------+---------+---------+------------+-----------------+------------------+
I want to join first and second table to show user "important" information like this:
Your Active Servers:
+-----------+-------------+---------+------------+-----------------+
| server_id | server_name | os_name | os_version | external_ip |
+-----------+-------------+---------+------------+-----------------+
| 0 | My Server 1 | Fedora | 27 | 92.94.95.99 |***
| 2 | My Server 5 | CentOS | 7 | 2.2.2.2 |###
+-----------+-------------+---------+------------+-----------------+
If I join first and second table by user_id it will load duplicates too but I want only last inserted record of that particular user's server. In this case on last record "external_ip" of one server changed but other one remained the same (marked with *** and ###).
you could use an inner join on subselect for the max id for user, server on monitorig
select s.server_id, s.server_name, m.os_name, m.os_version, m.external_ip
from servers s
inner join Monitoring m on m.user_id = s.user_id and s.auth_code = m.auth_code
inner join (
select max(id) max_id, user_id, os_name, os_version
from Monitoring
group by user_id, os_name, os_version
) t on t.max_id = m.id
where user_id = 1

Query date from same column with several conditions

I want to do a query to see when a client is disconnected, between January and February, by a cable company and if they got connect again until 7 days after the disconnection.
My table would be something like this:
+---------+----------+------------+------------+
| client | ID_Order | Work_Order | Date_Order |
+---------+----------+------------+------------+
| Client1 | 123AB | Disconnect | 20/01/2017 |
| Client1 | 234EA | Connect | 22/01/2017 |
| Client2 | 242FA | Connect | 30/01/2017 |
| Client3 | 244FE | Disconnect | 30/01/2017 |
| Client2 | 301EA | Disconnect | 10/02/2017 |
| Client4 | 355AD | Disconnect | 20/02/2017 |
| Client4 | 368AD | Connect | 25/02/2017 |
| Client5 | 401AD | Connect | 05/03/2017 |
| Client6 | 440AD | Disconnect | 15/03/2017 |
+---------+----------+------------+------------+
And I want to transform the previous table in a table like this: one row per client, with the connect order and disconnect order in 2 different columns
+---------+-----------------+-------------+--------------+------------+
| client | ID_Order_Discon | Date_Discon | ID_Order_Con | Date_Con |
+---------+-----------------+-------------+--------------+------------+
| Client1 | 123AB | 20/01/2017 | 234EA | 22/01/2017 |
| Client4 | 355AD | 20/02/2017 | 368AD | 25/02/2017 |
+---------+-----------------+-------------+--------------+------------+
My problem:
1- How make the query inside the same columns (Date_Order), to choose the clients that where connected after 7 days the disconnection. Guess need to use DATEDIFF()?
2- how to put the orders of the same client in 2 different columns? Guess I have to do an IF()/CASE () and a join ()?
To Combine both table you can use:
select c1.client, cq.ID_Order ID_Order_Discon , c1.Date_Order as Date_discon, c2.ID_Order ID_Order_Con, c2.Date_order Date_Con
from table c1 join table c2 on t1.client = t2.client and t1.work-order = 'disconnect' and t2.work_order = 'Connect'
and for the frst question you can use where DATEDIFF(c1.date_order,c2.dateOrder)>7

create VIEW in mysql from two tables

I have a table with users for my mail server. This table for imap authenication in dovecot:
+-------------+------------------+-------------------+------------------+------+------+---------------------------------------+--------+---------+---------------------------+
| user_name | domain_name | passwd | pwd_hash | uid | gid | mailbox_basepath | enable | quota | desc_rec |
+-------------+------------------+-------------------+------------------+------+------+---------------------------------------+--------+---------+---------------------------+
| logistic | piduna.pp.ua | loG-1990M | _no_hash_passwd_ | 2000 | 2000 | /home/maildir/piduna.pp.ua/ | 1 | 2048000 | box for logistic |
| 1c | piduna.pp.ua | 1c_user_1c | _no_hash_passwd_ | 2000 | 2000 | /home/maildir/piduna.pp.ua | 1 | 2048000 | Denisyuk V.V. |
| admin | piduna.pp.ua | AAddMmM1N | _no_hash_passwd_ | 2000 | 2000 | /home/maildir/piduna.pp.ua | 1 | 2048000 | Admin |
| al.service | piduna.pp.ua | Alumo_Serv4321 | _no_hash_passwd_ | 2000 | 2000 | /home/maildir/piduna.pp.ua | 1 | 2048000 | Alumo Service |
I need to create table with two columns. First column, all#piduna.pp.ua. Second column it is all my email accounts. In one table, I know how make concatenation from user_name and domain_name. Look:
CREATE VIEW `forwardings_all_view` AS select lcase(concat(`users`.`user_name`,'#',`users`.`domain_name`)) AS `email_fqn` from `users` where (`users`.`enable` = 1)
But, how to add in it VIEW, second column: all#piduna.pp.ua.
Like that:
+------------------------------+-------------------------------------------------+
| email_fqn | source |
+------------------------------+-------------------------------------------------+
| .logistic#piduna.pp.ua | all#piduna.pp.ua |
| 1c#piduna.pp.ua | |
| admin#piduna.pp.ua | |
| al.service#piduna.pp.ua | |
Try this:
create view first_user as
select user_name from users where enable limit 1;
create view forwardings_all_view as
select lcase(concat(a.`user_name`,'#',a.`domain_name`)) AS `email_fqn`,
if(b.user_name is null, '', 'all#piduna.pp.ua') `source`
from `users` a
left join first_user b on a.user_name = b.user_name
where a.`enable` = 1;
fiddle

Fixing Joined Many-to-Many MySQL Query

I have two tables that look like this:
Table A:
+-----+-----+------+-------+
| aID | uID | attr | value |
+-----+-----+------+-------+
| 1 | 1 | fn | john |
+-----+-----+------+-------+
| 2 | 1 | ln | smith |
+-----+-----+------+-------+
| 3 | 2 | fn | jim |
+-----+-----+------+-------+
| 4 | 2 | ln | bean |
+-----+-----+------+-------+
Table B:
+-----+-----+-------+-------+
| bID | uID | perm | value |
+-----+-----+-------+-------+
| 1 | 1 | admin | 1 |
+-----+-----+-------+-------+
| 2 | 2 | news | 1 |
+-----+-----+-------+-------+
| 3 | 2 | cms | 1 |
+-----+-----+-------+-------+
As it shows, Table A holds attribute data for a user uID, and Table B holds permission data for a user uID.
At the moment, I am using,:
SELECT GROUP_CONCAT(`a`.`attr`) AS `attrs`
, GROUP_CONCAT(`a`.`value`) AS `values`
, GROUP_CONCAT(`b`.`perm`) AS `perms`
FROM `a`
JOIN `b`
ON `a`.`uID` = `b`.`uID`
GROUP BY `a`.`uID`, `b`.`uID`
But it is giving me a result:
+-------------+-------------------+-------------------+
| attrs | values | perms |
+-------------+-------------------+-------------------+
| fn,ln | John,Smith | admin,admin |
+-------------+-------------------+-------------------+
| fn,fn,ln,ln | Jim,Jim,Bean,Bean | news,cms,news,cms |
+-------------+-------------------+-------------------+
What do I need to change in my query to get:
+-------+------------+----------+
| attrs | values | perms |
+-------+------------+----------+
| fn,ln | John,Smith | admin |
+-------+------------+----------+
| fn,fn | Jim,Bean | news,cms |
+-------+------------+----------+
GROUP_CONCAT takes additional arguments, as explained on its documentation page here.
The one you want is distinct:
SELECT GROUP_CONCAT(distinct `a`.`attr`) AS `attrs` . . .