1 /*  Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3     This program is free software; you can redistribute it and/or
4     modify it under the terms of the GNU General Public License as
5     published by the Free Software Foundation; version 2 of the
6     License.
7 
8     This program is distributed in the hope that it will be useful,
9     but WITHOUT ANY WARRANTY; without even the implied warranty of
10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11     GNU General Public License for more details.
12 
13     You should have received a copy of the GNU General Public License
14     along with this program; if not, write to the Free Software
15     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16 
17 /**
18   @file
19 
20   auth_socket authentication plugin.
21 
22   Authentication is successful if the connection is done via a unix socket and
23   the owner of the client process matches the user name that was used when
24   connecting to mysqld.
25 */
26 #define _GNU_SOURCE /* for struct ucred */
27 
28 #include <mysql/plugin_auth.h>
29 #include <sys/socket.h>
30 #include <pwd.h>
31 #include <string.h>
32 
socket_auth(MYSQL_PLUGIN_VIO * vio,MYSQL_SERVER_AUTH_INFO * info)33 static int socket_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
34 {
35   unsigned char *pkt;
36   MYSQL_PLUGIN_VIO_INFO vio_info;
37   struct ucred cred;
38   socklen_t cred_len= sizeof(cred);
39   struct passwd pwd_buf, *pwd;
40   char buf[1024];
41 
42   /* no user name yet ? read the client handshake packet with the user name */
43   if (info->user_name == 0)
44   {
45     if (vio->read_packet(vio, &pkt) < 0)
46       return CR_ERROR;
47   }
48 
49   info->password_used= PASSWORD_USED_NO_MENTION;
50 
51   vio->info(vio, &vio_info);
52   if (vio_info.protocol != MYSQL_VIO_SOCKET)
53     return CR_ERROR;
54 
55   /* get the UID of the client process */
56   if (getsockopt(vio_info.socket, SOL_SOCKET, SO_PEERCRED, &cred, &cred_len))
57     return CR_ERROR;
58 
59   if (cred_len != sizeof(cred))
60     return CR_ERROR;
61 
62   /* and find the username for this uid */
63   getpwuid_r(cred.uid, &pwd_buf, buf, sizeof(buf), &pwd);
64   if (pwd == NULL)
65     return CR_ERROR;
66 
67   /* now it's simple as that */
68   return strcmp(pwd->pw_name, info->user_name) ? CR_ERROR : CR_OK;
69 }
70 
71 static struct st_mysql_auth socket_auth_handler=
72 {
73   MYSQL_AUTHENTICATION_INTERFACE_VERSION,
74   0,
75   socket_auth
76 };
77 
mysql_declare_plugin(socket_auth)78 mysql_declare_plugin(socket_auth)
79 {
80   MYSQL_AUTHENTICATION_PLUGIN,
81   &socket_auth_handler,
82   "auth_socket",
83   "Sergei Golubchik",
84   "Unix Socket based authentication",
85   PLUGIN_LICENSE_GPL,
86   NULL,
87   NULL,
88   0x0100,
89   NULL,
90   NULL,
91   NULL,
92   0,
93 }
94 mysql_declare_plugin_end;
95 
96