Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit419a8dd

Browse files
committed
Add a hook for modifying the ldapbind password
The hook can be installed by a shared_preload library.A similar mechanism could be used for radius paswords, for example, andthe type name auth_password_hook_typ has been shosen with that in mind.John Naylor and Andrew DunstanDiscussion:https://postgr.es/m/469b06ed-69de-ba59-c13a-91d2372e52a9@dunslane.net
1 parente3ac850 commit419a8dd

File tree

8 files changed

+255
-1
lines changed

8 files changed

+255
-1
lines changed

‎src/backend/libpq/auth.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ static intCheckLDAPAuth(Port *port);
144144
#defineLDAP_OPT_DIAGNOSTIC_MESSAGE LDAP_OPT_ERROR_STRING
145145
#endif
146146

147+
/* Default LDAP password mutator hook, can be overridden by a shared library */
148+
staticchar*dummy_ldap_password_mutator(char*input);
149+
auth_password_hook_typldap_password_hook=dummy_ldap_password_mutator;
150+
147151
#endif/* USE_LDAP */
148152

149153
/*----------------------------------------------------------------
@@ -2370,6 +2374,12 @@ InitializeLDAPConnection(Port *port, LDAP **ldap)
23702374
#defineLDAPS_PORT 636
23712375
#endif
23722376

2377+
staticchar*
2378+
dummy_ldap_password_mutator(char*input)
2379+
{
2380+
returninput;
2381+
}
2382+
23732383
/*
23742384
* Return a newly allocated C string copied from "pattern" with all
23752385
* occurrences of the placeholder "$username" replaced with "user_name".
@@ -2498,7 +2508,7 @@ CheckLDAPAuth(Port *port)
24982508
*/
24992509
r=ldap_simple_bind_s(ldap,
25002510
port->hba->ldapbinddn ?port->hba->ldapbinddn :"",
2501-
port->hba->ldapbindpasswd ?port->hba->ldapbindpasswd :"");
2511+
port->hba->ldapbindpasswd ?ldap_password_hook(port->hba->ldapbindpasswd) :"");
25022512
if (r!=LDAP_SUCCESS)
25032513
{
25042514
ereport(LOG,

‎src/include/libpq/auth.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,10 @@ extern void sendAuthRequest(Port *port, AuthRequest areq, const char *extradata,
2828
typedefvoid (*ClientAuthentication_hook_type) (Port*,int);
2929
externPGDLLIMPORTClientAuthentication_hook_typeClientAuthentication_hook;
3030

31+
/* hook type for password manglers */
32+
typedefchar*(*auth_password_hook_typ) (char*input);
33+
34+
/* Default LDAP password mutator hook, can be overridden by a shared library */
35+
externPGDLLIMPORTauth_password_hook_typldap_password_hook;
36+
3137
#endif/* AUTH_H */

‎src/test/modules/Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,16 @@ else
4242
ALWAYS_SUBDIRS += ssl_passphrase_callback
4343
endif
4444

45+
# Test runs an LDAP server, so only run if ldap is in PG_TEST_EXTRA
46+
ifeq ($(with_ldap),yes)
47+
ifneq (,$(filter ldap,$(PG_TEST_EXTRA)))
48+
SUBDIRS += ldap_password_func
49+
else
50+
ALWAYS_SUBDIRS += ldap_password_func
51+
endif
52+
else
53+
ALWAYS_SUBDIRS += ldap_password_func
54+
endif
55+
4556
$(recurse)
4657
$(recurse_always)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright (c) 2022, PostgreSQL Global Development Group
2+
3+
# ldap_password_func Makefile
4+
5+
exportwith_ldap
6+
7+
MODULE_big = ldap_password_func
8+
OBJS = ldap_password_func.o$(WIN32RES)
9+
PGFILEDESC = "set hook to mutate ldapbindpasswd"
10+
11+
TAP_TESTS = 1
12+
13+
ifdefUSE_PGXS
14+
PG_CONFIG = pg_config
15+
PGXS :=$(shell$(PG_CONFIG) --pgxs)
16+
include$(PGXS)
17+
else
18+
subdir = src/test/modules/ldap_password_func
19+
top_builddir = ../../../..
20+
include$(top_builddir)/src/Makefile.global
21+
include$(top_srcdir)/contrib/contrib-global.mk
22+
endif
23+
24+
25+
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* Copyright (c) 2022, PostgreSQL Global Development Group
4+
*
5+
* ldap_password_func.c
6+
*
7+
* Loadable PostgreSQL module to mutate the ldapbindpasswd. This
8+
* implementation just hands back the configured password rot13'd.
9+
*
10+
*-------------------------------------------------------------------------
11+
*/
12+
13+
#include"postgres.h"
14+
15+
#include<float.h>
16+
#include<stdio.h>
17+
18+
#include"libpq/libpq.h"
19+
#include"libpq/libpq-be.h"
20+
#include"libpq/auth.h"
21+
#include"utils/guc.h"
22+
23+
PG_MODULE_MAGIC;
24+
25+
void_PG_init(void);
26+
void_PG_fini(void);
27+
28+
/* hook function */
29+
staticchar*rot13_passphrase(char*password);
30+
31+
/*
32+
* Module load callback
33+
*/
34+
void
35+
_PG_init(void)
36+
{
37+
ldap_password_hook=rot13_passphrase;
38+
}
39+
40+
void
41+
_PG_fini(void)
42+
{
43+
/* do nothing yet */
44+
}
45+
46+
staticchar*
47+
rot13_passphrase(char*pw)
48+
{
49+
size_tsize=strlen(pw)+1;
50+
51+
char*new_pw= (char*)palloc(size);
52+
53+
strlcpy(new_pw,pw,size);
54+
for (char*p=new_pw;*p;p++)
55+
{
56+
charc=*p;
57+
58+
if ((c >='a'&&c <='m')|| (c >='A'&&c <='M'))
59+
*p=c+13;
60+
elseif ((c >='n'&&c <='z')|| (c >='N'&&c <='Z'))
61+
*p=c-13;
62+
}
63+
64+
returnnew_pw;
65+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
ifnot ldap.found()
2+
subdir_done()
3+
endif
4+
5+
ldap_password_func_sources=files(
6+
'ldap_password_func.c',
7+
)
8+
9+
if host_system=='windows'
10+
ldap_password_func_sources+= rc_lib_gen.process(win32ver_rc,extra_args: [
11+
'--NAME','ldap_password_func',
12+
'--FILEDESC','set hook to mutate ldapbindpassw',])
13+
endif
14+
15+
ldap_password_func=shared_module('ldap_password_func',
16+
ldap_password_func_sources,
17+
kwargs: pg_mod_args+ {
18+
'dependencies': [ldap, pg_mod_args['dependencies']],
19+
},
20+
)
21+
test_install_libs+= ldap_password_func
22+
23+
tests+= {
24+
'name':'ldap_password_func',
25+
'sd':meson.current_source_dir(),
26+
'bd':meson.current_build_dir(),
27+
'tap': {
28+
'tests': [
29+
't/001_mutated_bindpasswd.pl',
30+
],
31+
'env': {'with_ldap':'yes'}
32+
},
33+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
2+
# Copyright (c) 2022, PostgreSQL Global Development Group
3+
4+
use strict;
5+
use warnings;
6+
use File::Copy;
7+
use FindBin;
8+
use PostgreSQL::Test::Utils;
9+
use PostgreSQL::Test::Cluster;
10+
use Test::More;
11+
12+
use lib"$FindBin::RealBin/../../../ldap";
13+
use LdapServer;
14+
15+
my ($slapd,$ldap_bin_dir,$ldap_schema_dir);
16+
17+
$ldap_bin_dir =undef;# usually in PATH
18+
19+
if ($ENV{with_ldap}ne'yes')
20+
{
21+
planskip_all=>'LDAP not supported by this build';
22+
}
23+
elsif ($ENV{PG_TEST_EXTRA} !~/\bldap\b/)
24+
{
25+
planskip_all=>
26+
'Potentially unsafe test LDAP not enabled in PG_TEST_EXTRA';
27+
}
28+
elsif (!$LdapServer::setup)
29+
{
30+
planskip_all=>
31+
"ldap tests not supported on $^O or dependencies not installed";
32+
}
33+
34+
my$clear_ldap_rootpw ="FooBaR1";
35+
my$rot13_ldap_rootpw ="SbbOnE1";
36+
37+
my$ldap = LdapServer->new($clear_ldap_rootpw,'users');# no anonymous auth
38+
$ldap->ldapadd_file("$FindBin::RealBin/../../../ldap/authdata.ldif");
39+
$ldap->ldapsetpw('uid=test1,dc=example,dc=net','secret1');
40+
41+
my ($ldap_server,$ldap_port,$ldap_basedn,$ldap_rootdn) =
42+
$ldap->prop(qw(server port basedn rootdn));
43+
44+
45+
note"setting up PostgreSQL instance";
46+
47+
my$node = PostgreSQL::Test::Cluster->new('node');
48+
$node->init;
49+
$node->append_conf('postgresql.conf',"log_connections = on\n");
50+
$node->append_conf('postgresql.conf',"shared_preload_libraries = 'ldap_password_func'");
51+
$node->start;
52+
53+
$node->safe_psql('postgres','CREATE USER test1;');
54+
55+
note"running tests";
56+
57+
subtest_access
58+
{
59+
local$Test::Builder::Level =$Test::Builder::Level + 1;
60+
61+
my ($node,$role,$expected_res,$test_name,%params) =@_;
62+
my$connstr ="user=$role";
63+
64+
if ($expected_reseq 0)
65+
{
66+
$node->connect_ok($connstr,$test_name,%params);
67+
}
68+
else
69+
{
70+
# No checks of the error message, only the status code.
71+
$node->connect_fails($connstr,$test_name,%params);
72+
}
73+
}
74+
75+
note"use ldapbindpasswd";
76+
77+
$ENV{"PGPASSWORD"} ='secret1';
78+
79+
unlink($node->data_dir .'/pg_hba.conf');
80+
$node->append_conf('pg_hba.conf',
81+
qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapbasedn="$ldap_basedn" ldapbinddn="$ldap_rootdn" ldapbindpasswd=wrong}
82+
);
83+
$node->restart;
84+
85+
test_access($node,'test1', 2,'search+bind authentication fails with wrong ldapbindpasswd');
86+
87+
unlink($node->data_dir .'/pg_hba.conf');
88+
$node->append_conf('pg_hba.conf',
89+
qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapbasedn="$ldap_basedn" ldapbinddn="$ldap_rootdn" ldapbindpasswd="$clear_ldap_rootpw"}
90+
);
91+
$node->restart;
92+
93+
test_access($node,'test1', 2,'search+bind authentication fails with clear password');
94+
95+
unlink($node->data_dir .'/pg_hba.conf');
96+
$node->append_conf('pg_hba.conf',
97+
qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapbasedn="$ldap_basedn" ldapbinddn="$ldap_rootdn" ldapbindpasswd="$rot13_ldap_rootpw"}
98+
);
99+
$node->restart;
100+
101+
test_access($node,'test1', 0,'search+bind authentication succeeds with rot13ed password');
102+
103+
done_testing();

‎src/test/modules/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ subdir('commit_ts')
55
subdir('delay_execution')
66
subdir('dummy_index_am')
77
subdir('dummy_seclabel')
8+
subdir('ldap_password_func')
89
subdir('libpq_pipeline')
910
subdir('plsample')
1011
subdir('snapshot_too_old')

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp