Skip to content

[enhance](auth) introduction of configuration property to prohibit login with empty LDAP password#61440

Open
iaorekhov-1980 wants to merge 6 commits into
apache:masterfrom
iaorekhov-1980:feat/disable_ldap_empty_pass
Open

[enhance](auth) introduction of configuration property to prohibit login with empty LDAP password#61440
iaorekhov-1980 wants to merge 6 commits into
apache:masterfrom
iaorekhov-1980:feat/disable_ldap_empty_pass

Conversation

@iaorekhov-1980

@iaorekhov-1980 iaorekhov-1980 commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

This PR adds new configuration property ldap_allow_empty_pass to prohibit option for existing user to login into LDAP with empty password for legacy approach.
It doesn't impact new approach from #60407 , because since 4.1.x new LDAP plugin explicitly prohibits login with empty pass.
But in legacy version - 3.1.x and 4.0.x such option is still available.
If ldap_allow_empty_pass in ldap.conf is not specified or specified as true - user can login with empty pass (existing behavior).
If ldap_allow_empty_pass specified as false - login attempt with empty password will be rejected with corresponding error message.

Could you please include this PR into 4.x and 3.1.x branches, please!

Issue Number: close #60353

Related PR: #xxx

Problem Summary:

Currently for existing user it is possible to login into LDAP with empty password.
New configuration property disables such option, but default behavior still allows to login without specified password.

Release note

New ldap_allow_empty_pass property for legacy authentication approach was introduced into ldap.conf to prohibit login with empty LDAP password as it is allowed by LDAP protocol by default.

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes.
  1. ldap.conf and LdapConfig.java - new configuration ldap_allow_empty_pass property with default value true to keep existing behavior as default
  2. ErrorCode.java - specific error message for case with empty password was added
  3. LdapManager.java - added logic to prohibit login with empty LDAP password and placed it into separate method, which is invoked from already existing checkUserPasswd
    3.1 user has specified empty password
    3.2 property ldap_allow_empty_pass is false and doesn't allow to login with empty password
    If both conditions met - authentication is failed and false is returning, as by other check in checkUserPassword
  4. No functional changes were made to Auth.java and LdapAuthenticator.java — they only delegate to LdapManager as before. A LOG.info() line was added to aid debugging when an empty-password login attempt is detected.
  5. LdapManagerTest.java - introduced new test methods to validate for existing behavior (without specified ldap_allow_empty_pass property or true) and new one (with ldap_allow_empty_pass property specified to false) to check that login is still successful in first case and failed in the second one.
  6. LdapAuthenticationPluginIntegrationTest.java - added test methods to verify that new plugin based LDAP authentication doesn't depend on this ldap_allow_empty_pass property and empty password is always rejected.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

@Thearas

Thearas commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@iaorekhov-1980 iaorekhov-1980 changed the title [enhance] (auth) add option to disable login with empty pass [enhance](auth) introduction of configuration property to prohibit login with empty LDAP password Mar 17, 2026
@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run buildall

@doris-robot

Copy link
Copy Markdown
TPC-H: Total hot run time: 27089 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 8fa563330bafb91c2f9f69f841d845f183198ca7, data reload: false

------ Round 1 ----------------------------------
orders	Doris	NULL	NULL	0	0	0	NULL	0	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	17617	4514	4315	4315
q2	q3	10635	811	516	516
q4	4671	362	254	254
q5	7560	1209	1013	1013
q6	181	174	147	147
q7	795	873	655	655
q8	9299	1508	1367	1367
q9	4915	4761	4719	4719
q10	6238	1901	1664	1664
q11	496	260	253	253
q12	700	589	469	469
q13	18029	2944	2187	2187
q14	237	239	223	223
q15	q16	755	735	685	685
q17	743	873	453	453
q18	6148	5442	5311	5311
q19	1113	1002	633	633
q20	549	507	393	393
q21	4439	1862	1507	1507
q22	491	388	325	325
Total cold run time: 95611 ms
Total hot run time: 27089 ms

----- Round 2, with runtime_filter_mode=off -----
orders	Doris	NULL	NULL	150000000	42	6422171781	NULL	22778155	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	4776	4670	4657	4657
q2	q3	3893	4344	3815	3815
q4	884	1216	789	789
q5	4096	4446	4339	4339
q6	196	187	148	148
q7	1785	1705	1555	1555
q8	2490	2734	2797	2734
q9	7523	7464	7308	7308
q10	3870	4087	3624	3624
q11	500	432	426	426
q12	505	597	455	455
q13	2810	3129	2330	2330
q14	281	315	277	277
q15	q16	715	765	726	726
q17	1185	1414	1404	1404
q18	7024	6758	6686	6686
q19	987	1004	1013	1004
q20	2067	2158	2028	2028
q21	4208	3590	3351	3351
q22	466	447	389	389
Total cold run time: 50261 ms
Total hot run time: 48045 ms

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 71.43% (5/7) 🎉
Increment coverage report
Complete coverage report

@doris-robot

Copy link
Copy Markdown
TPC-DS: Total hot run time: 169028 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 8fa563330bafb91c2f9f69f841d845f183198ca7, data reload: false

query5	4320	660	523	523
query6	339	223	202	202
query7	4220	476	283	283
query8	358	245	231	231
query9	8748	2760	2725	2725
query10	536	392	358	358
query11	7003	5120	4916	4916
query12	185	129	121	121
query13	1270	470	341	341
query14	5632	3713	3543	3543
query14_1	2867	2822	2795	2795
query15	207	193	176	176
query16	968	475	462	462
query17	891	740	609	609
query18	2445	445	342	342
query19	215	210	182	182
query20	139	136	127	127
query21	215	138	114	114
query22	13255	14148	14701	14148
query23	16283	15861	15542	15542
query23_1	15902	15612	15359	15359
query24	7301	1646	1234	1234
query24_1	1251	1234	1255	1234
query25	551	472	434	434
query26	1251	262	156	156
query27	2779	492	318	318
query28	4499	1856	1875	1856
query29	881	589	487	487
query30	296	226	193	193
query31	1017	946	901	901
query32	90	72	69	69
query33	512	333	290	290
query34	903	907	530	530
query35	645	702	617	617
query36	1080	1112	983	983
query37	139	99	88	88
query38	2972	2883	2891	2883
query39	879	843	825	825
query39_1	797	802	804	802
query40	237	154	134	134
query41	64	65	59	59
query42	262	261	260	260
query43	244	249	223	223
query44	
query45	198	194	188	188
query46	891	983	605	605
query47	2846	2135	2071	2071
query48	317	328	231	231
query49	639	455	390	390
query50	715	279	215	215
query51	4124	4205	4003	4003
query52	267	269	265	265
query53	290	339	288	288
query54	309	279	288	279
query55	94	91	88	88
query56	321	330	326	326
query57	1937	1928	1656	1656
query58	308	289	276	276
query59	2835	2963	2789	2789
query60	382	361	352	352
query61	183	183	178	178
query62	639	595	557	557
query63	319	288	283	283
query64	5288	1416	1128	1128
query65	
query66	1496	490	375	375
query67	24307	24379	24302	24302
query68	
query69	427	335	299	299
query70	1009	987	936	936
query71	351	329	321	321
query72	3033	2826	2462	2462
query73	554	561	315	315
query74	9665	9589	9396	9396
query75	2893	2764	2488	2488
query76	2296	1051	683	683
query77	371	378	316	316
query78	10954	11189	10452	10452
query79	1104	843	578	578
query80	1333	649	551	551
query81	553	267	230	230
query82	998	159	126	126
query83	340	266	249	249
query84	298	129	106	106
query85	949	517	458	458
query86	443	308	300	300
query87	3144	3166	3039	3039
query88	3566	2663	2603	2603
query89	430	371	348	348
query90	2034	189	185	185
query91	180	165	142	142
query92	79	76	74	74
query93	983	904	517	517
query94	651	323	307	307
query95	609	402	326	326
query96	663	539	237	237
query97	2488	2460	2410	2410
query98	240	221	222	221
query99	1001	1012	919	919
Total cold run time: 251426 ms
Total hot run time: 169028 ms

@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run external

@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run nonConcurrent

@iaorekhov-1980
iaorekhov-1980 marked this pull request as ready for review March 18, 2026 09:15
@iaorekhov-1980
iaorekhov-1980 force-pushed the feat/disable_ldap_empty_pass branch from 8fa5633 to 629cab0 Compare March 23, 2026 07:38
@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run buildall

@doris-robot

Copy link
Copy Markdown
TPC-H: Total hot run time: 26705 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 629cab0bfbfbc28cf613d29f5a7c6acb9bdc9ba7, data reload: false

------ Round 1 ----------------------------------
orders	Doris	NULL	NULL	0	0	0	NULL	0	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	17654	4511	4276	4276
q2	q3	10671	758	506	506
q4	4687	366	258	258
q5	7555	1211	1018	1018
q6	173	172	145	145
q7	768	840	670	670
q8	9437	1468	1312	1312
q9	4896	4753	4694	4694
q10	6321	1922	1656	1656
q11	443	260	237	237
q12	751	582	465	465
q13	18070	2915	2195	2195
q14	227	223	213	213
q15	q16	761	758	677	677
q17	713	879	415	415
q18	5929	5335	5229	5229
q19	1101	964	578	578
q20	523	482	377	377
q21	4511	1824	1393	1393
q22	343	391	407	391
Total cold run time: 95534 ms
Total hot run time: 26705 ms

----- Round 2, with runtime_filter_mode=off -----
orders	Doris	NULL	NULL	150000000	42	6422171781	NULL	22778155	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	4791	4663	4715	4663
q2	q3	3869	4322	3842	3842
q4	860	1210	799	799
q5	4036	4308	4336	4308
q6	189	176	141	141
q7	1750	1694	1573	1573
q8	2524	2730	2594	2594
q9	7541	7380	7370	7370
q10	3801	3972	3585	3585
q11	525	453	430	430
q12	496	627	457	457
q13	2685	3236	2759	2759
q14	304	312	289	289
q15	q16	734	802	726	726
q17	1169	1363	1356	1356
q18	7168	6915	6629	6629
q19	892	939	955	939
q20	2080	2185	1970	1970
q21	3947	3517	3322	3322
q22	472	430	378	378
Total cold run time: 49833 ms
Total hot run time: 48130 ms

@doris-robot

Copy link
Copy Markdown
TPC-DS: Total hot run time: 167913 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 629cab0bfbfbc28cf613d29f5a7c6acb9bdc9ba7, data reload: false

query5	4320	612	511	511
query6	334	232	202	202
query7	4216	456	260	260
query8	365	252	230	230
query9	8718	2726	2707	2707
query10	538	372	337	337
query11	6957	5106	4859	4859
query12	179	129	128	128
query13	1279	454	351	351
query14	5719	3754	3445	3445
query14_1	2880	2826	2877	2826
query15	205	195	177	177
query16	1008	483	461	461
query17	1024	723	638	638
query18	2455	453	355	355
query19	215	224	186	186
query20	133	135	129	129
query21	217	136	115	115
query22	13233	13983	14951	13983
query23	16351	15787	15481	15481
query23_1	15642	15629	16108	15629
query24	7331	1629	1239	1239
query24_1	1239	1237	1245	1237
query25	631	486	409	409
query26	1263	267	151	151
query27	2763	472	295	295
query28	4471	1830	1845	1830
query29	872	578	494	494
query30	304	230	201	201
query31	1063	952	884	884
query32	78	70	73	70
query33	501	337	277	277
query34	880	888	539	539
query35	689	687	593	593
query36	1102	1160	987	987
query37	133	93	83	83
query38	2958	2896	2886	2886
query39	860	821	805	805
query39_1	789	793	792	792
query40	237	152	136	136
query41	63	98	58	58
query42	255	256	252	252
query43	239	256	214	214
query44	
query45	198	187	190	187
query46	873	988	606	606
query47	2069	2157	2063	2063
query48	299	326	224	224
query49	626	472	369	369
query50	678	278	208	208
query51	4054	4030	3959	3959
query52	262	263	250	250
query53	295	336	287	287
query54	304	273	265	265
query55	91	88	85	85
query56	313	332	311	311
query57	1914	1855	1630	1630
query58	283	278	267	267
query59	2820	2967	2731	2731
query60	337	342	329	329
query61	154	157	155	155
query62	625	591	524	524
query63	317	286	279	279
query64	5142	1256	1004	1004
query65	
query66	1477	464	351	351
query67	24254	24310	24148	24148
query68	
query69	411	311	291	291
query70	979	953	967	953
query71	338	310	311	310
query72	2842	2638	2469	2469
query73	533	550	322	322
query74	9633	9603	9401	9401
query75	2873	2771	2451	2451
query76	2274	1038	670	670
query77	354	409	306	306
query78	11021	11084	10438	10438
query79	1115	765	568	568
query80	792	633	569	569
query81	513	260	220	220
query82	1353	152	117	117
query83	336	261	249	249
query84	280	122	100	100
query85	879	506	461	461
query86	372	306	294	294
query87	3219	3103	3016	3016
query88	3563	2622	2662	2622
query89	427	370	347	347
query90	1952	174	178	174
query91	171	171	148	148
query92	74	73	72	72
query93	918	840	492	492
query94	455	313	286	286
query95	595	403	322	322
query96	646	515	231	231
query97	2481	2505	2389	2389
query98	238	228	219	219
query99	1033	1010	906	906
Total cold run time: 249268 ms
Total hot run time: 167913 ms

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 71.43% (5/7) 🎉
Increment coverage report
Complete coverage report

@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run external

1 similar comment
@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run external

@morningman morningman self-assigned this Mar 25, 2026
@morningman

Copy link
Copy Markdown
Contributor

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary for PR #61440

PR Goal: Add ldap_allow_empty_pass config to prohibit LDAP login with empty passwords.

Critical Checkpoint Conclusions

1. Does the code accomplish its goal? Is there a test that proves it?
Yes. The check is correctly placed in both independent LDAP authentication paths (LdapAuthenticator.internalAuthenticate for MySQL wire protocol and Auth.checkPlainPassword for Thrift/HTTP/Arrow Flight). Tests cover the LdapAuthenticator path. However, there is no test for the Auth.checkPlainPassword path.

2. Is the modification as small, clear, and focused as possible?
Yes. The change is minimal and well-scoped.

3. Concurrency concerns?
The config ldap_allow_empty_pass is a static boolean read without synchronization. This is acceptable for a config flag — worst case is a brief window of stale reads during config reload, which is tolerable for this use case.

4. Configuration items added — should it allow dynamic changes?
Yes — see inline comment. The config should be mutable = true so it can be toggled at runtime without FE restart. This is a pure runtime policy check with no initialization dependency, unlike connection/pool configs.

5. Functionally parallel code paths?
Both independent LDAP auth paths are covered. No parallel paths are missed.

6. Error message quality?
The error message "Access with empty password is prohibited for user %s because of current mode" is vague — "current mode" doesn't explain what mode. See inline comment for suggested improvement.

7. Test coverage?

  • Unit test covers the LdapAuthenticator path with empty password allowed/denied scenarios. Good.
  • Missing: test for Auth.checkPlainPassword path (the Thrift/HTTP entry point).
  • Missing: test with null password (not just empty string "").

8. Incompatible changes / rolling upgrade?
No incompatible changes. Default value true preserves backward compatibility.

9. Observability?
LOG.info is adequate for rejected login attempts.

10. Transaction/persistence?
Not applicable.

11. Performance?
No concerns — the check is a simple boolean comparison on a non-hot path.

12. Other issues?

  • The LdapManager.checkUserPasswd at line 106 already rejects null passwords (Objects.isNull(passwd) returns false) but does NOT reject empty strings — it will proceed to ldapClient.checkPassword() with an empty string, which typically results in an LDAP "unauthenticated bind" (silently succeeds). This confirms the PR addresses a real security issue.
  • The PR description mentions ldap_use_ssl in section 3.2 but means ldap_allow_empty_pass — this is a typo in the PR description only (not in code).
  • The Release note section says "None" but this is a user-visible behavior change (new config property). It should have a release note.

Comment thread fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java
Comment thread fe/fe-common/src/main/java/org/apache/doris/common/ErrorCode.java
@iaorekhov-1980
iaorekhov-1980 force-pushed the feat/disable_ldap_empty_pass branch 2 times, most recently from aaa284b to 267c2e3 Compare March 26, 2026 11:17
@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run feut

8 similar comments
@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run feut

@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run feut

@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run feut

@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run feut

@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run feut

@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run feut

@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run feut

@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run feut

@iaorekhov-1980
iaorekhov-1980 force-pushed the feat/disable_ldap_empty_pass branch from 9c31d8e to 7e04059 Compare July 14, 2026 13:02
@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run feut

@iaorekhov-1980
iaorekhov-1980 force-pushed the feat/disable_ldap_empty_pass branch from 7e04059 to ba374c8 Compare July 14, 2026 14:37
@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 41.67% (5/12) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 29149 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit ba374c8b835debdf41a08308bb723c7efa3c8cea, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17685	4048	3977	3977
q2	1994	315	206	206
q3	10298	1413	839	839
q4	4704	473	335	335
q5	7583	865	563	563
q6	195	164	134	134
q7	738	810	609	609
q8	9937	1498	1604	1498
q9	5868	4389	4319	4319
q10	6874	1740	1485	1485
q11	512	335	322	322
q12	765	545	444	444
q13	18141	3310	2732	2732
q14	264	258	243	243
q15	q16	788	773	717	717
q17	933	972	1014	972
q18	7007	5824	5459	5459
q19	1248	1344	1060	1060
q20	766	651	556	556
q21	5735	2627	2382	2382
q22	414	352	297	297
Total cold run time: 102449 ms
Total hot run time: 29149 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4349	4232	4273	4232
q2	285	308	212	212
q3	4620	4918	4392	4392
q4	1986	2127	1339	1339
q5	4402	4261	4198	4198
q6	221	171	125	125
q7	1735	1894	1764	1764
q8	2533	2234	2041	2041
q9	7817	7817	7883	7817
q10	4724	4660	4208	4208
q11	573	405	392	392
q12	760	754	542	542
q13	3416	3571	3038	3038
q14	300	323	294	294
q15	q16	724	749	647	647
q17	1338	1323	1317	1317
q18	7964	7304	7149	7149
q19	1099	1081	1073	1073
q20	2210	2222	1923	1923
q21	5190	4539	4387	4387
q22	515	456	438	438
Total cold run time: 56761 ms
Total hot run time: 51528 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 178006 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit ba374c8b835debdf41a08308bb723c7efa3c8cea, data reload: false

query5	4309	646	488	488
query6	456	224	211	211
query7	4835	548	336	336
query8	346	203	184	184
query9	8791	4011	4064	4011
query10	461	366	310	310
query11	5943	2419	2150	2150
query12	164	98	102	98
query13	1303	615	417	417
query14	6203	5240	4925	4925
query14_1	4645	4224	4251	4224
query15	202	200	178	178
query16	995	446	429	429
query17	988	720	555	555
query18	2425	465	334	334
query19	202	183	147	147
query20	113	111	103	103
query21	228	154	133	133
query22	13594	13570	13273	13273
query23	17311	16412	16053	16053
query23_1	16358	16255	16139	16139
query24	7698	1758	1300	1300
query24_1	1306	1284	1263	1263
query25	579	459	410	410
query26	1338	351	213	213
query27	2618	558	377	377
query28	4483	2006	1968	1968
query29	1082	611	504	504
query30	340	262	244	244
query31	1140	1105	986	986
query32	105	63	65	63
query33	534	323	253	253
query34	1173	1137	655	655
query35	765	781	664	664
query36	1198	1214	1045	1045
query37	153	107	98	98
query38	1870	1727	1652	1652
query39	882	874	860	860
query39_1	853	832	828	828
query40	248	163	146	146
query41	71	68	68	68
query42	94	93	96	93
query43	324	328	284	284
query44	1422	770	762	762
query45	199	194	178	178
query46	1056	1196	701	701
query47	2137	2104	2011	2011
query48	410	418	319	319
query49	596	424	323	323
query50	1002	435	327	327
query51	10613	10667	10593	10593
query52	88	90	77	77
query53	251	278	205	205
query54	302	243	231	231
query55	76	73	71	71
query56	316	303	311	303
query57	1319	1295	1198	1198
query58	285	288	280	280
query59	1586	1674	1371	1371
query60	314	280	263	263
query61	175	192	147	147
query62	553	493	431	431
query63	230	197	196	196
query64	2795	1026	857	857
query65	4694	4599	4621	4599
query66	1812	494	379	379
query67	29324	29225	29006	29006
query68	3016	1557	1055	1055
query69	416	306	265	265
query70	1038	945	985	945
query71	348	310	327	310
query72	3023	2734	2344	2344
query73	846	786	427	427
query74	5087	4929	4713	4713
query75	2550	2482	2140	2140
query76	2343	1191	759	759
query77	348	375	291	291
query78	11805	11832	11354	11354
query79	1414	1114	722	722
query80	1281	561	444	444
query81	551	326	270	270
query82	614	150	117	117
query83	403	326	291	291
query84	319	160	128	128
query85	960	603	508	508
query86	429	287	277	277
query87	1847	1820	1729	1729
query88	3741	2787	2756	2756
query89	419	367	324	324
query90	1939	198	190	190
query91	198	185	155	155
query92	63	57	60	57
query93	1675	1705	1005	1005
query94	747	362	328	328
query95	788	501	553	501
query96	998	763	354	354
query97	2666	2611	2547	2547
query98	213	203	199	199
query99	1087	1111	965	965
Total cold run time: 263863 ms
Total hot run time: 178006 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 24.93 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit ba374c8b835debdf41a08308bb723c7efa3c8cea, data reload: false

query1	0.01	0.01	0.01
query2	0.10	0.05	0.04
query3	0.25	0.14	0.13
query4	1.61	0.14	0.14
query5	0.25	0.22	0.22
query6	1.21	1.08	1.08
query7	0.04	0.01	0.01
query8	0.06	0.04	0.04
query9	0.38	0.31	0.30
query10	0.56	0.55	0.54
query11	0.19	0.14	0.14
query12	0.19	0.15	0.14
query13	0.47	0.47	0.48
query14	0.99	1.02	0.99
query15	0.62	0.59	0.59
query16	0.32	0.32	0.32
query17	1.14	1.09	1.06
query18	0.23	0.21	0.21
query19	2.05	1.89	1.99
query20	0.02	0.01	0.02
query21	15.45	0.22	0.13
query22	4.87	0.06	0.06
query23	16.13	0.31	0.12
query24	2.91	0.44	0.32
query25	0.11	0.06	0.05
query26	0.73	0.22	0.16
query27	0.03	0.05	0.04
query28	3.49	0.91	0.52
query29	12.46	4.04	3.22
query30	0.29	0.16	0.15
query31	2.77	0.61	0.31
query32	3.23	0.60	0.48
query33	3.31	3.16	3.18
query34	15.48	4.26	3.57
query35	3.53	3.52	3.52
query36	0.56	0.43	0.44
query37	0.09	0.07	0.06
query38	0.05	0.04	0.03
query39	0.04	0.03	0.03
query40	0.18	0.16	0.15
query41	0.08	0.03	0.03
query42	0.04	0.03	0.03
query43	0.04	0.03	0.04
Total cold run time: 96.56 s
Total hot run time: 24.93 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 0.00% (0/12) 🎉
Increment coverage report
Complete coverage report

@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

Hello, @CalvinKirs

Could you please check my PR as I've fixed and answered comments from your review.

Thanks in advance!

@iaorekhov-1980
iaorekhov-1980 force-pushed the feat/disable_ldap_empty_pass branch from ba374c8 to a4a8562 Compare July 16, 2026 07:40
@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 29103 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit a4a85622acc8c6983ed57ef6536368e15fb453a6, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17627	4041	4003	4003
q2	2011	314	193	193
q3	10291	1383	793	793
q4	4686	465	342	342
q5	7571	849	563	563
q6	180	164	135	135
q7	762	821	602	602
q8	9310	1660	1526	1526
q9	5594	4305	4360	4305
q10	6751	1753	1474	1474
q11	500	356	321	321
q12	768	563	443	443
q13	18096	3406	2750	2750
q14	271	260	240	240
q15	q16	788	774	710	710
q17	907	972	941	941
q18	6869	5829	5523	5523
q19	1318	1195	996	996
q20	786	685	592	592
q21	5934	2687	2360	2360
q22	440	361	291	291
Total cold run time: 101460 ms
Total hot run time: 29103 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4356	4283	4259	4259
q2	299	310	218	218
q3	4519	4978	4360	4360
q4	2024	2137	1360	1360
q5	4358	4283	4243	4243
q6	229	174	126	126
q7	1734	1630	1831	1630
q8	2662	2191	2147	2147
q9	7946	7962	7657	7657
q10	4659	4670	4153	4153
q11	580	417	371	371
q12	765	745	554	554
q13	3296	3590	2965	2965
q14	297	319	282	282
q15	q16	702	722	656	656
q17	1357	1312	1325	1312
q18	8081	7198	7179	7179
q19	1160	1170	1068	1068
q20	2201	2184	1927	1927
q21	5216	4525	4394	4394
q22	507	449	392	392
Total cold run time: 56948 ms
Total hot run time: 51253 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 178313 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit a4a85622acc8c6983ed57ef6536368e15fb453a6, data reload: false

query5	4300	649	504	504
query6	461	226	214	214
query7	4867	624	340	340
query8	338	190	172	172
query9	8747	4089	4097	4089
query10	462	371	310	310
query11	5906	2319	2141	2141
query12	159	107	103	103
query13	1264	648	442	442
query14	6263	5251	4959	4959
query14_1	4301	4302	4270	4270
query15	206	205	182	182
query16	1054	473	388	388
query17	968	728	580	580
query18	2461	484	360	360
query19	208	196	152	152
query20	112	109	110	109
query21	242	164	139	139
query22	13536	13453	13273	13273
query23	17211	16482	16315	16315
query23_1	16216	16179	16279	16179
query24	7529	1813	1285	1285
query24_1	1294	1270	1252	1252
query25	523	430	355	355
query26	1340	347	211	211
query27	2607	646	388	388
query28	4491	1991	1990	1990
query29	1075	602	472	472
query30	328	265	229	229
query31	1117	1085	977	977
query32	97	61	61	61
query33	515	326	254	254
query34	1188	1156	636	636
query35	758	783	664	664
query36	1211	1175	1060	1060
query37	150	108	96	96
query38	1886	1670	1647	1647
query39	875	864	837	837
query39_1	847	832	827	827
query40	241	160	139	139
query41	65	63	64	63
query42	103	88	87	87
query43	323	328	282	282
query44	1437	770	751	751
query45	209	183	173	173
query46	1113	1199	715	715
query47	2196	2151	2033	2033
query48	420	416	295	295
query49	582	425	303	303
query50	1108	426	337	337
query51	10738	10636	10518	10518
query52	84	86	74	74
query53	261	286	205	205
query54	286	235	212	212
query55	75	69	68	68
query56	310	281	302	281
query57	1317	1289	1190	1190
query58	297	261	261	261
query59	1573	1664	1438	1438
query60	302	273	260	260
query61	152	153	150	150
query62	536	490	434	434
query63	249	204	202	202
query64	2857	1052	857	857
query65	4725	4669	4594	4594
query66	1819	503	371	371
query67	28547	29189	28943	28943
query68	3040	1572	1010	1010
query69	407	311	258	258
query70	1054	987	917	917
query71	390	332	311	311
query72	3059	2888	2637	2637
query73	818	856	438	438
query74	5022	4906	4702	4702
query75	2553	2508	2120	2120
query76	2340	1238	792	792
query77	367	381	279	279
query78	11872	11684	11356	11356
query79	1300	1198	738	738
query80	607	556	445	445
query81	451	336	301	301
query82	245	161	124	124
query83	323	328	288	288
query84	298	160	127	127
query85	887	617	522	522
query86	314	291	271	271
query87	1814	1819	1745	1745
query88	3706	2790	2746	2746
query89	415	384	323	323
query90	2167	215	204	204
query91	200	193	165	165
query92	60	62	56	56
query93	1547	1524	939	939
query94	541	330	323	323
query95	782	507	560	507
query96	1067	848	340	340
query97	2620	2619	2469	2469
query98	214	224	206	206
query99	1088	1133	981	981
Total cold run time: 260862 ms
Total hot run time: 178313 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 24.97 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit a4a85622acc8c6983ed57ef6536368e15fb453a6, data reload: false

query1	0.01	0.01	0.01
query2	0.09	0.05	0.05
query3	0.25	0.13	0.13
query4	1.61	0.13	0.14
query5	0.26	0.23	0.23
query6	1.24	1.08	1.06
query7	0.04	0.01	0.01
query8	0.06	0.03	0.04
query9	0.37	0.31	0.31
query10	0.55	0.54	0.53
query11	0.19	0.14	0.14
query12	0.17	0.14	0.13
query13	0.46	0.47	0.48
query14	1.02	0.99	1.01
query15	0.60	0.60	0.60
query16	0.32	0.33	0.31
query17	1.10	1.14	1.12
query18	0.22	0.21	0.21
query19	2.06	1.90	1.94
query20	0.01	0.02	0.01
query21	15.42	0.22	0.13
query22	4.87	0.05	0.05
query23	16.13	0.31	0.12
query24	2.91	0.44	0.32
query25	0.10	0.05	0.04
query26	0.77	0.20	0.16
query27	0.05	0.04	0.04
query28	3.52	0.93	0.52
query29	12.48	4.15	3.34
query30	0.27	0.15	0.15
query31	2.77	0.58	0.31
query32	3.22	0.58	0.48
query33	3.08	3.16	3.17
query34	15.56	4.21	3.53
query35	3.57	3.46	3.55
query36	0.55	0.44	0.43
query37	0.09	0.06	0.06
query38	0.04	0.04	0.03
query39	0.04	0.03	0.03
query40	0.18	0.17	0.15
query41	0.08	0.03	0.04
query42	0.03	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 96.4 s
Total hot run time: 24.97 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 41.67% (5/12) 🎉
Increment coverage report
Complete coverage report

@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run feut

@CalvinKirs

Copy link
Copy Markdown
Member

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for three correctness/security issues in the legacy LDAP authentication update. The review is complete for head a4a85622acc8c6983ed57ef6536368e15fb453a6: three review rounds converged, including separate whole-diff and authentication-risk passes, and the final live-thread sweep found no duplicate of these comments. No additional user review focus was provided.

Critical-checkpoint conclusions:

  • Goal and proof: the central LdapManager.checkUserPasswd check does block an empty string before cached-password acceptance and LDAP bind when the startup flag is false, and no supported legacy caller bypass was found. The added tests do not exercise that production chokepoint or either changed caller, so they do not prove the shipped behavior.
  • Scope and clarity: the nine-file patch is focused on a restart-scoped legacy-LDAP policy plus plugin compatibility tests. The plugin remains behaviorally independent and rejects zero-length credentials itself; its fe-common dependency is test-scoped.
  • Concurrency and lifecycle: ldap_allow_empty_pass is loaded from ldap.conf before FE services start, is non-mutable in production, and is read concurrently without writes. No lock, deadlock, static-initialization, resource-release, or ownership issue was found.
  • Configuration and compatibility: the setting follows the existing per-FE startup lifecycle; mixed-version/restart behavior is local to each FE. There is no storage format, serialized state, function-symbol, EditLog, transaction, or FE-BE protocol change. The insecure default is already covered by existing review discussion and is not duplicated here.
  • Parallel paths and conditions: all legacy MySQL and plain-password entry paths reach the gated overload chain. Native fallback, optional authentication-chain success, certificate-authenticated paths, and the newer LDAP plugin are separate mechanisms rather than gate bypasses.
  • Error handling and security: the boolean manager result loses the rejection cause, so both callers can issue the new policy error for ordinary failures. The new LDAP-specific failure text also creates a client-visible pre-auth LDAP-membership distinction, which is in scope under the repository threat model.
  • Tests and results: production gate ordering, flag-true versus flag-false failure semantics, both changed callers, and response neutrality are not covered. Live compile, CheckStyle, FE unit tests, regressions, and performance checks pass; FE coverage fails and the automated review check remains pending. Per the review contract, no local build was run; .worktree_initialized and thirdparty/installed/bin/protoc are absent, so validation was static plus live CI.
  • Observability and performance: the rejection log is consistent with existing authentication logging, and the constant-time check avoids cache/LDAP work when disabled. No additional metric or material CPU/memory issue was found.
  • Transactions, persistence, and data writes: not applicable; the patch changes no persisted metadata, master-failover path, data mutation, or result file.

Please address the three inline findings before approval.

throw new AuthenticationException(ErrorCode.ERR_EMPTY_PASSWORD, remoteUser + "@" + remoteHost);
} else {
throw new AuthenticationException(ErrorCode.ERR_ACCESS_DENIED_ERROR,
remoteUser + "@" + remoteHost + " via LDAP",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Keep failed authentication responses backend-neutral

This branch is reached only after doesUserExist(remoteUser) resolved the name in LDAP. Adding via LDAP therefore makes every nonempty bad password return a different client-visible message from a nonexistent or native user. BaseController returns formatErrMsg() in the HTTP unauthorized response body, and Arrow Flight includes e.getMessage() in its UNAUTHENTICATED description, so an unauthenticated caller can enumerate LDAP-backed accounts. Please keep the client response identical to the generic access-denied form and put the selected backend only in server-side debug/audit logs; the LDAP-only empty-password response needs the same neutrality.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correcting two inline anchors from review 4720137528; the finding bodies are unchanged.

LOG.debug("internalAuthenticate: user={}, success=false", userName);
}
ErrorReport.report(ErrorCode.ERR_ACCESS_DENIED_ERROR, qualifiedUser, remoteIp, usePasswd);
if (Strings.isNullOrEmpty(password)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Report the policy error only when the policy rejected the login

checkUserPasswd returns false for the null precondition, missing users, LDAP bind rejection, and operational LDAP failures as well as for the new policy gate. This branch looks only at the supplied password, so with the default ldap_allow_empty_pass=true an LDAP server that rejects an empty bind still produces error 6001 saying empty passwords are prohibited and advising the operator to enable an already-enabled flag. Auth.checkPlainPassword has the same branch (and Arrow Flight explicitly converts its empty-password sentinel to null). Please preserve a typed failure reason, or at minimum require !LdapConfig.ldap_allow_empty_pass before emitting ERR_EMPTY_PASSWORD; ordinary failures should retain their existing error.

@Test
public void testUserLoginWithEmptyLDAPPasswordDefault() {
LdapManager ldapManager = new LdapManager();
Assert.assertTrue(ldapManager.checkLoginWithEmptyPasswordForLdapIsAllowed("username", null));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Exercise the production empty-password chokepoint

These new tests call the helper directly, so they still pass if its invocation is deleted from LdapManager.checkUserPasswd or moved after the cached-password/LDAP-bind success paths. The existing manager test uses only nonempty passwords, LdapAuthenticatorTest mocks checkUserPasswd, and no Auth.checkPlainPassword test is changed despite the PR description claiming both caller suites. Please test an empty credential through checkUserPasswd with cached/client success under both flag values, assert the disabled case returns before those success paths, and cover both callers. Those caller assertions should distinguish a flag-disabled policy rejection from a flag-enabled empty-bind failure and keep LDAP-present/nonempty failures message-neutral with LDAP-absent/native failures.

@iaorekhov-1980
iaorekhov-1980 force-pushed the feat/disable_ldap_empty_pass branch from 2631282 to 29a1361 Compare July 17, 2026 15:13
@iaorekhov-1980
iaorekhov-1980 force-pushed the feat/disable_ldap_empty_pass branch from 29a1361 to 00b5785 Compare July 17, 2026 15:18
@iaorekhov-1980

Copy link
Copy Markdown
Contributor Author

run feut

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement] (auth) add configuration to support disable of login with empty LDAP password

7 participants