/*
* mypasswd - password changer for mysql_auth
*
* mypasswd.c
* (C) 2002 Ervin Hegedus
* Released under GPL, see COPYING-2.0 for details.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <mysql/mysql.h>
#include <syslog.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <termios.h>
#include <ctype.h>
#include "define.h"
#include "extern.h"
/*
* usage: if user no gives (enough) parameters
*/
void usage (void)
{
fprintf (stderr, "Use: mypasswd [-d] username [new password]\n");
fprintf (stderr, " - use -d switch, if you want to delete a user from database;\n");
fprintf (stderr, " - if you don't give new password in command line,\n");
fprintf (stderr, " you need to type twice at the 'Enter NEW password:',\n");
fprintf (stderr, " and 'Retype NEW password:' prompts\n\n");
}
/*
* get hide password from standard input
*/
void getpassw(char * newpass, char * output)
{
struct termios term, termsave;
char c;
int i = 0;
// save tty state
tcgetattr (fileno (stdin), &termsave);
term = termsave;
term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
tcsetattr (fileno (stdin), TCSAFLUSH, &term);
// print query string
fprintf (stdout, "%s", output);
// get password with no echo
while ((c = getc(stdin)), c != EOF && c != '\n') {
if (i < MAX_STRLEN) {
newpass[i++] = c;
}
}
newpass[i] = '\0';
// restore tty state
tcsetattr (fileno (stdin), TCSAFLUSH, &termsave);
// print a newline
fputc ('\n', stdout);
}
int main (int argc, char ** argv)
{
MYSQL connect;
MYSQL_RES *result;
MYSQL_ROW row;
struct my_params parameters;
// MAX_STRLEN defined in define.h (value=32)
char user[MAX_STRLEN] = "", newpw[MAX_STRLEN] = "", t_newpw[MAX_STRLEN] = "";
char query[512], error_mess[512], out_mess[512];
if (argc < 2) {
usage();
exit (1);
}
/*
* try open and read config file, config file place' see define.h
*/
if (parse (¶meters) != 0) {
fprintf (stderr, "Can't open mysql_auth.conf!\n");
exit (1);
}
/*
* try to initialize MYSQL structure
*/
mysql_init (&connect);
if (&connect == NULL) {
syslog (LOG_WARNING, "Can't initialize MYSQL structure!");
puts ("ERR");
exit (1);
}
/*
* try connect to mysql database, with those user/password, what are
* defined in mysql_auth.conf - this is the squid -> mysql connect pair!
*/
mysql_real_connect (&connect, parameters.var_host_name,\
parameters.var_user_name,\
parameters.var_user_password,\
parameters.var_database_name,\
0,\
parameters.var_mysqld_socket,\
0);
/*
* if error returns, log trough syslog
*/
if (mysql_errno (&connect)) {
fprintf (stderr, "Can't connect to mysql server: %s.\n", \
parameters.var_host_name);
fprintf (stderr, "Error was: %d - %s.\n", \
mysql_errno (&connect), mysql_error (&connect));
exit (1);
}
/*
* try to select from table - there is all the same,
* what will the result, just look the table name and column names
*/
memset (query, '\0', strlen (query) + 1);
sprintf (query, "SELECT * FROM %s WHERE %s LIKE 'squid' AND %s LIKE 'squid'", \
parameters.var_table_name, \
parameters.var_user_column, \
parameters.var_password_column);
mysql_query (&connect, query);
if (mysql_errno (&connect)) {
fprintf (stderr, "Can't select from table - error was: %d - %s", \
mysql_errno (&connect), \
mysql_error (&connect));
exit (1);
}
/*
* these are requires for mysql fuctions
*/
result = mysql_use_result (&connect);
while (mysql_fetch_row (result));
mysql_free_result(result);
/***********************************************************
*
* if all mysql parameters okay, let's start the transaction
*
***********************************************************/
if (argc >= 3) {
if (strcmp (argv[1], "-d") == 0) {
strcpy (user, argv[2]);
sprintf (query, "DELETE FROM %s WHERE %s LIKE '%s'", \
parameters.var_table_name, parameters.var_user_column, user);
mysql_query (&connect, query);
if (mysql_errno (&connect)) {
fprintf (stderr, "Can't delete record - error was: %d - %s\n", \
mysql_errno (&connect), \
mysql_error (&connect));
}
else {
fprintf (stdout, "Password record DELETED succesfully.\n");
}
exit (1);
}
// 3rd argument is the new password
else {
// if 2nd argument is not alphanumeric, then error (may be 2nd arg is a switch)
if (isalpha (argv[1][0]) == 0) {
usage ();
exit (1);
}
strcpy (user, argv[1]);
strcpy (newpw, argv[2]);
}
}
else {
// if 2nd argument is not alphanumeric, then error (may be 2nd arg is a switch)
if (isalpha (argv[1][0]) == 0) {
usage ();
exit (1);
}
strcpy (user, argv[1]);
getpassw (newpw, "Enter NEW password: ");
getpassw (t_newpw, "Re-enter NEW password: ");
if (strcmp (newpw, t_newpw) != 0) {
fprintf (stderr, "Password verification error.\n");
exit (1);
}
}
// if you use encrypt form to store the passwords, use mysql internal
// password() function
if (strcasecmp (parameters.var_encrypt_password_form, "yes") == 0) {
t_newpw[0] = '\0';
sprintf (t_newpw, "password (\"%s\")", newpw);
}
else {
t_newpw[0] = '\0';
sprintf (t_newpw, "'%s'", newpw);
}
newpw[0] = '\0';
strcpy (newpw, t_newpw);
memset (query, '\0', strlen (query) + 1);
sprintf (query, "SELECT * FROM %s WHERE %s LIKE '%s'", \
parameters.var_table_name, \
parameters.var_user_column, user);
mysql_query (&connect, query);
/*
* may be when mysql_auth runs, meantime lost connection,
* invalid table name, etc...
*/
if (mysql_errno (&connect)) {
fprintf (stderr, "Can't select from table - error was: %d - %s\n", \
mysql_errno (&connect), \
mysql_error (&connect));
exit (1);
}
result = mysql_use_result (&connect);
while ((row = mysql_fetch_row (result)));
memset (query, '\0', strlen (query) + 1);
memset (error_mess, '\0', strlen (error_mess) + 1);
memset (out_mess, '\0', strlen (out_mess) + 1);
// select number of user in database - it is JUST 0 or 1, AND just 0 or 1
// if number of user equal 1, then user exist: update password of user
if (mysql_num_rows (result) == 1) {
sprintf (query, "UPDATE %s SET %s = %s WHERE %s LIKE '%s'", \
parameters.var_table_name, \
parameters.var_password_column, newpw, \
parameters.var_user_column, user);
// mysql transaction
mysql_query (&connect, query);
if (mysql_errno (&connect)) {
fprintf (stderr, "Can't update record - error was: %d - %s\n", \
mysql_errno (&connect), \
mysql_error (&connect));
}
else {
fprintf (stdout, "Password record UPDATED succesfully.\n");
}
}
// if number of user equal 0, then user does not exist: insert new user
else {
sprintf (query, "INSERT INTO %s (%s, %s) VALUES ('%s', %s)", \
parameters.var_table_name, parameters.var_user_column, \
parameters.var_password_column, user, newpw);
// mysql transaction
mysql_query (&connect, query);
if (mysql_errno (&connect)) {
fprintf (stderr, "Can't insert record - error was: %d - %s\n", \
mysql_errno (&connect), \
mysql_error (&connect));