Skip to content

Commit 8b21d0a

Browse files
committed
Improve ldapsearch/ldapmodify --proxyAs handling
Updated the ldapsearch and ldapmodify command-line tools to provide better validation for the value of the --proxyAs argument. The tools will now reject attempts to use the argument with a value that doesn't start with either "dn:" or "u:", and they will also reject attempts to use a value that starts with "dn:" but is not followed by a valid LDAP DN.
1 parent eb22dc8 commit 8b21d0a

File tree

6 files changed

+215
-2
lines changed

6 files changed

+215
-2
lines changed

docs/release-notes.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@ <h3>Version 6.0.11</h3>
1919
<br><br>
2020
</li>
2121

22+
<li>
23+
Updated the ldapsearch and ldapmodify command-line tools to provide better
24+
validation for the value of the --proxyAs argument. The tools will now reject
25+
attempts to use the argument with a value that doesn't start with either "dn:" or
26+
"u:", and they will also reject attempts to use a value that starts with "dn:"
27+
but is not followed by a valid LDAP DN.
28+
<br><br>
29+
</li>
30+
2231
<li>
2332
Updated the Filter methods for creating substring filters to better support empty
2433
components. In LDAP filters, filters are transmitted using a binary encoding,

messages/unboundid-ldapsdk-tools.properties

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,6 +1533,12 @@ ERR_LDAPMODIFY_ROUTE_TO_BACKEND_SET_INVALID_FORMAT=Value ''{0}'' provided for \
15331533
argument ''{1}'' is invalid. The value must contain the ID of the \
15341534
entry-balancing request processor followed by a colon and the ID of a \
15351535
desired backend set to use for that entry-balancing request processor.
1536+
ERR_LDAPMODIFY_PROXY_AS_DN_NOT_DN=The value of the {0} argument is not valid \
1537+
because ''{1}'' cannot be parsed as a valid LDAP DN.
1538+
ERR_LDAPMODIFY_PROXY_AS_VALUE_MISSING_PREFIX=The value of the {0} argument is \
1539+
not valid because it does not start with either ''dn:'' (to indicate that \
1540+
the following value is an LDAP DN) or ''u:'' (to indicate that the \
1541+
following value is a username).
15361542
ERR_LDAPMODIFY_CANNOT_CREATE_CONNECTION_POOL=An error occurred while \
15371543
attempting to create a connection pool to communicate with the directory \
15381544
server: {0}
@@ -2341,6 +2347,12 @@ ERR_LDAPSEARCH_ROUTE_TO_BACKEND_SET_INVALID_FORMAT=Value ''{0}'' provided for \
23412347
ERR_LDAPSEARCH_RENAME_ATTRIBUTE_MISMATCH=The --renameAttributeFrom argument \
23422348
must be provided the same number of times as the --renameAttributeTo \
23432349
argument.
2350+
ERR_LDAPSEARCH_PROXY_AS_DN_NOT_DN=The value of the {0} argument is not valid \
2351+
because ''{1}'' cannot be parsed as a valid LDAP DN.
2352+
ERR_LDAPSEARCH_PROXY_AS_VALUE_MISSING_PREFIX=The value of the {0} argument is \
2353+
not valid because it does not start with either ''dn:'' (to indicate that \
2354+
the following value is an LDAP DN) or ''u:'' (to indicate that the \
2355+
following value is a username).
23442356
ERR_LDAPSEARCH_MOVE_SUBTREE_MISMATCH=The --moveSubtreeFrom argument must be \
23452357
provided the same number of times as the --moveSubtreeTo argument.
23462358
ERR_LDAPSEARCH_OUTPUT_FORMAT_NOT_SUPPORTED_WITH_URLS=The ''{0}'' output \

src/com/unboundid/ldap/sdk/unboundidds/tools/LDAPModify.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,6 +1574,30 @@ public void doExtendedNonLDAPArgumentValidation()
15741574
rpID, bsIDs));
15751575
}
15761576
}
1577+
1578+
1579+
// If the --proxyAs argument was provided, then make sure its value is
1580+
// properly formatted.
1581+
if (proxyAs.isPresent())
1582+
{
1583+
final String proxyAsValue = proxyAs.getValue();
1584+
final String lowerProxyAsValue = StaticUtils.toLowerCase(proxyAsValue);
1585+
if (lowerProxyAsValue.startsWith("dn:"))
1586+
{
1587+
final String dnString = proxyAsValue.substring(3);
1588+
if (! DN.isValidDN(dnString))
1589+
{
1590+
throw new ArgumentException(ERR_LDAPMODIFY_PROXY_AS_DN_NOT_DN.get(
1591+
proxyAs.getIdentifierString(), dnString));
1592+
}
1593+
}
1594+
else if (! lowerProxyAsValue.startsWith("u:"))
1595+
{
1596+
throw new ArgumentException(
1597+
ERR_LDAPMODIFY_PROXY_AS_VALUE_MISSING_PREFIX.get(
1598+
proxyAs.getIdentifierString()));
1599+
}
1600+
}
15771601
}
15781602

15791603

src/com/unboundid/ldap/sdk/unboundidds/tools/LDAPSearch.java

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,8 @@ public void addNonLDAPArguments(@NotNull final ArgumentParser parser)
11101110
INFO_PLACEHOLDER_AUTHZID.get(),
11111111
INFO_LDAPSEARCH_ARG_DESCRIPTION_PROXY_AS.get());
11121112
proxyAs.addLongIdentifier("proxy-as", true);
1113+
proxyAs.addLongIdentifier("proxyV2As", true);
1114+
proxyAs.addLongIdentifier("proxy-v2-as", true);
11131115
proxyAs.setArgumentGroupName(INFO_LDAPSEARCH_ARG_GROUP_CONTROLS.get());
11141116
parser.addArgument(proxyAs);
11151117

@@ -2199,6 +2201,30 @@ else if (derefStr.equals("find"))
21992201
}
22002202

22012203

2204+
// If the --proxyAs argument was provided, then make sure its value is
2205+
// properly formatted.
2206+
if (proxyAs.isPresent())
2207+
{
2208+
final String proxyAsValue = proxyAs.getValue();
2209+
final String lowerProxyAsValue = StaticUtils.toLowerCase(proxyAsValue);
2210+
if (lowerProxyAsValue.startsWith("dn:"))
2211+
{
2212+
final String dnString = proxyAsValue.substring(3);
2213+
if (! DN.isValidDN(dnString))
2214+
{
2215+
throw new ArgumentException(ERR_LDAPSEARCH_PROXY_AS_DN_NOT_DN.get(
2216+
proxyAs.getIdentifierString(), dnString));
2217+
}
2218+
}
2219+
else if (! lowerProxyAsValue.startsWith("u:"))
2220+
{
2221+
throw new ArgumentException(
2222+
ERR_LDAPSEARCH_PROXY_AS_VALUE_MISSING_PREFIX.get(
2223+
proxyAs.getIdentifierString()));
2224+
}
2225+
}
2226+
2227+
22022228
// See if any entry transformations need to be applied.
22032229
final ArrayList<EntryTransformation> transformations = new ArrayList<>(5);
22042230
if (excludeAttribute.isPresent())
@@ -3442,8 +3468,26 @@ else if (valueStr.equals("without-non-deleted-entries"))
34423468

34433469
if (proxyAs.isPresent())
34443470
{
3445-
controls.add(new ProxiedAuthorizationV2RequestControl(
3446-
proxyAs.getValue()));
3471+
final String proxyAsValue = proxyAs.getValue();
3472+
final String lowerProxyAsValue = StaticUtils.toLowerCase(proxyAsValue);
3473+
if (lowerProxyAsValue.startsWith("dn:"))
3474+
{
3475+
final String dnString = proxyAsValue.substring(3);
3476+
if (! DN.isValidDN(dnString))
3477+
{
3478+
throw new LDAPException(ResultCode.PARAM_ERROR,
3479+
ERR_LDAPSEARCH_PROXY_AS_DN_NOT_DN.get(
3480+
proxyAs.getIdentifierString(), dnString));
3481+
}
3482+
}
3483+
else if (! lowerProxyAsValue.startsWith("u:"))
3484+
{
3485+
throw new LDAPException(ResultCode.PARAM_ERROR,
3486+
ERR_LDAPSEARCH_PROXY_AS_VALUE_MISSING_PREFIX.get(
3487+
proxyAs.getIdentifierString()));
3488+
}
3489+
3490+
controls.add(new ProxiedAuthorizationV2RequestControl(proxyAsValue));
34473491
}
34483492

34493493
if (proxyV1As.isPresent())

tests/unit/src/com/unboundid/ldap/sdk/unboundidds/tools/LDAPModifyTestCase.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3449,4 +3449,65 @@ public void testInvalidAccessLogFieldControls()
34493449
"--ldifFile", ldifFile.getAbsolutePath()),
34503450
ResultCode.PARAM_ERROR);
34513451
}
3452+
3453+
3454+
3455+
/**
3456+
* Tests to ensure that the tool rejects attempts to use the --proxyAs
3457+
* argument with invalid values.
3458+
*
3459+
* @throws Exception If an unexpected problem occurs.
3460+
*/
3461+
@Test()
3462+
public void testInvalidProxyAsValues()
3463+
throws Exception
3464+
{
3465+
final InMemoryDirectoryServer ds = getTestDS(true, true);
3466+
3467+
final File ldifFile = createTempFile(
3468+
"dn: dc=example,dc=com",
3469+
"changetype: modify",
3470+
"replace: description",
3471+
"description: foo");
3472+
3473+
assertEquals(
3474+
LDAPModify.main((InputStream) null, null, null,
3475+
"--hostname", "localhost",
3476+
"--port", String.valueOf(ds.getListenPort()),
3477+
"--proxyAs", "missing-prefix",
3478+
"--ldifFile", ldifFile.getAbsolutePath()),
3479+
ResultCode.PARAM_ERROR);
3480+
3481+
assertEquals(
3482+
LDAPModify.main((InputStream) null, null, null,
3483+
"--hostname", "localhost",
3484+
"--port", String.valueOf(ds.getListenPort()),
3485+
"--proxyAs", "i:invalid-prefix",
3486+
"--ldifFile", ldifFile.getAbsolutePath()),
3487+
ResultCode.PARAM_ERROR);
3488+
3489+
assertEquals(
3490+
LDAPModify.main((InputStream) null, null, null,
3491+
"--hostname", "localhost",
3492+
"--port", String.valueOf(ds.getListenPort()),
3493+
"--proxyAs", "dn:not-a-dn",
3494+
"--ldifFile", ldifFile.getAbsolutePath()),
3495+
ResultCode.PARAM_ERROR);
3496+
3497+
assertEquals(
3498+
LDAPModify.main((InputStream) null, null, null,
3499+
"--hostname", "localhost",
3500+
"--port", String.valueOf(ds.getListenPort()),
3501+
"--proxyAs", "dn:uid=test.user,ou=People,dc=example,dc=com",
3502+
"--ldifFile", ldifFile.getAbsolutePath()),
3503+
ResultCode.SUCCESS);
3504+
3505+
assertEquals(
3506+
LDAPModify.main((InputStream) null, null, null,
3507+
"--hostname", "localhost",
3508+
"--port", String.valueOf(ds.getListenPort()),
3509+
"--proxyAs", "u:test.user",
3510+
"--ldifFile", ldifFile.getAbsolutePath()),
3511+
ResultCode.SUCCESS);
3512+
}
34523513
}

tests/unit/src/com/unboundid/ldap/sdk/unboundidds/tools/LDAPSearchTestCase.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2770,4 +2770,67 @@ public void testInvalidAccessLogFieldControls()
27702770
"(objectClass=*)"),
27712771
ResultCode.PARAM_ERROR);
27722772
}
2773+
2774+
2775+
2776+
/**
2777+
* Tests to ensure that the tool rejects attempts to use the --proxyAs
2778+
* argument with invalid values.
2779+
*
2780+
* @throws Exception If an unexpected problem occurs.
2781+
*/
2782+
@Test()
2783+
public void testInvalidProxyAsValues()
2784+
throws Exception
2785+
{
2786+
assertEquals(
2787+
LDAPSearch.main(NULL_OUTPUT_STREAM, NULL_OUTPUT_STREAM,
2788+
"--hostname", "localhost",
2789+
"--port", String.valueOf(ds.getListenPort()),
2790+
"--baseDN", "",
2791+
"--scope", "base",
2792+
"--proxyAs", "missing-prefix",
2793+
"(objectClass=*)"),
2794+
ResultCode.PARAM_ERROR);
2795+
2796+
assertEquals(
2797+
LDAPSearch.main(NULL_OUTPUT_STREAM, NULL_OUTPUT_STREAM,
2798+
"--hostname", "localhost",
2799+
"--port", String.valueOf(ds.getListenPort()),
2800+
"--baseDN", "",
2801+
"--scope", "base",
2802+
"--proxyAs", "i:invalid-prefix",
2803+
"(objectClass=*)"),
2804+
ResultCode.PARAM_ERROR);
2805+
2806+
assertEquals(
2807+
LDAPSearch.main(NULL_OUTPUT_STREAM, NULL_OUTPUT_STREAM,
2808+
"--hostname", "localhost",
2809+
"--port", String.valueOf(ds.getListenPort()),
2810+
"--baseDN", "",
2811+
"--scope", "base",
2812+
"--proxyAs", "dn:not-a-dn",
2813+
"(objectClass=*)"),
2814+
ResultCode.PARAM_ERROR);
2815+
2816+
assertEquals(
2817+
LDAPSearch.main(NULL_OUTPUT_STREAM, NULL_OUTPUT_STREAM,
2818+
"--hostname", "localhost",
2819+
"--port", String.valueOf(ds.getListenPort()),
2820+
"--baseDN", "",
2821+
"--scope", "base",
2822+
"--proxyAs", "dn:uid=aaron.adams,ou=People,dc=example,dc=com",
2823+
"(objectClass=*)"),
2824+
ResultCode.SUCCESS);
2825+
2826+
assertEquals(
2827+
LDAPSearch.main(NULL_OUTPUT_STREAM, NULL_OUTPUT_STREAM,
2828+
"--hostname", "localhost",
2829+
"--port", String.valueOf(ds.getListenPort()),
2830+
"--baseDN", "",
2831+
"--scope", "base",
2832+
"--proxyAs", "u:aaron.adams",
2833+
"(objectClass=*)"),
2834+
ResultCode.SUCCESS);
2835+
}
27732836
}

0 commit comments

Comments
 (0)