~ubuntu-branches/ubuntu/wily/dovecot/wily

« back to all changes in this revision

Viewing changes to src/auth/auth-request.c

  • Committer: Package Import Robot
  • Author(s): Jaldhar H. Vyas
  • Date: 2013-09-09 00:57:32 UTC
  • mfrom: (1.13.11)
  • mto: (4.8.5 experimental) (1.16.1)
  • mto: This revision was merged to the branch mainline in revision 97.
  • Revision ID: package-import@ubuntu.com-20130909005732-dn1eell8srqbhh0e
Tags: upstream-2.2.5
ImportĀ upstreamĀ versionĀ 2.2.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */
 
1
/* Copyright (c) 2002-2013 Dovecot authors, see the included COPYING file */
2
2
 
3
3
#include "auth-common.h"
4
4
#include "ioloop.h"
33
33
#define AUTH_DNS_WARN_MSECS 500
34
34
#define CACHED_PASSWORD_SCHEME "SHA1"
35
35
 
 
36
struct auth_request_proxy_dns_lookup_ctx {
 
37
        struct auth_request *request;
 
38
        auth_request_proxy_cb_t *callback;
 
39
        struct dns_lookup *dns_lookup;
 
40
};
 
41
 
36
42
unsigned int auth_request_state_count[AUTH_REQUEST_STATE_MAX];
37
43
 
38
44
static void get_log_prefix(string_t *str, struct auth_request *auth_request,
50
56
 
51
57
        request->refcount = 1;
52
58
        request->last_access = ioloop_time;
 
59
        request->session_pid = (pid_t)-1;
53
60
 
54
61
        request->set = global_auth_settings;
55
62
        request->mech = mech;
56
63
        request->mech_name = mech == NULL ? NULL : mech->mech_name;
 
64
        request->extra_fields = auth_fields_init(request->pool);
57
65
        return request;
58
66
}
59
67
 
71
79
 
72
80
        request->refcount = 1;
73
81
        request->last_access = ioloop_time;
 
82
        request->session_pid = (pid_t)-1;
74
83
        request->set = global_auth_settings;
 
84
        request->extra_fields = auth_fields_init(request->pool);
75
85
        return request;
76
86
}
77
87
 
109
119
{
110
120
        i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
111
121
 
112
 
        if (request->passdb_failure) {
 
122
        if (request->failed || !request->passdb_success) {
113
123
                /* password was valid, but some other check failed. */
114
124
                auth_request_fail(request);
115
125
                return;
135
145
 
136
146
        auth_request_set_state(request, AUTH_REQUEST_STATE_FINISHED);
137
147
        auth_request_refresh_last_access(request);
138
 
        auth_request_handler_reply(request, AUTH_CLIENT_RESULT_FAILURE,
139
 
                                   NULL, 0);
 
148
        auth_request_handler_reply(request, AUTH_CLIENT_RESULT_FAILURE, "", 0);
140
149
}
141
150
 
142
151
void auth_request_internal_failure(struct auth_request *request)
167
176
                            strlen(request->mech_password));
168
177
        }
169
178
 
 
179
        if (request->dns_lookup_ctx != NULL)
 
180
                dns_lookup_abort(&request->dns_lookup_ctx->dns_lookup);
170
181
        if (request->to_abort != NULL)
171
182
                timeout_remove(&request->to_abort);
172
183
        if (request->to_penalty != NULL)
178
189
                pool_unref(&request->pool);
179
190
}
180
191
 
181
 
void auth_request_export(struct auth_request *request,
182
 
                         struct auth_stream_reply *reply)
183
 
{
184
 
        auth_stream_reply_add(reply, "user", request->user);
185
 
        auth_stream_reply_add(reply, "service", request->service);
 
192
static void
 
193
auth_str_add_keyvalue(string_t *dest, const char *key, const char *value)
 
194
{
 
195
        str_append_c(dest, '\t');
 
196
        str_append(dest, key);
 
197
        if (value != NULL) {
 
198
                str_append_c(dest, '=');
 
199
                str_append_tabescaped(dest, value);
 
200
        }
 
201
}
 
202
 
 
203
void auth_request_export(struct auth_request *request, string_t *dest)
 
204
{
 
205
        str_append(dest, "user=");
 
206
        str_append_tabescaped(dest, request->user);
 
207
 
 
208
        auth_str_add_keyvalue(dest, "service", request->service);
186
209
 
187
210
        if (request->master_user != NULL) {
188
 
                auth_stream_reply_add(reply, "master_user",
 
211
                auth_str_add_keyvalue(dest, "master-user",
189
212
                                      request->master_user);
190
213
        }
191
 
        auth_stream_reply_add(reply, "original_username",
 
214
        auth_str_add_keyvalue(dest, "original_username",
192
215
                              request->original_username);
193
 
        auth_stream_reply_add(reply, "requested_login_user",
194
 
                              request->requested_login_user);
 
216
        if (request->requested_login_user != NULL) {
 
217
                auth_str_add_keyvalue(dest, "requested-login-user",
 
218
                                      request->requested_login_user);
 
219
        }
195
220
 
196
221
        if (request->local_ip.family != 0) {
197
 
                auth_stream_reply_add(reply, "lip",
 
222
                auth_str_add_keyvalue(dest, "lip",
198
223
                                      net_ip2addr(&request->local_ip));
199
224
        }
200
225
        if (request->remote_ip.family != 0) {
201
 
                auth_stream_reply_add(reply, "rip",
 
226
                auth_str_add_keyvalue(dest, "rip",
202
227
                                      net_ip2addr(&request->remote_ip));
203
228
        }
204
 
        if (request->local_port != 0) {
205
 
                auth_stream_reply_add(reply, "lport",
206
 
                                      dec2str(request->local_port));
207
 
        }
208
 
        if (request->remote_port != 0) {
209
 
                auth_stream_reply_add(reply, "rport",
210
 
                                      dec2str(request->remote_port));
211
 
        }
 
229
        if (request->local_port != 0)
 
230
                str_printfa(dest, "\tlport=%u", request->local_port);
 
231
        if (request->remote_port != 0)
 
232
                str_printfa(dest, "\trport=%u", request->remote_port);
 
233
        if (request->real_local_ip.family != 0) {
 
234
                auth_str_add_keyvalue(dest, "real_lip",
 
235
                                      net_ip2addr(&request->real_local_ip));
 
236
        }
 
237
        if (request->real_remote_ip.family != 0) {
 
238
                auth_str_add_keyvalue(dest, "real_rip",
 
239
                                      net_ip2addr(&request->real_remote_ip));
 
240
        }
 
241
        if (request->real_local_port != 0)
 
242
                str_printfa(dest, "\treal_lport=%u", request->real_local_port);
 
243
        if (request->real_remote_port != 0)
 
244
                str_printfa(dest, "\treal_rport=%u", request->real_remote_port);
212
245
        if (request->secured)
213
 
                auth_stream_reply_add(reply, "secured", "1");
 
246
                str_append(dest, "\tsecured");
214
247
        if (request->skip_password_check)
215
 
                auth_stream_reply_add(reply, "skip_password_check", "1");
 
248
                str_append(dest, "\tskip-password-check");
216
249
        if (request->valid_client_cert)
217
 
                auth_stream_reply_add(reply, "valid-client-cert", "1");
 
250
                str_append(dest, "\tvalid-client-cert");
218
251
        if (request->no_penalty)
219
 
                auth_stream_reply_add(reply, "no-penalty", "1");
 
252
                str_append(dest, "\tno-penalty");
220
253
        if (request->successful)
221
 
                auth_stream_reply_add(reply, "successful", "1");
 
254
                str_append(dest, "\tsuccessful");
222
255
        if (request->mech_name != NULL)
223
 
                auth_stream_reply_add(reply, "mech", request->mech_name);
 
256
                auth_str_add_keyvalue(dest, "mech", request->mech_name);
224
257
}
225
258
 
226
259
bool auth_request_import_info(struct auth_request *request,
229
262
        /* authentication and user lookups may set these */
230
263
        if (strcmp(key, "service") == 0)
231
264
                request->service = p_strdup(request->pool, value);
232
 
        else if (strcmp(key, "lip") == 0)
233
 
                net_addr2ip(value, &request->local_ip);
234
 
        else if (strcmp(key, "rip") == 0)
235
 
                net_addr2ip(value, &request->remote_ip);
236
 
        else if (strcmp(key, "lport") == 0)
 
265
        else if (strcmp(key, "lip") == 0) {
 
266
                (void)net_addr2ip(value, &request->local_ip);
 
267
                if (request->real_local_ip.family == 0)
 
268
                        request->real_local_ip = request->local_ip;
 
269
        } else if (strcmp(key, "rip") == 0) {
 
270
                (void)net_addr2ip(value, &request->remote_ip);
 
271
                if (request->real_remote_ip.family == 0)
 
272
                        request->real_remote_ip = request->remote_ip;
 
273
        } else if (strcmp(key, "lport") == 0) {
237
274
                request->local_port = atoi(value);
238
 
        else if (strcmp(key, "rport") == 0)
 
275
                if (request->real_local_port == 0)
 
276
                        request->real_local_port = request->local_port;
 
277
        } else if (strcmp(key, "rport") == 0) {
239
278
                request->remote_port = atoi(value);
 
279
                if (request->real_remote_port == 0)
 
280
                        request->real_remote_port = request->remote_port;
 
281
        }
 
282
        else if (strcmp(key, "real_lip") == 0)
 
283
                (void)net_addr2ip(value, &request->real_local_ip);
 
284
        else if (strcmp(key, "real_rip") == 0)
 
285
                (void)net_addr2ip(value, &request->real_remote_ip);
 
286
        else if (strcmp(key, "real_lport") == 0)
 
287
                request->real_local_port = atoi(value);
 
288
        else if (strcmp(key, "real_rport") == 0)
 
289
                request->real_remote_port = atoi(value);
240
290
        else if (strcmp(key, "session") == 0)
241
291
                request->session_id = p_strdup(request->pool, value);
242
292
        else
272
322
        return TRUE;
273
323
}
274
324
 
 
325
bool auth_request_import_master(struct auth_request *request,
 
326
                                const char *key, const char *value)
 
327
{
 
328
        pid_t pid;
 
329
 
 
330
        /* master request lookups may set these */
 
331
        if (strcmp(key, "session_pid") == 0) {
 
332
                if (str_to_pid(value, &pid) == 0)
 
333
                        request->session_pid = pid;
 
334
        } else
 
335
                return FALSE;
 
336
        return TRUE;
 
337
}
 
338
 
275
339
bool auth_request_import(struct auth_request *request,
276
340
                         const char *key, const char *value)
277
341
{
281
345
        /* for communication between auth master and worker processes */
282
346
        if (strcmp(key, "user") == 0)
283
347
                request->user = p_strdup(request->pool, value);
284
 
        else if (strcmp(key, "master_user") == 0)
 
348
        else if (strcmp(key, "master-user") == 0)
285
349
                request->master_user = p_strdup(request->pool, value);
286
 
        else if (strcmp(key, "original_username") == 0)
 
350
        else if (strcmp(key, "original-username") == 0)
287
351
                request->original_username = p_strdup(request->pool, value);
288
 
        else if (strcmp(key, "requested_login_user") == 0)
 
352
        else if (strcmp(key, "requested-login-user") == 0)
289
353
                request->requested_login_user = p_strdup(request->pool, value);
290
 
        else if (strcmp(key, "nologin") == 0)
291
 
                request->no_login = TRUE;
292
354
        else if (strcmp(key, "successful") == 0)
293
355
                request->successful = TRUE;
294
 
        else if (strcmp(key, "skip_password_check") == 0)
 
356
        else if (strcmp(key, "skip-password-check") == 0)
295
357
                request->skip_password_check = TRUE;
296
358
        else if (strcmp(key, "mech") == 0)
297
359
                request->mech_name = p_strdup(request->pool, value);
316
378
        i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
317
379
 
318
380
        if (request->successful) {
319
 
                auth_request_success(request, NULL, 0);
 
381
                auth_request_success(request, "", 0);
320
382
                return;
321
383
        }
322
384
 
328
390
                                    enum passdb_result result)
329
391
{
330
392
        struct passdb_module *passdb = request->passdb->passdb;
331
 
        const char *extra_fields, *encoded_password;
 
393
        const char *encoded_password;
332
394
        string_t *str;
333
395
 
334
396
        switch (result) {
347
409
                i_unreached();
348
410
        }
349
411
 
350
 
        extra_fields = request->extra_fields == NULL ? NULL :
351
 
                auth_stream_reply_export(request->extra_fields);
352
 
 
353
412
        if (passdb_cache == NULL || passdb->cache_key == NULL ||
354
413
            request->master_user != NULL)
355
414
                return;
363
422
                return;
364
423
        }
365
424
 
366
 
        if (!request->no_password && request->passdb_password == NULL) {
 
425
        if (request->passdb_password == NULL &&
 
426
            !auth_fields_exists(request->extra_fields, "nopassword")) {
367
427
                /* passdb didn't provide the correct password */
368
428
                if (result != PASSDB_RESULT_OK ||
369
429
                    request->mech_password == NULL)
398
458
                str_append(str, request->passdb_password);
399
459
        }
400
460
 
401
 
        if (extra_fields != NULL && *extra_fields != '\0') {
 
461
        if (!auth_fields_is_empty(request->extra_fields)) {
402
462
                str_append_c(str, '\t');
403
 
                str_append(str, extra_fields);
404
 
        }
405
 
        if (request->extra_cache_fields != NULL) {
406
 
                extra_fields =
407
 
                        auth_stream_reply_export(request->extra_cache_fields);
408
 
                if (*extra_fields != '\0') {
409
 
                        str_append_c(str, '\t');
410
 
                        str_append(str, extra_fields);
411
 
                }
 
463
                /* add only those extra fields to cache that were set by this
 
464
                   passdb lookup. the CHANGED flag does this, because we
 
465
                   snapshotted the extra_fields before the current passdb
 
466
                   lookup. */
 
467
                auth_fields_append(request->extra_fields, str,
 
468
                                   AUTH_FIELD_FLAG_CHANGED,
 
469
                                   AUTH_FIELD_FLAG_CHANGED);
412
470
        }
413
471
        auth_cache_insert(passdb_cache, request, passdb->cache_key, str_c(str),
414
472
                          result == PASSDB_RESULT_OK);
415
473
}
416
474
 
417
 
static void auth_request_userdb_reply_update_user(struct auth_request *request)
418
 
{
419
 
        const char *str, *p;
420
 
 
421
 
        str = t_strdup(auth_stream_reply_export(request->userdb_reply));
422
 
 
423
 
        /* reset the reply and add the new username */
424
 
        auth_stream_reply_reset(request->userdb_reply);
425
 
        auth_stream_reply_add(request->userdb_reply, NULL, request->user);
426
 
 
427
 
        /* add the rest */
428
 
        p = strchr(str, '\t');
429
 
        if (p != NULL)
430
 
                auth_stream_reply_import(request->userdb_reply, p + 1);
431
 
}
432
 
 
433
 
static bool auth_request_master_lookup_finish(struct auth_request *request)
434
 
{
435
 
        struct auth_passdb *passdb;
436
 
 
437
 
        if (request->passdb_failure)
438
 
                return TRUE;
 
475
static void auth_request_master_lookup_finish(struct auth_request *request)
 
476
{
 
477
        if (request->failed)
 
478
                return;
439
479
 
440
480
        /* master login successful. update user and master_user variables. */
441
481
        auth_request_log_info(request, "passdb", "Master user logging in as %s",
444
484
        request->master_user = request->user;
445
485
        request->user = request->requested_login_user;
446
486
        request->requested_login_user = NULL;
447
 
        if (request->userdb_reply != NULL)
448
 
                auth_request_userdb_reply_update_user(request);
449
 
 
450
 
        request->skip_password_check = TRUE;
451
 
        request->passdb_password = NULL;
452
 
 
453
 
        if (!request->passdb->set->pass) {
454
 
                /* skip the passdb lookup, we're authenticated now. */
455
 
                return TRUE;
456
 
        }
457
 
 
458
 
        /* the authentication continues with passdb lookup for the
459
 
           requested_login_user. */
460
 
        request->passdb = auth_request_get_auth(request)->passdbs;
461
 
 
462
 
        for (passdb = request->passdb; passdb != NULL; passdb = passdb->next) {
463
 
                if (passdb->passdb->iface.lookup_credentials != NULL)
464
 
                        break;
465
 
        }
466
 
        if (passdb == NULL) {
467
 
                auth_request_log_error(request, "passdb",
468
 
                        "No passdbs support skipping password verification - "
469
 
                        "pass=yes can't be used in master passdb");
470
 
        }
471
 
        return FALSE;
 
487
}
 
488
 
 
489
static bool
 
490
auth_request_want_skip_passdb(struct auth_request *request,
 
491
                              struct auth_passdb *passdb)
 
492
{
 
493
        /* skip_password_check basically specifies if authentication is
 
494
           finished */
 
495
        bool authenticated = request->skip_password_check;
 
496
 
 
497
        switch (passdb->skip) {
 
498
        case AUTH_PASSDB_SKIP_NEVER:
 
499
                return FALSE;
 
500
        case AUTH_PASSDB_SKIP_AUTHENTICATED:
 
501
                return authenticated;
 
502
        case AUTH_PASSDB_SKIP_UNAUTHENTICATED:
 
503
                return !authenticated;
 
504
        }
 
505
        i_unreached();
472
506
}
473
507
 
474
508
static bool
475
509
auth_request_handle_passdb_callback(enum passdb_result *result,
476
510
                                    struct auth_request *request)
477
511
{
 
512
        struct auth_passdb *next_passdb;
 
513
        enum auth_passdb_rule result_rule;
 
514
        bool passdb_continue = FALSE;
 
515
 
478
516
        if (request->passdb_password != NULL) {
479
517
                safe_memset(request->passdb_password, 0,
480
518
                            strlen(request->passdb_password));
490
528
                                              "User found from deny passdb");
491
529
                        *result = PASSDB_RESULT_USER_DISABLED;
492
530
                }
493
 
        } else if (*result == PASSDB_RESULT_OK) {
494
 
                /* success */
495
 
                if (request->requested_login_user != NULL) {
496
 
                        /* this was a master user lookup. */
497
 
                        if (!auth_request_master_lookup_finish(request))
498
 
                                return FALSE;
499
 
                } else {
500
 
                        if (request->passdb->set->pass) {
501
 
                                /* this wasn't the final passdb lookup,
502
 
                                   continue to next passdb */
503
 
                                request->passdb = request->passdb->next;
504
 
                                request->passdb_password = NULL;
505
 
                                return FALSE;
506
 
                        }
507
 
                }
508
 
        } else if (*result == PASSDB_RESULT_PASS_EXPIRED) {
509
 
                if (request->extra_fields == NULL) {
510
 
                        request->extra_fields =
511
 
                                auth_stream_reply_init(request->pool);
512
 
                }
513
 
                auth_stream_reply_add(request->extra_fields, "reason",
514
 
                                      "Password expired");
515
 
        } else if (request->passdb->next != NULL &&
516
 
                   *result != PASSDB_RESULT_USER_DISABLED) {
 
531
                return TRUE;
 
532
        }
 
533
 
 
534
        /* users that exist but can't log in are special. we don't try to match
 
535
           any of the success/failure rules to them. they'll always fail. */
 
536
        switch (*result) {
 
537
        case PASSDB_RESULT_USER_DISABLED:
 
538
                return TRUE;
 
539
        case PASSDB_RESULT_PASS_EXPIRED:
 
540
                auth_request_set_field(request, "reason",
 
541
                                       "Password expired", NULL);
 
542
                return TRUE;
 
543
 
 
544
        case PASSDB_RESULT_OK:
 
545
                result_rule = request->passdb->result_success;
 
546
                break;
 
547
        case PASSDB_RESULT_INTERNAL_FAILURE:
 
548
                result_rule = request->passdb->result_internalfail;
 
549
                break;
 
550
        case PASSDB_RESULT_SCHEME_NOT_AVAILABLE:
 
551
        case PASSDB_RESULT_USER_UNKNOWN:
 
552
        case PASSDB_RESULT_PASSWORD_MISMATCH:
 
553
        default:
 
554
                result_rule = request->passdb->result_failure;
 
555
                break;
 
556
        }
 
557
 
 
558
        switch (result_rule) {
 
559
        case AUTH_PASSDB_RULE_RETURN:
 
560
                break;
 
561
        case AUTH_PASSDB_RULE_RETURN_OK:
 
562
                request->passdb_success = TRUE;
 
563
                break;
 
564
        case AUTH_PASSDB_RULE_RETURN_FAIL:
 
565
                request->passdb_success = FALSE;
 
566
                break;
 
567
        case AUTH_PASSDB_RULE_CONTINUE:
 
568
                passdb_continue = TRUE;
 
569
                break;
 
570
        case AUTH_PASSDB_RULE_CONTINUE_OK:
 
571
                passdb_continue = TRUE;
 
572
                request->passdb_success = TRUE;
 
573
                break;
 
574
        case AUTH_PASSDB_RULE_CONTINUE_FAIL:
 
575
                passdb_continue = TRUE;
 
576
                request->passdb_success = FALSE;
 
577
                break;
 
578
        }
 
579
 
 
580
        if (*result == PASSDB_RESULT_OK && passdb_continue) {
 
581
                /* password was successfully verified. don't bother
 
582
                   checking it again. */
 
583
                request->skip_password_check = TRUE;
 
584
        }
 
585
 
 
586
        if (request->requested_login_user != NULL &&
 
587
            *result == PASSDB_RESULT_OK) {
 
588
                auth_request_master_lookup_finish(request);
 
589
                /* if the passdb lookup continues, it continues with non-master
 
590
                   passdbs for the requested_login_user. */
 
591
                next_passdb = auth_request_get_auth(request)->passdbs;
 
592
        } else {
 
593
                next_passdb = request->passdb->next;
 
594
        }
 
595
        while (next_passdb != NULL &&
 
596
               auth_request_want_skip_passdb(request, next_passdb))
 
597
                next_passdb = next_passdb->next;
 
598
 
 
599
        if (passdb_continue && next_passdb != NULL) {
517
600
                /* try next passdb. */
518
 
                request->passdb = request->passdb->next;
 
601
                request->passdb = next_passdb;
519
602
                request->passdb_password = NULL;
520
603
 
521
 
                request->proxy = FALSE;
522
 
                request->proxy_maybe = FALSE;
523
 
                request->proxy_always = FALSE;
 
604
                if (*result == PASSDB_RESULT_OK) {
 
605
                        /* this passdb lookup succeeded, preserve its extra
 
606
                           fields */
 
607
                        auth_fields_snapshot(request->extra_fields);
 
608
                        request->snapshot_has_userdb_reply =
 
609
                                request->userdb_reply != NULL;
 
610
                        if (request->userdb_reply != NULL)
 
611
                                auth_fields_snapshot(request->userdb_reply);
 
612
                } else {
 
613
                        /* this passdb lookup failed, remove any extra fields
 
614
                           it set */
 
615
                        auth_fields_rollback(request->extra_fields);
 
616
                        if (request->userdb_reply == NULL)
 
617
                                ;
 
618
                        else if (!request->snapshot_has_userdb_reply)
 
619
                                request->userdb_reply = NULL;
 
620
                        else
 
621
                                auth_fields_rollback(request->userdb_reply);
 
622
                }
524
623
 
525
624
                if (*result == PASSDB_RESULT_USER_UNKNOWN) {
526
625
                        /* remember that we did at least one successful
527
626
                           passdb lookup */
528
 
                        request->passdb_user_unknown = TRUE;
 
627
                        request->passdbs_seen_user_unknown = TRUE;
529
628
                } else if (*result == PASSDB_RESULT_INTERNAL_FAILURE) {
530
629
                        /* remember that we have had an internal failure. at
531
630
                           the end return internal failure if we couldn't
532
631
                           successfully login. */
533
 
                        request->passdb_internal_failure = TRUE;
 
632
                        request->passdbs_seen_internal_failure = TRUE;
534
633
                }
535
 
                if (request->extra_fields != NULL)
536
 
                        auth_stream_reply_reset(request->extra_fields);
537
 
 
538
634
                return FALSE;
539
 
        } else if (request->passdb_internal_failure) {
 
635
        } else if (request->passdbs_seen_internal_failure) {
540
636
                /* last passdb lookup returned internal failure. it may have
541
637
                   had the correct password, so return internal failure
542
638
                   instead of plain failure. */
543
639
                *result = PASSDB_RESULT_INTERNAL_FAILURE;
 
640
        } else if (request->passdb_success) {
 
641
                /* either this or a previous passdb lookup succeeded. */
 
642
                *result = PASSDB_RESULT_OK;
544
643
        }
545
 
 
546
644
        return TRUE;
547
645
}
548
646
 
694
792
                                binary_to_hex(credentials, size));
695
793
                }
696
794
                if (result == PASSDB_RESULT_SCHEME_NOT_AVAILABLE &&
697
 
                    request->passdb_user_unknown) {
 
795
                    request->passdbs_seen_user_unknown) {
698
796
                        /* one of the passdbs accepted the scheme,
699
797
                           but the user was unknown there */
700
798
                        result = PASSDB_RESULT_USER_UNKNOWN;
782
880
                auth_request_log_debug(request, "password",
783
881
                        "passdb doesn't support credential lookups");
784
882
                auth_request_lookup_credentials_callback(
785
 
                        PASSDB_RESULT_SCHEME_NOT_AVAILABLE, NULL, 0, request);
 
883
                                        PASSDB_RESULT_SCHEME_NOT_AVAILABLE,
 
884
                                        &uchar_nul, 0, request);
786
885
        } else if (passdb->blocking) {
787
886
                passdb_blocking_lookup_credentials(request);
788
887
        } else {
821
920
                                           enum userdb_result result)
822
921
{
823
922
        struct userdb_module *userdb = request->userdb->userdb;
824
 
        const char *str;
 
923
        string_t *str;
 
924
        const char *cache_value;
825
925
 
826
926
        if (passdb_cache == NULL || userdb->cache_key == NULL ||
827
927
            request->master_user != NULL)
828
928
                return;
829
929
 
830
 
        str = result == USERDB_RESULT_USER_UNKNOWN ? "" :
831
 
                auth_stream_reply_export(request->userdb_reply);
 
930
        if (result == USERDB_RESULT_USER_UNKNOWN)
 
931
                cache_value = "";
 
932
        else {
 
933
                str = t_str_new(128);
 
934
                auth_fields_append(request->userdb_reply, str,
 
935
                                   AUTH_FIELD_FLAG_CHANGED,
 
936
                                   AUTH_FIELD_FLAG_CHANGED);
 
937
                if (str_len(str) == 0) {
 
938
                        /* no userdb fields. but we can't save an empty string,
 
939
                           since that means "user unknown". */
 
940
                        str_append(str, AUTH_REQUEST_USER_KEY_IGNORE);
 
941
                }
 
942
                cache_value = str_c(str);
 
943
        }
832
944
        /* last_success has no meaning with userdb */
833
 
        auth_cache_insert(passdb_cache, request, userdb->cache_key, str, FALSE);
 
945
        auth_cache_insert(passdb_cache, request, userdb->cache_key,
 
946
                          cache_value, FALSE);
834
947
}
835
948
 
836
949
static bool auth_request_lookup_user_cache(struct auth_request *request,
837
950
                                           const char *key,
838
 
                                           struct auth_stream_reply **reply_r,
 
951
                                           struct auth_fields **reply_r,
839
952
                                           enum userdb_result *result_r,
840
953
                                           bool use_expired)
841
954
{
858
971
        if (*value == '\0') {
859
972
                /* negative cache entry */
860
973
                *result_r = USERDB_RESULT_USER_UNKNOWN;
861
 
                *reply_r = auth_stream_reply_init(request->pool);
 
974
                *reply_r = auth_fields_init(request->pool);
862
975
                return TRUE;
863
976
        }
864
977
 
865
978
        *result_r = USERDB_RESULT_OK;
866
 
        *reply_r = auth_stream_reply_init_userdb(request->pool);
867
 
        auth_stream_reply_import(*reply_r, value);
 
979
        *reply_r = auth_fields_init(request->pool);
 
980
        auth_fields_import(*reply_r, value, 0);
868
981
        return TRUE;
869
982
}
870
983
 
876
989
        if (result != USERDB_RESULT_OK && request->userdb->next != NULL) {
877
990
                /* try next userdb. */
878
991
                if (result == USERDB_RESULT_INTERNAL_FAILURE)
879
 
                        request->userdb_internal_failure = TRUE;
 
992
                        request->userdbs_seen_internal_failure = TRUE;
880
993
 
881
994
                request->userdb = request->userdb->next;
882
995
                auth_request_lookup_user(request,
886
999
 
887
1000
        if (result == USERDB_RESULT_OK)
888
1001
                userdb_template_export(userdb->override_fields_tmpl, request);
889
 
        else if (request->userdb_internal_failure) {
 
1002
        else if (request->userdbs_seen_internal_failure) {
890
1003
                /* one of the userdb lookups failed. the user might have been
891
1004
                   in there, so this is an internal failure */
892
1005
                result = USERDB_RESULT_INTERNAL_FAILURE;
913
1026
                   request was expired in cache, fallback to using cached
914
1027
                   expired record. */
915
1028
                const char *cache_key = userdb->cache_key;
916
 
                struct auth_stream_reply *reply;
 
1029
                struct auth_fields *reply;
917
1030
 
918
1031
                if (auth_request_lookup_user_cache(request, cache_key, &reply,
919
1032
                                                   &result, TRUE)) {
938
1051
        /* (for now) auth_cache is shared between passdb and userdb */
939
1052
        cache_key = passdb_cache == NULL ? NULL : userdb->cache_key;
940
1053
        if (cache_key != NULL) {
941
 
                struct auth_stream_reply *reply;
 
1054
                struct auth_fields *reply;
942
1055
                enum userdb_result result;
943
1056
 
944
1057
                if (auth_request_lookup_user_cache(request, cache_key, &reply,
1105
1218
                /* IP not known */
1106
1219
                auth_request_log_info(request, "passdb",
1107
1220
                        "allow_nets check failed: Remote IP not known");
1108
 
                request->passdb_failure = TRUE;
 
1221
                request->failed = TRUE;
1109
1222
                return;
1110
1223
        }
1111
1224
 
1128
1241
                auth_request_log_info(request, "passdb",
1129
1242
                        "allow_nets check failed: IP not in allowed networks");
1130
1243
        }
1131
 
        request->passdb_failure = !found;
 
1244
        request->failed = !found;
1132
1245
}
1133
1246
 
1134
1247
static void
1156
1269
        }
1157
1270
}
1158
1271
 
1159
 
static void auth_request_set_reply_field(struct auth_request *request,
1160
 
                                         const char *name, const char *value)
1161
 
{
1162
 
        if (strcmp(name, "nologin") == 0) {
1163
 
                /* user can't actually login - don't keep this
1164
 
                   reply for master */
1165
 
                request->no_login = TRUE;
1166
 
                value = NULL;
1167
 
        } else if (strcmp(name, "proxy") == 0) {
1168
 
                /* we're proxying authentication for this user. send
1169
 
                   password back if using plaintext authentication. */
1170
 
                request->proxy = TRUE;
1171
 
                value = NULL;
1172
 
        } else if (strcmp(name, "proxy_always") == 0) {
1173
 
                /* when proxy_maybe=yes and proxying wouldn't normally be done,
1174
 
                   with this enabled proxy=y is still returned without host.
1175
 
                   this can be used to make director set the host. */
1176
 
                request->proxy_always = TRUE;
1177
 
                value = NULL;
1178
 
        } else if (strcmp(name, "proxy_maybe") == 0) {
1179
 
                /* like "proxy", but log in normally if we're proxying to
1180
 
                   ourself */
1181
 
                request->proxy = TRUE;
1182
 
                request->proxy_maybe = TRUE;
1183
 
                value = NULL;
1184
 
        }
1185
 
 
1186
 
        if (request->extra_fields == NULL)
1187
 
                request->extra_fields = auth_stream_reply_init(request->pool);
1188
 
        auth_stream_reply_remove(request->extra_fields, name);
1189
 
        auth_stream_reply_add(request->extra_fields, name, value);
1190
 
}
1191
 
 
1192
1272
static const char *
1193
1273
get_updated_username(const char *old_username,
1194
1274
                     const char *name, const char *value)
1237
1317
                                       "username changed %s -> %s",
1238
1318
                                       request->user, new_value);
1239
1319
                request->user = p_strdup(request->pool, new_value);
1240
 
                if (request->userdb_reply != NULL)
1241
 
                        auth_request_userdb_reply_update_user(request);
1242
1320
        }
1243
1321
        return TRUE;
1244
1322
}
1277
1355
        if (auth_request_try_update_username(request, name, value)) {
1278
1356
                /* don't change the original value so it gets saved correctly
1279
1357
                   to cache. */
1280
 
        } else if (strcmp(name, "nodelay") == 0) {
1281
 
                /* don't delay replying to client of the failure */
1282
 
                request->no_failure_delay = TRUE;
 
1358
        } else if (strcmp(name, "allow_nets") == 0) {
 
1359
                auth_request_validate_networks(request, value);
 
1360
        } else if (strncmp(name, "userdb_", 7) == 0) {
 
1361
                /* for prefetch userdb */
 
1362
                if (request->userdb_reply == NULL)
 
1363
                        auth_request_init_userdb_reply(request);
 
1364
                auth_request_set_userdb_field(request, name + 7, value);
1283
1365
        } else if (strcmp(name, "nopassword") == 0) {
1284
1366
                /* NULL password - anything goes */
1285
1367
                const char *password = request->passdb_password;
1294
1376
                                return;
1295
1377
                        }
1296
1378
                }
1297
 
                request->no_password = TRUE;
1298
1379
                request->passdb_password = NULL;
1299
 
        } else if (strcmp(name, "allow_nets") == 0) {
1300
 
                auth_request_validate_networks(request, value);
 
1380
                auth_fields_add(request->extra_fields, name, value, 0);
 
1381
                return;
1301
1382
        } else if (strcmp(name, "passdb_import") == 0) {
1302
1383
                auth_request_passdb_import(request, value, "", default_scheme);
1303
1384
                return;
1304
 
        } else if (strncmp(name, "userdb_", 7) == 0) {
1305
 
                /* for prefetch userdb */
1306
1385
                if (strcmp(name, "userdb_userdb_import") == 0) {
1307
1386
                        /* we need can't put the whole userdb_userdb_import
1308
1387
                           value to extra_cache_fields or it doesn't work
1311
1390
                                                   "userdb_", default_scheme);
1312
1391
                        return;
1313
1392
                }
1314
 
                if (request->userdb_reply == NULL)
1315
 
                        auth_request_init_userdb_reply(request);
1316
 
                auth_request_set_userdb_field(request, name + 7, value);
1317
1393
        } else {
1318
1394
                /* these fields are returned to client */
1319
 
                auth_request_set_reply_field(request, name, value);
 
1395
                auth_fields_add(request->extra_fields, name, value, 0);
1320
1396
                return;
1321
1397
        }
1322
1398
 
1325
1401
                /* we'll need to get this field stored into cache,
1326
1402
                   or we're a worker and we'll need to send this to the main
1327
1403
                   auth process that can store it in the cache. */
1328
 
                if (request->extra_cache_fields == NULL) {
1329
 
                        request->extra_cache_fields =
1330
 
                                auth_stream_reply_init(request->pool);
1331
 
                }
1332
 
                auth_stream_reply_add(request->extra_cache_fields, name, value);
 
1404
                auth_fields_add(request->extra_fields, name, value,
 
1405
                                AUTH_FIELD_FLAG_HIDDEN);
 
1406
        }
 
1407
}
 
1408
 
 
1409
void auth_request_set_null_field(struct auth_request *request, const char *name)
 
1410
{
 
1411
        if (strncmp(name, "userdb_", 7) == 0) {
 
1412
                /* make sure userdb prefetch is used even if all the fields
 
1413
                   were returned as NULL. */
 
1414
                if (request->userdb_reply == NULL)
 
1415
                        auth_request_init_userdb_reply(request);
1333
1416
        }
1334
1417
}
1335
1418
 
1365
1448
{
1366
1449
        struct userdb_module *module = request->userdb->userdb;
1367
1450
 
1368
 
        request->userdb_reply = auth_stream_reply_init_userdb(request->pool);
1369
 
        auth_stream_reply_add(request->userdb_reply, NULL, request->user);
1370
 
 
 
1451
        request->userdb_reply = auth_fields_init(request->pool);
1371
1452
        userdb_template_export(module->default_fields_tmpl, request);
1372
1453
}
1373
1454
 
1384
1465
                auth_request_log_error(request, "uidgid_file",
1385
1466
                                       "stat(%s) failed: %m", str_c(path));
1386
1467
        } else {
1387
 
                auth_stream_reply_add(request->userdb_reply,
1388
 
                                      "uid", dec2str(st.st_uid));
1389
 
                auth_stream_reply_add(request->userdb_reply,
1390
 
                                      "gid", dec2str(st.st_gid));
 
1468
                auth_fields_add(request->userdb_reply,
 
1469
                                "uid", dec2str(st.st_uid), 0);
 
1470
                auth_fields_add(request->userdb_reply,
 
1471
                                "gid", dec2str(st.st_gid), 0);
1391
1472
        }
1392
1473
}
1393
1474
 
1448
1529
                        warned = TRUE;
1449
1530
                }
1450
1531
                name = "system_groups_user";
 
1532
        } else if (strcmp(name, AUTH_REQUEST_USER_KEY_IGNORE) == 0) {
 
1533
                return;
1451
1534
        }
1452
1535
 
1453
 
        auth_stream_reply_remove(request->userdb_reply, name);
1454
 
        auth_stream_reply_add(request->userdb_reply, name, value);
 
1536
        auth_fields_add(request->userdb_reply, name, value, 0);
1455
1537
}
1456
1538
 
1457
1539
void auth_request_set_userdb_field_values(struct auth_request *request,
1478
1560
                                str_append_c(value, ',');
1479
1561
                        str_append(value, dec2str(gid));
1480
1562
                }
1481
 
                auth_stream_reply_add(request->userdb_reply, name,
1482
 
                                      str_c(value));
 
1563
                auth_fields_add(request->userdb_reply, name, str_c(value), 0);
1483
1564
        } else {
1484
1565
                /* add only one */
1485
1566
                if (values[1] != NULL) {
1493
1574
 
1494
1575
static bool auth_request_proxy_is_self(struct auth_request *request)
1495
1576
{
1496
 
        const char *const *tmp, *port = NULL, *destuser = NULL;
1497
 
 
1498
 
        if (!request->proxy_host_is_self)
1499
 
                return FALSE;
1500
 
 
1501
 
        tmp = auth_stream_split(request->extra_fields);
1502
 
        for (; *tmp != NULL; tmp++) {
1503
 
                if (strncmp(*tmp, "port=", 5) == 0)
1504
 
                        port = *tmp + 5;
1505
 
                else if (strncmp(*tmp, "destuser=", 9) == 0)
1506
 
                        destuser = *tmp + 9;
1507
 
        }
1508
 
 
 
1577
        const char *port = NULL;
 
1578
 
 
1579
        /* check if the port is the same */
 
1580
        port = auth_fields_find(request->extra_fields, "port");
1509
1581
        if (port != NULL && !str_uint_equals(port, request->local_port))
1510
1582
                return FALSE;
1511
 
        return destuser == NULL ||
1512
 
                strcmp(destuser, request->original_username) == 0;
 
1583
        /* don't check destuser. in some systems destuser is intentionally
 
1584
           changed to proxied connections, but that shouldn't affect the
 
1585
           proxying decision.
 
1586
 
 
1587
           it's unlikely any systems would actually want to proxy a connection
 
1588
           to itself only to change the username, since it can already be done
 
1589
           without proxying by changing the "user" field. */
 
1590
        return TRUE;
1513
1591
}
1514
1592
 
1515
1593
static bool
1518
1596
{
1519
1597
        unsigned int i;
1520
1598
 
1521
 
        if (net_ip_compare(ip, &request->local_ip))
 
1599
        if (net_ip_compare(ip, &request->real_local_ip))
1522
1600
                return TRUE;
1523
1601
 
1524
1602
        for (i = 0; request->set->proxy_self_ips[i].family != 0; i++) {
1528
1606
        return FALSE;
1529
1607
}
1530
1608
 
1531
 
static void auth_request_proxy_finish_ip(struct auth_request *request)
 
1609
static void
 
1610
auth_request_proxy_finish_ip(struct auth_request *request,
 
1611
                             bool proxy_host_is_self)
1532
1612
{
1533
 
        if (!request->proxy_maybe) {
 
1613
        if (!auth_fields_exists(request->extra_fields, "proxy_maybe")) {
1534
1614
                /* proxying */
1535
 
                request->no_login = TRUE;
1536
 
        } else if (!auth_request_proxy_is_self(request)) {
 
1615
        } else if (!proxy_host_is_self ||
 
1616
                   !auth_request_proxy_is_self(request)) {
1537
1617
                /* proxy destination isn't ourself - proxy */
1538
 
                auth_stream_reply_remove(request->extra_fields, "proxy_maybe");
1539
 
                auth_stream_reply_add(request->extra_fields, "proxy", NULL);
1540
 
                request->no_login = TRUE;
 
1618
                auth_fields_remove(request->extra_fields, "proxy_maybe");
 
1619
                auth_fields_add(request->extra_fields, "proxy", NULL, 0);
1541
1620
        } else {
1542
1621
                /* proxying to ourself - log in without proxying by dropping
1543
1622
                   all the proxying fields. */
1544
 
                bool proxy_always = request->proxy_always;
 
1623
                bool proxy_always = auth_fields_exists(request->extra_fields,
 
1624
                                                       "proxy_always");
1545
1625
 
1546
1626
                auth_request_proxy_finish_failure(request);
1547
1627
                if (proxy_always) {
1548
 
                        /* director adds the host */
1549
 
                        auth_stream_reply_add(request->extra_fields,
1550
 
                                              "proxy", NULL);
1551
 
                        request->proxy = TRUE;
 
1628
                        /* setup where "self" refers to the local director
 
1629
                           cluster, while "non-self" refers to remote clusters.
 
1630
 
 
1631
                           we've matched self here, so add proxy field and
 
1632
                           let director fill the host. */
 
1633
                        auth_fields_add(request->extra_fields,
 
1634
                                        "proxy", NULL, 0);
1552
1635
                }
1553
1636
        }
1554
1637
}
1555
1638
 
1556
 
struct auth_request_proxy_dns_lookup_ctx {
1557
 
        struct auth_request *request;
1558
 
        auth_request_proxy_cb_t *callback;
1559
 
};
1560
 
 
1561
1639
static void
1562
1640
auth_request_proxy_dns_callback(const struct dns_lookup_result *result,
1563
 
                                void *context)
 
1641
                                struct auth_request_proxy_dns_lookup_ctx *ctx)
1564
1642
{
1565
 
        struct auth_request_proxy_dns_lookup_ctx *ctx = context;
1566
1643
        struct auth_request *request = ctx->request;
1567
1644
        const char *host;
1568
1645
        unsigned int i;
1569
 
 
1570
 
        host = auth_stream_reply_find(request->extra_fields, "host");
 
1646
        bool proxy_host_is_self;
 
1647
 
 
1648
        request->dns_lookup_ctx = NULL;
 
1649
        ctx->dns_lookup = NULL;
 
1650
 
 
1651
        host = auth_fields_find(request->extra_fields, "host");
1571
1652
        i_assert(host != NULL);
1572
1653
 
1573
1654
        if (result->ret != 0) {
1581
1662
                                "DNS lookup for %s took %u.%03u s",
1582
1663
                                host, result->msecs/1000, result->msecs % 1000);
1583
1664
                }
1584
 
                auth_stream_reply_remove(request->extra_fields, "hostip");
1585
 
                auth_stream_reply_add(request->extra_fields, "hostip",
1586
 
                                      net_ip2addr(&result->ips[0]));
 
1665
                auth_fields_add(request->extra_fields, "hostip",
 
1666
                                net_ip2addr(&result->ips[0]), 0);
 
1667
                proxy_host_is_self = FALSE;
1587
1668
                for (i = 0; i < result->ips_count; i++) {
1588
1669
                        if (auth_request_proxy_ip_is_self(request,
1589
1670
                                                          &result->ips[i])) {
1590
 
                                request->proxy_host_is_self = TRUE;
 
1671
                                proxy_host_is_self = TRUE;
1591
1672
                                break;
1592
1673
                        }
1593
1674
                }
1594
 
                auth_request_proxy_finish_ip(request);
 
1675
                auth_request_proxy_finish_ip(request, proxy_host_is_self);
1595
1676
        }
1596
1677
        if (ctx->callback != NULL)
1597
1678
                ctx->callback(result->ret == 0, request);
1598
1679
        auth_request_unref(&request);
1599
 
        i_free(ctx);
1600
1680
}
1601
1681
 
1602
1682
static int auth_request_proxy_host_lookup(struct auth_request *request,
 
1683
                                          const char *host,
1603
1684
                                          auth_request_proxy_cb_t *callback)
1604
1685
{
1605
1686
        struct auth_request_proxy_dns_lookup_ctx *ctx;
1606
1687
        struct dns_lookup_settings dns_set;
1607
 
        const char *host, *value;
1608
 
        struct ip_addr ip;
 
1688
        const char *value;
1609
1689
        unsigned int secs;
1610
1690
 
1611
 
        host = auth_stream_reply_find(request->extra_fields, "host");
1612
 
        if (host == NULL)
1613
 
                return 1;
1614
 
        if (net_addr2ip(host, &ip) == 0) {
1615
 
                if (auth_request_proxy_ip_is_self(request, &ip))
1616
 
                        request->proxy_host_is_self = TRUE;
1617
 
                return 1;
1618
 
        }
1619
 
 
1620
1691
        /* need to do dns lookup for the host */
1621
1692
        memset(&dns_set, 0, sizeof(dns_set));
1622
1693
        dns_set.dns_client_socket_path = AUTH_DNS_SOCKET_PATH;
1623
1694
        dns_set.timeout_msecs = AUTH_DNS_DEFAULT_TIMEOUT_MSECS;
1624
 
        value = auth_stream_reply_find(request->extra_fields, "proxy_timeout");
 
1695
        value = auth_fields_find(request->extra_fields, "proxy_timeout");
1625
1696
        if (value != NULL) {
1626
1697
                if (str_to_uint(value, &secs) < 0) {
1627
1698
                        auth_request_log_error(request, "proxy",
1631
1702
                }
1632
1703
        }
1633
1704
 
1634
 
        ctx = i_new(struct auth_request_proxy_dns_lookup_ctx, 1);
 
1705
        ctx = p_new(request->pool, struct auth_request_proxy_dns_lookup_ctx, 1);
1635
1706
        ctx->request = request;
1636
1707
        auth_request_ref(request);
1637
1708
 
1638
 
        if (dns_lookup(host, &dns_set, auth_request_proxy_dns_callback, ctx) < 0) {
 
1709
        if (dns_lookup(host, &dns_set, auth_request_proxy_dns_callback, ctx,
 
1710
                       &ctx->dns_lookup) < 0) {
1639
1711
                /* failed early */
1640
1712
                return -1;
1641
1713
        }
1646
1718
int auth_request_proxy_finish(struct auth_request *request,
1647
1719
                              auth_request_proxy_cb_t *callback)
1648
1720
{
1649
 
        int ret;
1650
 
 
1651
 
        if (!request->proxy)
1652
 
                return 1;
1653
 
 
1654
 
        if ((ret = auth_request_proxy_host_lookup(request, callback)) <= 0)
1655
 
                return ret;
1656
 
 
1657
 
        auth_request_proxy_finish_ip(request);
 
1721
        const char *host;
 
1722
        struct ip_addr ip;
 
1723
        bool proxy_host_is_self;
 
1724
 
 
1725
        if (request->auth_only)
 
1726
                return 1;
 
1727
        if (!auth_fields_exists(request->extra_fields, "proxy") &&
 
1728
            !auth_fields_exists(request->extra_fields, "proxy_maybe"))
 
1729
                return 1;
 
1730
 
 
1731
        host = auth_fields_find(request->extra_fields, "host");
 
1732
        if (host == NULL) {
 
1733
                /* director can set the host */
 
1734
                proxy_host_is_self = FALSE;
 
1735
        } else if (net_addr2ip(host, &ip) == 0) {
 
1736
                proxy_host_is_self =
 
1737
                        auth_request_proxy_ip_is_self(request, &ip);
 
1738
        } else {
 
1739
                /* asynchronous host lookup */
 
1740
                return auth_request_proxy_host_lookup(request, host, callback);
 
1741
        }
 
1742
 
 
1743
        auth_request_proxy_finish_ip(request, proxy_host_is_self);
1658
1744
        return 1;
1659
1745
}
1660
1746
 
1661
1747
void auth_request_proxy_finish_failure(struct auth_request *request)
1662
1748
{
1663
 
        if (!request->proxy)
1664
 
                return;
1665
 
 
1666
1749
        /* drop all proxying fields */
1667
 
        auth_stream_reply_remove(request->extra_fields, "proxy");
1668
 
        auth_stream_reply_remove(request->extra_fields, "proxy_maybe");
1669
 
        auth_stream_reply_remove(request->extra_fields, "host");
1670
 
        auth_stream_reply_remove(request->extra_fields, "port");
1671
 
        auth_stream_reply_remove(request->extra_fields, "destuser");
1672
 
 
1673
 
        request->proxy = FALSE;
1674
 
        request->proxy_maybe = FALSE;
1675
 
        request->proxy_always = FALSE;
 
1750
        auth_fields_remove(request->extra_fields, "proxy");
 
1751
        auth_fields_remove(request->extra_fields, "proxy_maybe");
 
1752
        auth_fields_remove(request->extra_fields, "proxy_always");
 
1753
        auth_fields_remove(request->extra_fields, "host");
 
1754
        auth_fields_remove(request->extra_fields, "port");
 
1755
        auth_fields_remove(request->extra_fields, "destuser");
1676
1756
}
1677
1757
 
1678
1758
static void log_password_failure(struct auth_request *request,
1745
1825
        int ret;
1746
1826
 
1747
1827
        if (request->skip_password_check) {
1748
 
                /* currently this can happen only with master logins */
 
1828
                /* passdb continue* rule after a successful authentication */
1749
1829
                return 1;
1750
1830
        }
1751
1831
 
1754
1834
                return 0;
1755
1835
        }
1756
1836
 
1757
 
        if (request->no_password) {
 
1837
        if (auth_fields_exists(request->extra_fields, "nopassword")) {
1758
1838
                auth_request_log_debug(request, subsystem,
1759
1839
                                       "Allowing any password");
1760
1840
                return 1;
1831
1911
        { '\0', NULL, "login_username" },
1832
1912
        { '\0', NULL, "login_domain" },
1833
1913
        { '\0', NULL, "session" },
 
1914
        { '\0', NULL, "real_lip" },
 
1915
        { '\0', NULL, "real_rip" },
 
1916
        { '\0', NULL, "real_lport" },
 
1917
        { '\0', NULL, "real_rport" },
1834
1918
        { '\0', NULL, NULL }
1835
1919
};
1836
1920
 
1901
1985
        }
1902
1986
        tab[18].value = auth_request->session_id == NULL ? NULL :
1903
1987
                escape_func(auth_request->session_id, auth_request);
 
1988
        if (auth_request->real_local_ip.family != 0)
 
1989
                tab[19].value = net_ip2addr(&auth_request->real_local_ip);
 
1990
        if (auth_request->real_remote_ip.family != 0)
 
1991
                tab[20].value = net_ip2addr(&auth_request->real_remote_ip);
 
1992
        tab[21].value = dec2str(auth_request->real_local_port);
 
1993
        tab[22].value = dec2str(auth_request->real_remote_port);
1904
1994
        return ret_tab;
1905
1995
}
1906
1996