Commit 114dbca9 114dbca969e32571e205a2f812007509e61424d3 by Sergey Poznyakoff

Merged sql core stuff from MySql/MySql.c

1 parent 5130f6bc
Showing 1 changed file with 325 additions and 28 deletions
...@@ -39,50 +39,351 @@ ...@@ -39,50 +39,351 @@
39 #include <mailutils/mailbox.h> 39 #include <mailutils/mailbox.h>
40 #include <mailutils/argp.h> 40 #include <mailutils/argp.h>
41 #include <mailutils/mu_auth.h> 41 #include <mailutils/mu_auth.h>
42 #include <mailutils/error.h>
42 43
43 #ifdef HAVE_MYSQL 44 #ifdef HAVE_MYSQL
44 # include "../MySql/MySql.h" 45 #include <mysql/mysql.h>
45 #endif 46
47 #define MFLAGS 0 /* Special user flags. It is safe to leave
48 this untouched */
49
50 char *sql_getpwnam_query;
51 char *sql_getpass_query;
52 char *sql_getpwuid_query;
53
54 char *sql_host = NULL; /* Hostname to connect to. NULL for UNIX
55 socket connection */
56 char *sql_user = "accounts"; /* Username for mysql access */
57 char *sql_passwd = "yurpass"; /* Password for mysql access */
58 char *sql_db = "accounts"; /* Database Name */
59 char *sql_socket = NULL; /* Socket name to use. Valid only if
60 connecting via UNIX sockets */
61 int sql_port = 0; /* Port number to connect to. 0 means default
62 MySQL port (3300) */
63
64 static char *
65 sql_expand_query (const char *query, const char *ustr)
66 {
67 char *p, *q, *res;
68 int len;
69
70 if (!query)
71 return NULL;
72
73 /* Compute resulting query length */
74 for (len = 0, p = (char *) query; *p; )
75 {
76 if (*p == '%')
77 {
78 if (p[1] == 'u')
79 {
80 len += strlen (ustr);
81 p += 2;
82 }
83 else if (p[1] == '%')
84 {
85 len++;
86 p += 2;
87 }
88 else
89 {
90 len++;
91 p++;
92 }
93 }
94 else
95 {
96 len++;
97 p++;
98 }
99 }
100
101 res = malloc (len + 1);
102 if (!res)
103 return res;
104
105 for (p = (char *) query, q = res; *p; )
106 {
107 if (*p == '%')
108 {
109 switch (*++p)
110 {
111 case 'u':
112 strcpy (q, ustr);
113 q += strlen (q);
114 p++;
115 break;
46 116
47 /* SQL */ 117 case '%':
48 /* FIXME: Underlying library needs rewriting */ 118 *q++ = *p++;
119 break;
120
121 default:
122 *q++ = *p++;
123 }
124 }
125 else
126 *q++ = *p++;
127 }
128 *q = 0;
129 return res;
130 }
49 131
50 int 132 static int
51 mu_auth_sql_by_name (void *return_data, void *key, 133 mu_auth_sql_by_name (void *return_data, void *key,
52 void *unused_func_data, void *unused_call_data) 134 void *unused_func_data, void *unused_call_data)
53 { 135 {
136 char *query_str = NULL;
137 MYSQL *m;
138 MYSQL_RES *res;
139 MYSQL_ROW row;
140 char *mailbox_name;
141 int rc;
142
54 if (!key) 143 if (!key)
55 { 144 {
56 errno = EINVAL; 145 errno = EINVAL;
57 return 1; 146 return 1;
58 } 147 }
59 #ifdef HAVE_MYSQL 148
60 return mu_auth_system (return_data, getMpwnam (key)); 149 m = mysql_init (0);
61 #else 150
62 errno = ENOSYS; 151 if (!m)
63 return 1; 152 return 1;
64 #endif 153
154 if (!mysql_real_connect (m, sql_host, sql_user, sql_passwd, sql_db, sql_port,
155 sql_socket, MFLAGS))
156 {
157 mu_error ("MySQL: connect failed: %s", mysql_error (m));
158 mysql_close (m);
159 return 1;
160 }
161
162 query_str = sql_expand_query (sql_getpwnam_query, key);
163
164 if (!query_str)
165 {
166 mysql_close (m);
167 return 1;
168 }
169
170 if (mysql_query (m, query_str) != 0)
171 {
172 mu_error ("MySQL: query failed: %s", mysql_error (m));
173 free (query_str);
174 mysql_close (m);
175 return 1;
176 }
177
178 free (query_str);
179
180 if ((res = mysql_store_result (m)) == NULL)
181 {
182 mu_error ("MySQL: can't store result: %s", mysql_error (m));
183 mysql_close (m);
184 return 1;
185 }
186
187 if ((row = mysql_fetch_row (res)) == NULL)
188 {
189 mu_error ("MySQL: can't fetch row: %s", mysql_error (m));
190 mysql_close (m);
191 return 1;
192 }
193
194 if (mysql_num_fields (res) == 7 && row[6])
195 mailbox_name = strdup (row[6]);
196 else
197 {
198 mailbox_name = malloc (strlen (mu_path_maildir) +
199 strlen (row[0]) + 1);
200 if (mailbox_name)
201 sprintf (mailbox_name, "%s%s", mu_path_maildir, row[0]);
202 }
203
204 if (mailbox_name)
205 rc = mu_auth_data_alloc ((struct mu_auth_data **) return_data,
206 row[0],
207 row[1],
208 atoi (row[2]),
209 atoi (row[3]),
210 "Mysql User",
211 row[4],
212 row[5],
213 mailbox_name,
214 1);
215 else
216 rc = 1;
217
218 free (mailbox_name);
219 mysql_free_result (res);
220 mysql_close (m);
221
222 return rc;
65 } 223 }
66 224
67 int 225 static int
68 mu_auth_sql_by_uid (void *return_data, void *key, 226 mu_auth_sql_by_uid (void *return_data, void *key,
69 void *unused_func_data, void *unused_call_data) 227 void *unused_func_data, void *unused_call_data)
70 { 228 {
229 char *query_str = NULL;
230 MYSQL *m;
231 MYSQL_RES *res;
232 MYSQL_ROW row;
233 char uidstr[64];
234 char *mailbox_name;
235 int rc;
236
71 if (!key) 237 if (!key)
72 { 238 {
73 errno = EINVAL; 239 errno = EINVAL;
74 return 1; 240 return 1;
75 } 241 }
76 242
77 #ifdef HAVE_MYSQL 243 m = mysql_init (0);
78 return mu_auth_system (return_data, getMpwuid (key)); 244
79 #else 245 if (!m)
80 errno = ENOSYS;
81 return 1; 246 return 1;
82 #endif 247
248 if (!mysql_real_connect (m, sql_host, sql_user, sql_passwd, sql_db, sql_port,
249 sql_socket, MFLAGS))
250 {
251 mu_error ("MySQL: connect failed: %s", mysql_error (m));
252 mysql_close (m);
253 return 1;
254 }
255
256 snprintf (uidstr, sizeof (uidstr), "%u", *(uid_t*)key);
257 query_str = sql_expand_query (sql_getpwnam_query, uidstr);
258
259 if (!query_str)
260 {
261 mysql_close (m);
262 return 1;
263 }
264
265 if (mysql_query (m, query_str) != 0)
266 {
267 mu_error ("MySQL: query failed: %s", mysql_error (m));
268 free (query_str);
269 mysql_close (m);
270 return 1;
271 }
272
273 free (query_str);
274
275 if ((res = mysql_store_result (m)) == NULL)
276 {
277 mu_error ("MySQL: can't store result: %s", mysql_error (m));
278 mysql_close (m);
279 return 1;
280 }
281
282 if ((row = mysql_fetch_row (res)) == NULL)
283 {
284 mu_error ("MySQL: can't fetch row: %s", mysql_error (m));
285 mysql_close (m);
286 return 1;
287 }
288
289 if (mysql_num_fields (res) == 7 && row[6])
290 mailbox_name = strdup (row[6]);
291 else
292 {
293 mailbox_name = malloc (strlen (mu_path_maildir) +
294 strlen (row[0]) + 1);
295 if (mailbox_name)
296 sprintf (mailbox_name, "%s%s", mu_path_maildir, row[0]);
297 }
298
299 if (mailbox_name)
300 rc = mu_auth_data_alloc ((struct mu_auth_data **) return_data,
301 row[0],
302 row[1],
303 atoi (row[2]),
304 atoi (row[3]),
305 "Mysql User",
306 row[4],
307 row[5],
308 mailbox_name,
309 1);
310 else
311 rc = 1;
312
313 free (mailbox_name);
314 mysql_free_result (res);
315 mysql_close (m);
316
317 return rc;
83 } 318 }
84 319
85 #ifdef HAVE_MYSQL 320 static int
321 mu_sql_authenticate (void *ignored_return_data, void *key,
322 void *ignored_func_data, void *call_data)
323 {
324 struct mu_auth_data *auth_data = key;
325 char *pass = call_data;
326 char *query_str = NULL;
327 MYSQL *m;
328 MYSQL_RES *res;
329 MYSQL_ROW row;
330 int rc;
331
332 if (!auth_data)
333 return 1;
334
335 m = mysql_init (0);
336
337 if (!m)
338 return 1;
339
340 if (!mysql_real_connect (m, sql_host, sql_user, sql_passwd, sql_db, sql_port,
341 sql_socket, MFLAGS))
342 {
343 mu_error ("MySQL: connect failed: %s", mysql_error (m));
344 mysql_close (m);
345 return 1;
346 }
347
348 query_str = sql_expand_query (sql_getpass_query, auth_data->name);
349
350 if (!query_str)
351 {
352 mysql_close (m);
353 return 1;
354 }
355
356 if (mysql_query (m, query_str) != 0)
357 {
358 mu_error ("MySQL: query failed: %s", mysql_error (m));
359 free (query_str);
360 mysql_close (m);
361 return 1;
362 }
363
364 free (query_str);
365
366 if ((res = mysql_store_result (m)) == NULL)
367 {
368 mu_error ("MySQL: can't store result: %s", mysql_error (m));
369 mysql_close (m);
370 return 1;
371 }
372
373 if ((row = mysql_fetch_row (res)) == NULL)
374 {
375 mu_error ("MySQL: can't fetch row: %s", mysql_error (m));
376 mysql_close (m);
377 return 1;
378 }
379
380 rc = strcmp (row[0], crypt (auth_data->passwd, row[0]));
381 mysql_free_result (res);
382 mysql_close (m);
383 return rc;
384 }
385
386
86 # define ARG_SQL_GETPWNAM 1 387 # define ARG_SQL_GETPWNAM 1
87 # define ARG_SQL_GETPWUID 2 388 # define ARG_SQL_GETPWUID 2
88 # define ARG_SQL_GETPASS 3 389 # define ARG_SQL_GETPASS 3
...@@ -112,16 +413,6 @@ static struct argp_option mu_sql_argp_option[] = { ...@@ -112,16 +413,6 @@ static struct argp_option mu_sql_argp_option[] = {
112 { NULL, 0, NULL, 0, NULL, 0 } 413 { NULL, 0, NULL, 0, NULL, 0 }
113 }; 414 };
114 415
115 char *sql_getpwnam_query;
116 char *sql_getpass_query;
117 char *sql_getpwuid_query;
118 char *sql_host = MHOST;
119 char *sql_user = MUSER;
120 char *sql_passwd = MPASS;
121 char *sql_db = MDB;
122 char *sql_socket = MSOCKET;
123 int sql_port = MPORT;
124
125 static error_t 416 static error_t
126 mu_sql_argp_parser (int key, char *arg, struct argp_state *state) 417 mu_sql_argp_parser (int key, char *arg, struct argp_state *state)
127 { 418 {
...@@ -175,6 +466,12 @@ struct argp mu_sql_argp = { ...@@ -175,6 +466,12 @@ struct argp mu_sql_argp = {
175 mu_sql_argp_parser, 466 mu_sql_argp_parser,
176 }; 467 };
177 468
469 #else
470
471 #define mu_sql_authenticate mu_auth_nosupport
472 #define mu_auth_sql_by_name mu_auth_nosupport
473 #define mu_auth_sql_by_uid mu_auth_nosupport
474
178 #endif 475 #endif
179 476
180 struct mu_auth_module mu_auth_sql_module = { 477 struct mu_auth_module mu_auth_sql_module = {
...@@ -184,7 +481,7 @@ struct mu_auth_module mu_auth_sql_module = { ...@@ -184,7 +481,7 @@ struct mu_auth_module mu_auth_sql_module = {
184 #else 481 #else
185 NULL, 482 NULL,
186 #endif 483 #endif
187 mu_auth_nosupport, 484 mu_sql_authenticate,
188 NULL, 485 NULL,
189 mu_auth_sql_by_name, 486 mu_auth_sql_by_name,
190 NULL, 487 NULL,
......