1 /* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
2 Copyright (c) 2010, 2011, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; version 2 of the
7 License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
17
18 /**
19 @file
20
21 auth_socket authentication plugin.
22
23 Authentication is successful if the connection is done via a unix socket and
24 the owner of the client process matches the user name that was used when
25 connecting to mysqld.
26 */
27 #define _GNU_SOURCE 1 /* for struct ucred */
28
29 #include <mysql/plugin_auth.h>
30 #include <string.h>
31 #include <pwd.h>
32 #include <sys/socket.h>
33 #include <sys/types.h>
34
35 #ifdef HAVE_PEERCRED
36 #define level SOL_SOCKET
37
38 #elif defined HAVE_SOCKPEERCRED
39 #define level SOL_SOCKET
40 #define ucred sockpeercred
41
42 #elif defined HAVE_XUCRED
43 #include <sys/un.h>
44 #include <sys/ucred.h>
45 #define level 0
46 #define SO_PEERCRED LOCAL_PEERCRED
47 #define uid cr_uid
48 #define ucred xucred
49
50 #else
51 #error impossible
52 #endif
53
54 /**
55 perform the unix socket based authentication
56
57 This authentication callback performs a unix socket based authentication -
58 it gets the uid of the client process and considers the user authenticated
59 if it uses username of this uid. That is - if the user is already
60 authenticated to the OS (if she is logged in) - she can use MySQL as herself
61 */
62
socket_auth(MYSQL_PLUGIN_VIO * vio,MYSQL_SERVER_AUTH_INFO * info)63 static int socket_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
64 {
65 unsigned char *pkt;
66 MYSQL_PLUGIN_VIO_INFO vio_info;
67 struct ucred cred;
68 socklen_t cred_len= sizeof(cred);
69 struct passwd pwd_buf, *pwd;
70 char buf[1024];
71
72 /* no user name yet ? read the client handshake packet with the user name */
73 if (info->user_name == 0)
74 {
75 if (vio->read_packet(vio, &pkt) < 0)
76 return CR_ERROR;
77 }
78
79 info->password_used= PASSWORD_USED_NO_MENTION;
80
81 vio->info(vio, &vio_info);
82 if (vio_info.protocol != MYSQL_VIO_SOCKET)
83 return CR_ERROR;
84
85 /* get the UID of the client process */
86 if (getsockopt(vio_info.socket, level, SO_PEERCRED, &cred, &cred_len))
87 return CR_ERROR;
88
89 if (cred_len != sizeof(cred))
90 return CR_ERROR;
91
92 /* and find the username for this uid */
93 getpwuid_r(cred.uid, &pwd_buf, buf, sizeof(buf), &pwd);
94 if (pwd == NULL)
95 return CR_ERROR;
96
97 /* now it's simple as that */
98 return strcmp(pwd->pw_name, info->user_name) ? CR_ERROR : CR_OK;
99 }
100
101 static struct st_mysql_auth socket_auth_handler=
102 {
103 MYSQL_AUTHENTICATION_INTERFACE_VERSION,
104 0,
105 socket_auth
106 };
107
maria_declare_plugin(auth_socket)108 maria_declare_plugin(auth_socket)
109 {
110 MYSQL_AUTHENTICATION_PLUGIN,
111 &socket_auth_handler,
112 "unix_socket",
113 "Sergei Golubchik",
114 "Unix Socket based authentication",
115 PLUGIN_LICENSE_GPL,
116 NULL,
117 NULL,
118 0x0100,
119 NULL,
120 NULL,
121 "1.0",
122 MariaDB_PLUGIN_MATURITY_STABLE
123 }
124 maria_declare_plugin_end;
125
126