PAM authentication plugin for MySQL, Percona Server and MariaDB

Merge lp:~maria-captains/percona-pam-for-mysql/use_dialog into lp:percona-pam-for-mysql

Proposed by Sergei on 2011-10-27
Status: Rejected
Rejected by: Laurynas Biveinis on 2011-12-09
Proposed branch: lp:~maria-captains/percona-pam-for-mysql/use_dialog
Merge into: lp:percona-pam-for-mysql
Diff against target: 880 lines (+135/-546) 9 files modified
To merge this branch: bzr merge lp:~maria-captains/percona-pam-for-mysql/use_dialog
Reviewer Review Type Date Requested Status
Laurynas Biveinis 2011-10-27 Disapprove on 2011-12-09
Review via email: mp+80551@code.launchpad.net
To post a comment you must log in.

Changes of this MP have been split into other MPs, some already merged, some in progress.

review: Disapprove

Unmerged revisions

8. By Sergei on 2011-10-27

rewrite to use dialog plugin.
simplify configure.ac.
support builds from within 5.5 tree.
fix make distcheck target.

Preview Diff

1=== modified file '.bzrignore'
2--- .bzrignore 2011-10-21 21:37:36 +0000
3+++ .bzrignore 2011-10-27 11:22:23 +0000
4@@ -15,3 +15,4 @@
5 .libs
6 build/percona-pam-plugin.spec
7 build/build-binary.sh
8+*.tar.gz
9
10=== modified file 'Makefile.am'
11--- Makefile.am 2011-10-20 19:07:25 +0000
12+++ Makefile.am 2011-10-27 11:22:23 +0000
13@@ -15,3 +15,6 @@
14 #
15
16 SUBDIRS = src
17+
18+EXTRA_DIST = bootstrap build/CMakeLists.txt
19+
20
21=== modified file 'bootstrap' (properties changed: -x to +x)
22=== added file 'build/CMakeLists.txt'
23--- build/CMakeLists.txt 1970-01-01 00:00:00 +0000
24+++ build/CMakeLists.txt 2011-10-27 11:22:23 +0000
25@@ -0,0 +1,5 @@
26+INCLUDE (CheckLibraryExists)
27+CHECK_LIBRARY_EXISTS(pam pam_authenticate "" HAVE_PAM)
28+IF(HAVE_PAM)
29+ MYSQL_ADD_PLUGIN(auth_pam auth_pam.c LINK_LIBRARIES pam)
30+ENDIF(HAVE_PAM)
31
32=== modified file 'configure.ac'
33--- configure.ac 2011-10-21 21:37:36 +0000
34+++ configure.ac 2011-10-27 11:22:23 +0000
35@@ -17,32 +17,24 @@
36 #
37 #
38 AC_PREREQ([2.61])
39-AC_INIT([Percona PAM plugin], [0.1], [mysql-dev@percona.com])
40-AC_CONFIG_SRCDIR([src/lib_auth_pam_client.h])
41+AC_INIT([Percona PAM plugin], [1.0], [mysql-dev@percona.com])
42+AC_CONFIG_SRCDIR([src/auth_pam.c])
43 AM_INIT_AUTOMAKE
44
45 # Checks for programs.
46-AC_PROG_CXX
47-AC_PROG_AWK
48-AC_PROG_CC
49-AC_PROG_CPP
50-AC_PROG_INSTALL
51-AC_PROG_LN_S
52-AC_PROG_MAKE_SET
53-AC_PROG_RANLIB
54 AC_PROG_LIBTOOL
55
56 AC_CHECK_PROGS([BZR], [bzr])
57
58 # mysql_config
59+AC_PATH_PROG([MYSQL_CONFIG], [mysql_config])
60 AC_ARG_WITH([mysql_config],
61 AC_HELP_STRING(
62- [--with-mysql_config=PROGRAM],
63+ [--with-mysql_config=PATH],
64 [location of the mysql_config program]),
65- [mysql_config_prog="$withval"])
66-AC_PATH_PROG([MYSQL_CONFIG], [mysql_config], [$mysql_config_prog])
67+ [MYSQL_CONFIG="$withval"])
68
69-if test "x$MYSQL_CONFIG" = "x"
70+if test "x$MYSQL_CONFIG" = "x" -o ! -x "$MYSQL_CONFIG"
71 then
72 AC_MSG_ERROR([Unable to find mysql_config. Please install or specify.])
73 fi
74@@ -54,47 +46,31 @@
75 )
76
77 # Checks for header files.
78-MYSQL_INCLUDES="$(mysql_config --include)"
79+MYSQL_INCLUDES=`"$MYSQL_CONFIG" --include`
80
81-save_CFLAGS="${CFLAGS}"
82 save_CPPFLAGS="${CPPFLAGS}"
83
84-CFLAGS="${CFLAGS} ${MYSQL_INCLUDES}"
85 CPPFLAGS="${CPPFLAGS} ${MYSQL_INCLUDES}"
86
87-AC_CHECK_HEADERS([string.h unistd.h])
88 AC_CHECK_HEADER([mysql/plugin.h], [],
89 AC_MSG_ERROR(
90 [Unable to find mysql/plugin.h. Please install the mysql
91 development headers]))
92
93-CFLAGS="${save_CFLAGS}"
94 CPPFLAGS="${save_CPPFLAGS}"
95
96 AC_SUBST([MYSQL_INCLUDES])
97
98-# Checks for typedefs, structures, and compiler characteristics.
99-
100-# Checks for library functions.
101-AC_FUNC_MALLOC
102-AC_CHECK_FUNCS([getpass strchr strdup])
103-
104 # Get the plugin dir
105-PLUGINDIR=$([$MYSQL_CONFIG --plugindir])
106+PLUGINDIR=`"$MYSQL_CONFIG" --plugindir`
107 AC_SUBST([PLUGINDIR])
108
109 # Get the revision if bzr is present
110 if test "x${BZR}" != "x"
111 then
112- if cd "$(dirname "$0")" && bzr status >& /dev/null
113- then
114- REVISION="$(cd "$(dirname "$0")"; ${BZR} log -r-1 | grep ^revno: | cut -d ' ' -f 2)"
115- else
116- REVISION=0
117- fi
118-else
119- REVISION=0
120+ REVISION=`"${BZR}" revno "$srcdir"`
121 fi
122+REVISION=${REVISION:-0}
123
124 AC_SUBST([REVISION])
125
126@@ -104,3 +80,4 @@
127 build/build-binary.sh
128 build/percona-pam-plugin.spec])
129 AC_OUTPUT
130+
131
132=== modified file 'src/Makefile.am'
133--- src/Makefile.am 2011-10-20 19:07:25 +0000
134+++ src/Makefile.am 2011-10-27 11:22:23 +0000
135@@ -16,11 +16,9 @@
136
137 plugindir = @PLUGINDIR@
138
139-AM_CFLAGS = @MYSQL_INCLUDES@
140-
141-plugin_LTLIBRARIES = auth_pam.la test_auth_pam_client.la
142-auth_pam_la_SOURCES = auth_pam.c lib_auth_pam_client.h lib_auth_pam_client.c
143-auth_pam_la_LDFLAGS = -module -avoid-version -shared
144-test_auth_pam_client_la_SOURCES = test_auth_pam_client.c \
145- lib_auth_pam_client.h lib_auth_pam_client.c
146-test_auth_pam_client_la_LDFLAGS = -module -avoid-version -shared
147+AM_CPPFLAGS = @MYSQL_INCLUDES@ -DMYSQL_DYNAMIC_PLUGIN
148+
149+plugin_LTLIBRARIES = auth_pam.la
150+auth_pam_la_SOURCES = auth_pam.c
151+auth_pam_la_LDFLAGS = -module -shared
152+
153
154=== modified file 'src/auth_pam.c'
155--- src/auth_pam.c 2011-10-25 17:46:19 +0000
156+++ src/auth_pam.c 2011-10-27 11:22:23 +0000
157@@ -18,71 +18,43 @@
158 /**
159 @file
160
161- PAM authentication for MySQL, server- and client-side plugins for the
162- production use.
163+ PAM authentication for MySQL.
164
165 A general-purpose PAM authentication plugin for MySQL. Acts as a mediator
166- between the MySQL server, the MySQL client, and the PAM backend. Consists of
167- both the server and the client plugin.
168-
169- The server plugin requests authentication from the PAM backend, forwards any
170- requests and messages from the PAM backend over the wire to the client (in
171- cleartext) and reads back any replies for the backend.
172-
173- The client plugin inputs from the TTY any requested info/passwords as
174- requested and sends them back over the wire to the server.
175+ between the MySQL server, the MySQL client, and the PAM backend.
176+
177+ The plugin requests authentication from the PAM backend, forwards any
178+ requests and messages from the PAM backend to the client "dialog" plugin
179+ (from dialog.so, loaded automatically by the libmysqlclient as needed)
180+ reads back any replies and passes them to the backend.
181
182 This plugin does not encrypt the communication channel in any way. If this is
183 required, a SSL connection should be used.
184
185 To install this plugin, copy the .so file to the plugin directory and do
186
187- INSTALL PLUGIN auth_pam_server SONAME 'auth_pam.so';
188+ INSTALL PLUGIN auth_pam SONAME 'auth_pam.so';
189+
190+ or add --plugin-load=auth.so to the my.cnf or the command line.
191
192 To use this plugin for one particular user, specify it at user's creation time
193- (TODO: tested with localhost only):
194
195- CREATE USER 'username'@'hostname' IDENTIFIED WITH auth_pam_server;
196+ CREATE USER 'username'@'hostname' IDENTIFIED WITH auth_pam;
197
198 Alternatively UPDATE the mysql.user table to set the plugin value for an
199 existing user.
200
201- Also it is possible to use this plugin to authenticate anonymous users:
202+ Also it is possible to use this plugin to authenticate all users:
203
204- CREATE USER ''@'hostname' IDENTIFIED WITH auth_pam_server;
205+ CREATE USER ''@'hostname' IDENTIFIED WITH auth_pam;
206
207 */
208
209-#include <assert.h>
210-
211 #include <security/pam_appl.h>
212 #include <security/pam_modules.h>
213-#include <security/pam_misc.h>
214-
215-#define MYSQL_DYNAMIC_PLUGIN
216-
217-/* Define these macros ourselves, so we don't have to include my_global.h and
218-can compile against unconfigured MySQL source tree. */
219-#define STDCALL
220-
221-#define MY_ASSERT_UNREACHABLE() assert(0)
222-
223-#include <mysql/plugin.h>
224+#include <string.h>
225+
226 #include <mysql/plugin_auth.h>
227-#include <mysql/client_plugin.h>
228-
229-#include <unistd.h> /* getpass() */
230-
231-#include "lib_auth_pam_client.h"
232-
233-/* The server plugin */
234-
235-/** The MySQL service name for PAM configuration */
236-static const char* service_name= "mysqld";
237-
238-/** The maximum length of MYSQL_SERVER_AUTH_INFO::external_user field.
239- Shouldn't be hardcoded in the plugin_auth.h but it is. */
240-enum { max_auth_info_external_user_len = 512 };
241
242 static int valid_pam_msg_style (int pam_msg_style)
243 {
244@@ -98,45 +70,21 @@
245 }
246 }
247
248-static char pam_msg_style_to_char (int pam_msg_style)
249-{
250- /* Do not use any of MySQL client-server protocol reserved values, i.e. \0 */
251- switch (pam_msg_style)
252- {
253- case PAM_PROMPT_ECHO_OFF: return '\2';
254- case PAM_PROMPT_ECHO_ON: return '\3';
255- case PAM_ERROR_MSG: return '\4';
256- case PAM_TEXT_INFO: return '\5';
257- default:
258- MY_ASSERT_UNREACHABLE();
259- return '\1';
260- }
261-}
262-
263-static void free_pam_response (struct pam_response ** resp, int n)
264-{
265- int i;
266- for (i = 0; i < n; i++)
267- {
268- free((*resp)[i].resp);
269- }
270- free(*resp);
271- *resp= NULL;
272-}
273+struct pam_conv_data {
274+ MYSQL_PLUGIN_VIO *vio;
275+ MYSQL_SERVER_AUTH_INFO *info;
276+ unsigned char buf[10240], *ptr;
277+};
278
279 static int vio_server_conv (int num_msg, const struct pam_message **msg,
280 struct pam_response ** resp, void *appdata_ptr)
281 {
282 int i;
283- int pkt_len;
284- MYSQL_PLUGIN_VIO *vio= NULL;
285+ struct pam_conv_data *data = (struct pam_conv_data *)appdata_ptr;
286+ unsigned char *end = data->buf + sizeof(data->buf) - 1;
287
288 if (appdata_ptr == NULL)
289- {
290- MY_ASSERT_UNREACHABLE();
291 return PAM_CONV_ERR;
292- }
293- vio= (MYSQL_PLUGIN_VIO *)appdata_ptr;
294
295 *resp = calloc (sizeof (struct pam_response), num_msg);
296 if (*resp == NULL)
297@@ -144,145 +92,100 @@
298
299 for (i = 0; i < num_msg; i++)
300 {
301- char *buf;
302-
303 if (!valid_pam_msg_style(msg[i]->msg_style))
304- {
305- free_pam_response(resp, i);
306- return PAM_CONV_ERR;
307- }
308-
309- /* Format the message. The first byte is the message type, followed by the
310- NUL-terminated message string itself. */
311- buf= malloc(strlen(msg[i]->msg) + 2);
312- if (!buf)
313- {
314- free_pam_response(resp, i);
315- return PAM_BUF_ERR;
316- }
317- buf[0]= pam_msg_style_to_char(msg[i]->msg_style);
318- strcpy(buf + 1, msg[i]->msg);
319-
320- /* Write the message. */
321- if (vio->write_packet(vio, (unsigned char *)buf, strlen(buf) + 1))
322- {
323- free(buf);
324- free_pam_response(resp, i);
325- return PAM_CONV_ERR;
326- }
327- free(buf);
328-
329- /* Is the answer expected? */
330- if ((msg[i]->msg_style != PAM_PROMPT_ECHO_ON)
331- && (msg[i]->msg_style != PAM_PROMPT_ECHO_OFF))
332- continue;
333-
334- /* Read the answer */
335- if ((pkt_len= vio->read_packet(vio, (unsigned char **)&buf)) < 0)
336- {
337- free_pam_response(resp, i);
338- return PAM_CONV_ERR;
339- }
340-
341- (*resp)[i].resp= malloc(pkt_len + 1);
342- if ((*resp)[i].resp == NULL)
343- {
344- free_pam_response(resp, i);
345- return PAM_BUF_ERR;
346- }
347- strncpy((*resp)[i].resp, buf, pkt_len);
348- (*resp)[i].resp[pkt_len]= '\0';
349+ return PAM_CONV_ERR;
350+
351+ if (msg[i]->msg)
352+ {
353+ int len = strlen(msg[i]->msg);
354+ if (len > end - data->ptr)
355+ len = end - data->ptr;
356+ memcpy(data->ptr, msg[i]->msg, len);
357+ data->ptr+= len;
358+ *(data->ptr)++ = '\n';
359+ }
360+
361+ if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF ||
362+ msg[i]->msg_style == PAM_PROMPT_ECHO_ON)
363+ {
364+ int pkt_len;
365+ unsigned char *pkt;
366+
367+ /* magic number for the dialog plugin, see dialog.c */
368+ data->buf[0] = msg[i]->msg_style == PAM_PROMPT_ECHO_ON ? 2 : 4;
369+
370+ if (data->vio->write_packet(data->vio, data->buf,
371+ data->ptr - data->buf - 1))
372+ return PAM_CONV_ERR;
373+
374+ pkt_len = data->vio->read_packet(data->vio, &pkt);
375+ if (pkt_len < 0)
376+ return PAM_CONV_ERR;
377+
378+ if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF)
379+ data->info->password_used = PASSWORD_USED_YES;
380+
381+ (*resp)[i].resp= strndup((char*)pkt, pkt_len);
382+ data->ptr = data->buf + 1;
383+ }
384 }
385 return PAM_SUCCESS;
386 }
387
388+#define DO_PAM(X) do { if ((error = (X)) != PAM_SUCCESS) goto ret; } while(0)
389+
390 static int authenticate_user_with_pam_server (MYSQL_PLUGIN_VIO *vio,
391 MYSQL_SERVER_AUTH_INFO *info)
392 {
393 pam_handle_t *pam_handle;
394- struct pam_conv conv_func_info= { &vio_server_conv, vio };
395+ struct pam_conv_data data;
396+ struct pam_conv conv_func_info= { &vio_server_conv, &data };
397 int error;
398 char *external_user_name;
399-
400- /* Impossible to tell if PAM will use passwords or something else */
401- info->password_used= PASSWORD_USED_NO_MENTION;
402-
403- error= pam_start(service_name,
404+ const char *service_name = info->auth_string && info->auth_string[0]
405+ ? info->auth_string : "mysqld";
406+ if (!info->user_name)
407+ return CR_ERROR;
408+
409+ data.vio = vio;
410+ data.info = info;
411+ data.ptr = data.buf + 1;
412+
413+ info->password_used = PASSWORD_USED_NO;
414+
415+ DO_PAM(pam_start(service_name,
416 info->user_name,
417- &conv_func_info, &pam_handle);
418- if (error != PAM_SUCCESS)
419- return CR_ERROR;
420-
421- error= pam_set_item(pam_handle, PAM_RUSER, info->user_name);
422- if (error != PAM_SUCCESS)
423- {
424- pam_end(pam_handle, error);
425- return CR_ERROR;
426- }
427-
428- error= pam_set_item(pam_handle, PAM_RHOST, info->host_or_ip);
429- if (error != PAM_SUCCESS)
430- {
431- pam_end(pam_handle, error);
432- return CR_ERROR;
433- }
434-
435- error= pam_authenticate(pam_handle, 0);
436- if (error != PAM_SUCCESS)
437- {
438- pam_end(pam_handle, error);
439- return CR_ERROR;
440- }
441-
442- error= pam_acct_mgmt(pam_handle, 0);
443- if (error != PAM_SUCCESS)
444- {
445- pam_end(pam_handle, error);
446- return CR_ERROR;
447- }
448-
449- /* Send end-of-auth message */
450- if (vio->write_packet(vio, (const unsigned char *)"\0", 1))
451- {
452- pam_end(pam_handle, error);
453- return CR_ERROR;
454- }
455+ &conv_func_info, &pam_handle));
456+
457+ DO_PAM(pam_set_item(pam_handle, PAM_RUSER, info->user_name));
458+
459+ DO_PAM(pam_set_item(pam_handle, PAM_RHOST, info->host_or_ip));
460+
461+ DO_PAM(pam_authenticate(pam_handle, 0));
462+
463+ DO_PAM(pam_acct_mgmt(pam_handle, 0));
464
465 /* Get the authenticated user name from PAM */
466- error= pam_get_item(pam_handle, PAM_USER, (void *)&external_user_name);
467- if (error != PAM_SUCCESS)
468- {
469- pam_end(pam_handle, error);
470- return CR_ERROR;
471- }
472+ DO_PAM(pam_get_item(pam_handle, PAM_USER, (void *)&external_user_name));
473
474 /* Check if user name from PAM is the same as provided for MySQL. If
475- different, set @@external_user for the current session to the one provided by
476+ different, set authenticated_as for the current session to the one provided by
477 PAM. */
478 if (strcmp(info->user_name, external_user_name))
479 {
480- strncpy(info->external_user, external_user_name,
481- max_auth_info_external_user_len);
482+ strncpy(info->authenticated_as, external_user_name,
483+ sizeof(info->authenticated_as));
484 }
485
486- error= pam_end(pam_handle, error);
487- if (error != PAM_SUCCESS)
488- return CR_ERROR;
489-
490- return CR_OK;
491+ret:
492+ pam_end(pam_handle, error);
493+ return error == PAM_SUCCESS ? CR_OK : CR_ERROR;
494 }
495
496 static struct st_mysql_auth pam_auth_handler=
497 {
498 MYSQL_AUTHENTICATION_INTERFACE_VERSION,
499- "auth_pam",
500- &authenticate_user_with_pam_server
501-};
502-
503-static struct st_mysql_auth test_pam_auth_handler=
504-{
505- MYSQL_AUTHENTICATION_INTERFACE_VERSION,
506- "auth_pam_test",
507+ "dialog",
508 &authenticate_user_with_pam_server
509 };
510
511@@ -290,32 +193,13 @@
512 {
513 MYSQL_AUTHENTICATION_PLUGIN,
514 &pam_auth_handler,
515- "auth_pam_server",
516+ "auth_pam",
517 "Percona, Inc.",
518 "PAM authentication plugin",
519 PLUGIN_LICENSE_GPL,
520 NULL,
521 NULL,
522- 0x0001,
523- NULL,
524- NULL,
525- NULL
526-#if MYSQL_PLUGIN_INTERFACE_VERSION >= 0x103
527- ,
528- 0
529-#endif
530-},
531-{
532- MYSQL_AUTHENTICATION_PLUGIN,
533- &test_pam_auth_handler,
534- "test_auth_pam_server",
535- "Percona, Inc.",
536- "PAM authentication plugin that requests the test version of the"
537- " client-side plugin. DO NOT USE IN PRODUCTION.",
538- PLUGIN_LICENSE_GPL,
539- NULL,
540- NULL,
541- 0x0001,
542+ 0x0100,
543 NULL,
544 NULL,
545 NULL
546@@ -326,67 +210,23 @@
547 }
548 mysql_declare_plugin_end;
549
550-/* The client plugin */
551-
552-/* Returns malloc-allocated string, NULL in case of memory error. */
553-static char * prompt_echo_off (const char * prompt)
554-{
555- /* TODO: getpass not thread safe. Probably not a big deal in the mysql
556- client program, but may be missing on non-glibc systems. */
557- char* getpass_input= getpass(prompt);
558- return strdup(getpass_input);
559-}
560-
561-/* Returns malloc-allocated string, NULL in case of memory or (unlikely)
562-I/O error. */
563-static char * prompt_echo_on (const char * prompt)
564-{
565- char* c;
566- char fgets_buf[1024];
567- fputs(prompt, stdout);
568- fputc(' ', stdout);
569- c= fgets(fgets_buf, sizeof(fgets_buf), stdin);
570- if (c == NULL)
571- {
572- if (ferror(stdin))
573- return NULL;
574- fgets_buf[0]= '\0';
575- }
576- if ((c= strchr(fgets_buf, '\n')))
577- *c= '\0';
578- else
579- fgets_buf[sizeof(fgets_buf) - 1]= '\0';
580- return strdup(fgets_buf);
581-}
582-
583-static void show_error(const char * message)
584-{
585- fprintf(stderr, "ERROR %s\n", message);
586-}
587-
588-static void show_info(const char * message)
589-{
590- printf("%s\n", message);
591-}
592-
593-static int authenticate_user_with_pam_client (MYSQL_PLUGIN_VIO *vio,
594- struct st_mysql *mysql)
595-{
596- return authenticate_user_with_pam_client_common (vio, mysql,
597- &prompt_echo_off,
598- &prompt_echo_on,
599- &show_error, &show_info);
600-}
601-
602-mysql_declare_client_plugin(AUTHENTICATION)
603+#ifdef maria_declare_plugin
604+maria_declare_plugin(auth_pam)
605+{
606+ MYSQL_AUTHENTICATION_PLUGIN,
607+ &pam_auth_handler,
608 "auth_pam",
609 "Percona, Inc.",
610 "PAM authentication plugin",
611- {0,1,0},
612- "GPL",
613- NULL,
614- NULL, /* init */
615- NULL, /* deinit */
616- NULL, /* options */
617- &authenticate_user_with_pam_client
618-mysql_end_client_plugin;
619+ PLUGIN_LICENSE_GPL,
620+ NULL,
621+ NULL,
622+ 0x0100,
623+ NULL,
624+ NULL,
625+ "1.0",
626+ MariaDB_PLUGIN_MATURITY_BETA
627+}
628+maria_declare_plugin_end;
629+#endif
630+
631
632=== removed file 'src/lib_auth_pam_client.c'
633--- src/lib_auth_pam_client.c 2011-10-20 19:07:25 +0000
634+++ src/lib_auth_pam_client.c 1970-01-01 00:00:00 +0000
635@@ -1,76 +0,0 @@
636-/*
637- (C) 2011 Percona Inc.
638-
639- This program is free software; you can redistribute it and/or modify
640- it under the terms of the GNU General Public License as published by
641- the Free Software Foundation; version 2 of the License.
642-
643- This program is distributed in the hope that it will be useful,
644- but WITHOUT ANY WARRANTY; without even the implied warranty of
645- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
646- GNU General Public License for more details.
647-
648- You should have received a copy of the GNU General Public License
649- along with this program; if not, write to the Free Software
650- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
651-*/
652-
653-/**
654- @file
655-
656- PAM authentication for MySQL, common code for client-side plugins.
657-
658- For the general description, see the top comment in auth_pam.c.
659-*/
660-#include "lib_auth_pam_client.h"
661-
662-#include <assert.h>
663-#include <string.h>
664-
665-#define MY_ASSERT_UNREACHABLE() assert(0)
666-
667-int authenticate_user_with_pam_client_common (MYSQL_PLUGIN_VIO *vio,
668- struct st_mysql *mysql __attribute__((unused)),
669- prompt_fn echoless_prompt_fn,
670- prompt_fn echo_prompt_fn,
671- info_fn show_error_fn,
672- info_fn show_info_fn)
673-{
674- do {
675- char *buf;
676- int pkt_len;
677-
678- if ((pkt_len= vio->read_packet(vio, (unsigned char **)&buf)) < 0)
679- return CR_ERROR;
680-
681- /* The first byte is the message type, followed by the message itself. */
682-
683- if (buf[0] == '\2' || buf[0] == '\3')
684- {
685- /* '\2' - PAM_PROMPT_ECHO_OFF, '\3' - PAM_PROMPT_ECHO_ON */
686- char *reply = (buf[0] == '\2')
687- ? echoless_prompt_fn(&buf[1]) : echo_prompt_fn(&buf[1]);
688- if (!reply)
689- return CR_ERROR;
690- if (vio->write_packet(vio, (unsigned char *)reply, strlen(reply) + 1))
691- {
692- free(reply);
693- return CR_ERROR;
694- }
695- free(reply);
696- }
697- else if (buf[0] == '\4') /* PAM_ERROR_MSG */
698- show_error_fn(&buf[1]);
699- else if (buf[0] == '\5') /* PAM_TEXT_INFO */
700- show_info_fn(&buf[1]);
701- else if (buf[0] == '\0') /* end-of-authorization */
702- return CR_OK;
703- else
704- return CR_ERROR; /* Unknown! */
705- }
706- while (1);
707-
708- /* Should not come here */
709- MY_ASSERT_UNREACHABLE();
710- return CR_ERROR;
711-}
712
713=== removed file 'src/lib_auth_pam_client.h'
714--- src/lib_auth_pam_client.h 2011-10-20 19:07:25 +0000
715+++ src/lib_auth_pam_client.h 1970-01-01 00:00:00 +0000
716@@ -1,80 +0,0 @@
717-#ifndef LIB_AUTH_PAM_CLIENT_INCLUDED
718-#define LIB_AUTH_PAM_CLIENT_INCLUDED
719-/*
720- (C) 2011 Percona Inc.
721-
722- This program is free software; you can redistribute it and/or modify
723- it under the terms of the GNU General Public License as published by
724- the Free Software Foundation; version 2 of the License.
725-
726- This program is distributed in the hope that it will be useful,
727- but WITHOUT ANY WARRANTY; without even the implied warranty of
728- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
729- GNU General Public License for more details.
730-
731- You should have received a copy of the GNU General Public License
732- along with this program; if not, write to the Free Software
733- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
734-*/
735-
736-/**
737- @file
738-
739- PAM authentication for MySQL, common definitions for client-side plugins.
740-
741- For the general description, see the top comment in auth_pam.c.
742-*/
743-
744-#define STDCALL
745-
746-#include <mysql/client_plugin.h>
747-
748-/**
749- Callback type for functions that prompt the user for (echoed or silent) input
750- and return it. Should returns a pointer to malloc-allocated string, the
751- caller is responsible for freeing it. Should return NULL in the case of a
752- memory allocation or I/O error. */
753-typedef char* (*prompt_fn)(const char *);
754-
755-/**
756- Callback type for functions that show user some info (error or notification).
757-*/
758-typedef void (*info_fn)(const char *);
759-
760-struct st_mysql;
761-
762-#ifdef __cplusplus
763-extern "C" {
764-#endif
765-
766-/**
767- Client-side PAM auth plugin implementation.
768-
769- Communicates with the server-side plugin and does user interaction using the
770- provided callbacks.
771-
772- @param vio TODO
773- @param mysql TODO
774- @param echoless_prompt_fn callback to use to prompt the user for non-echoed
775- input (e.g. password)
776- @param echo_prompt_fn callback to use to prompt the user for echoed input
777- (e.g. user name)
778- @param show_error_fn callback to use to show the user an error message
779- @param show_info_fn callback to use to show the user an informational message
780-
781- @return Authentication conversation status
782- @retval CR_OK the authentication dialog is completed successfully
783- @retval CR_ERROR the authentication dialog is aborted due to error
784-*/
785-int authenticate_user_with_pam_client_common (MYSQL_PLUGIN_VIO *vio,
786- struct st_mysql *mysql,
787- prompt_fn echoless_prompt_fn,
788- prompt_fn echo_prompt_fn,
789- info_fn show_error_fn,
790- info_fn show_info_fn);
791-
792-#ifdef __cplusplus
793-}
794-#endif
795-
796-#endif
797
798=== removed file 'src/test_auth_pam_client.c'
799--- src/test_auth_pam_client.c 2011-10-20 19:07:25 +0000
800+++ src/test_auth_pam_client.c 1970-01-01 00:00:00 +0000
801@@ -1,79 +0,0 @@
802-/*
803- (C) 2011 Percona Inc.
804-
805- This program is free software; you can redistribute it and/or modify
806- it under the terms of the GNU General Public License as published by
807- the Free Software Foundation; version 2 of the License.
808-
809- This program is distributed in the hope that it will be useful,
810- but WITHOUT ANY WARRANTY; without even the implied warranty of
811- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
812- GNU General Public License for more details.
813-
814- You should have received a copy of the GNU General Public License
815- along with this program; if not, write to the Free Software
816- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
817-*/
818-
819-/**
820- @file
821-
822- PAM authentication for MySQL, the test version of the client-side plugin.
823-*/
824-
825-#include <string.h>
826-
827-#define STDCALL
828-
829-#include <mysql/plugin_auth.h>
830-#include <mysql/client_plugin.h>
831-
832-#include "lib_auth_pam_client.h"
833-
834-const char * echo_off_reply_1 = "aaaaaaa";
835-const char * echo_off_reply_2 = "AAAAAAA";
836-
837-const char * echo_on_reply_1 = "bbbbbbbbbb";
838-const char * echo_on_reply_2 = "BBBBBBBBBB";
839-
840-/* Returns alternating echo_off_reply_1 and echo_off_reply_2 */
841-static char * test_prompt_echo_off (const char * prompt __attribute__((unused)))
842-{
843- static unsigned call_no= 0;
844- return strdup((call_no++ % 2) == 0 ? echo_off_reply_1 : echo_off_reply_2);
845-}
846-
847-/* Returns alternating echo_on_reply_1 and echo_on_reply_2 */
848-static char * test_prompt_echo_on (const char * prompt __attribute__((unused)))
849-{
850- static unsigned call_no= 0;
851- return strdup((call_no++ % 2) == 0 ? echo_on_reply_1 : echo_on_reply_2);
852-}
853-
854-/* Pretend we have shown the message to the user */
855-static void test_show_anything(const char * message __attribute__((unused)))
856-{
857-}
858-
859-static int test_pam_auth_client (MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql)
860-{
861- return authenticate_user_with_pam_client_common (vio, mysql,
862- &test_prompt_echo_off,
863- &test_prompt_echo_on,
864- &test_show_anything,
865- &test_show_anything);
866-}
867-
868-mysql_declare_client_plugin(AUTHENTICATION)
869- "auth_pam_test",
870- "Percona, Inc.",
871- "Test version of the client PAM authentication plugin. "
872- "DO NOT USE IN PRODUCTION.",
873- {0,1,0},
874- "GPL",
875- NULL,
876- NULL, /* init */
877- NULL, /* deinit */
878- NULL, /* options */
879- &test_pam_auth_client
880-mysql_end_client_plugin;

Subscribers

People subscribed via source and target branches