Skip to content

Commit

Permalink
Merge branch '389ds:main' into dev-container
Browse files Browse the repository at this point in the history
  • Loading branch information
slominskir authored Feb 20, 2024
2 parents 6d64a56 + aa3b4e6 commit 7a1ad80
Show file tree
Hide file tree
Showing 74 changed files with 802 additions and 512 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/coverity.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Coverity Scan

on:
schedule:
- cron: '30 9 * * 1'

jobs:
coverity:
runs-on: ubuntu-22.04

container:
image: quay.io/389ds/ci-images:fedora

steps:
- uses: actions/checkout@v4
- name: Checkout and configure
run: autoreconf -fvi && ./configure

- uses: vapier/coverity-scan-action@v1
with:
project: '389ds/389-ds-base'
command: make
email: ${{ secrets.COVERITY_SCAN_EMAIL }}
token: ${{ secrets.COVERITY_SCAN_TOKEN }}
29 changes: 29 additions & 0 deletions dirsrvtests/tests/suites/ds_logs/audit_log_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,35 @@ def test_auditlog_display_attrs(topo):
time.sleep(1)
assert inst.ds_audit_log.match("#sn: modrdn_delete")

def test_auditlog_bof(topo):
"""Test that value containing 256 chars doesn't crash the server
:id: 767c0604-146d-4d07-8bf4-1093f51ce97b
:setup: Standalone Instance
:steps:
1. Change 'cn' attribute to contain exactly 256 chars
2. Test that server didn't crash
:expectedresults:
1. Success
2. Success
"""

inst = topo.standalone
inst.config.replace('nsslapd-auditlog-logging-enabled', 'on')

inst.config.replace('nsslapd-auditlog-display-attrs', 'cn')
users = UserAccounts(inst, DEFAULT_SUFFIX)
user = users.ensure_state(properties={
'uid': 'test_auditlog_bof',
'cn': 'A'*256,
'sn': 'user',
'uidNumber': '1001',
'gidNumber': '1001',
'homeDirectory': '/home/auditlog_bof',
})
time.sleep(1)
assert inst.status() == True


if __name__ == '__main__':
# Run isolated
Expand Down
83 changes: 83 additions & 0 deletions dirsrvtests/tests/suites/password/pwp_history_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
import pytest
import time
import logging
import ldap
from lib389.tasks import *
from lib389.utils import ds_is_newer
from lib389.topologies import topology_st
from lib389.idm.user import UserAccounts, TEST_USER_PROPERTIES
from lib389.idm.directorymanager import DirectoryManager
from lib389.idm.organizationalunit import OrganizationalUnits
from lib389.passwd import password_hash
from lib389._constants import DEFAULT_SUFFIX

pytestmark = pytest.mark.tier1
Expand Down Expand Up @@ -325,6 +327,87 @@ def test_basic(topology_st, user):
# Done
log.info('Test suite PASSED.')

def test_prehashed_pwd(topology_st):
"""Test password history is updated with a pre-hashed password change
:id: 24d08663-f36a-44ab-8f02-b8a3f502925b
:setup: Standalone instance
:steps:
1. Configure password history policy as bellow:
passwordHistory: on
passwordChange: on
nsslapd-allow-hashed-passwords: on
2. Create ACI to allow users change their password
3. Add a test user
4. Attempt to change password using non hased value
5. Bind with non hashed value
6. Create a hash value for update
7. Update user password with hash value
8. Bind with hashed password cleartext
9. Check users passwordHistory
:expectedresults:
1. Password history policy should be configured successfully
2. ACI applied correctly
3. User successfully added
4. Password change accepted
5. Successful bind
6. Hash value created
7. Password change accepted
8. Successful bind
9. Users passwordHistory should contain 2 enteries
"""

# Configure password history policy and add a test user
try:
topology_st.standalone.config.replace_many(('passwordHistory', 'on'),
('passwordChange', 'on'),
('nsslapd-allow-hashed-passwords', 'on'))
log.info('Configured password policy.')
except ldap.LDAPError as e:
log.fatal('Failed to configure password policy: ' + str(e))
assert False
time.sleep(1)

# Add aci so users can change their own password
USER_ACI = '(targetattr="userpassword || passwordHistory")(version 3.0; acl "pwp test"; allow (all) userdn="ldap:///self";)'
ous = OrganizationalUnits(topology_st.standalone, DEFAULT_SUFFIX)
ou = ous.get('people')
ou.add('aci', USER_ACI)

# Create user
users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX)
user = users.create(properties=TEST_USER_PROPERTIES)
user.set('userpassword', 'password')
user.rebind('password')

# Change user pwd to generate a history of 1 entry
user.replace('userpassword', 'password1')
user.rebind('password1')

#Create pwd hash
pwd_hash = password_hash('password2', scheme='PBKDF2_SHA256', bin_dir=topology_st.standalone.ds_paths.bin_dir)
#log.info(pwd_hash)

# Update user pwd hash
user.replace('userpassword', pwd_hash)
time.sleep(2)

# Bind with hashed password
user.rebind('password2')

# Check password history
pwds = user.get_attr_vals('passwordHistory')
if len(pwds) != 2:
log.fatal('Incorrect number of passwords stored in history: %d' %
len(pwds))
log.error('password history: ' + str(pwds))
assert False
else:
log.info('Correct number of passwords found in history.')

# Done
log.info('Test suite PASSED.')

if __name__ == '__main__':
# Run isolated
Expand Down
27 changes: 25 additions & 2 deletions ldap/admin/src/logconv.pl
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@
my %cipher = ();
my @removefiles = ();

my @conncodes = qw(A1 B1 B4 T1 T2 B2 B3 R1 P1 P2 U1);
my @conncodes = qw(A1 B1 B4 T1 T2 T3 B2 B3 R1 P1 P2 U1);
my %conn = ();
map {$conn{$_} = $_} @conncodes;

Expand Down Expand Up @@ -355,6 +355,7 @@
$connmsg{"B4"} = "Server failed to flush data (response) back to Client";
$connmsg{"T1"} = "Idle Timeout Exceeded";
$connmsg{"T2"} = "IO Block Timeout Exceeded or NTSSL Timeout";
$connmsg{"T3"} = "Paged Search Time Limit Exceeded";
$connmsg{"B2"} = "Ber Too Big";
$connmsg{"B3"} = "Ber Peek";
$connmsg{"R1"} = "Revents";
Expand Down Expand Up @@ -1723,6 +1724,10 @@ sub dummy {
print "\n $recCount. You have some coonections that are being closed by the ioblocktimeout setting. You may want to increase the ioblocktimeout.\n";
$recCount++;
}
if (defined($conncount->{"T3"}) and $conncount->{"T3"} > 0){
print "\n $recCount. You have some connections that are being closed because a paged result search limit has been exceeded. You may want to increase the search time limit.\n";
$recCount++;
}
# compare binds to unbinds, if the difference is more than 30% of the binds, then report a issue
if (($bindCount - $unbindCount) > ($bindCount*.3)){
print "\n $recCount. You have a significant difference between binds and unbinds. You may want to investigate this difference.\n";
Expand Down Expand Up @@ -2366,6 +2371,7 @@ sub parseLineNormal
$brokenPipeCount++;
if (m/- T1/){ $hashes->{rc}->{"T1"}++; }
elsif (m/- T2/){ $hashes->{rc}->{"T2"}++; }
elsif (m/- T3/){ $hashes->{rc}->{"T3"}++; }
elsif (m/- A1/){ $hashes->{rc}->{"A1"}++; }
elsif (m/- B1/){ $hashes->{rc}->{"B1"}++; }
elsif (m/- B4/){ $hashes->{rc}->{"B4"}++; }
Expand All @@ -2381,6 +2387,7 @@ sub parseLineNormal
$connResetByPeerCount++;
if (m/- T1/){ $hashes->{src}->{"T1"}++; }
elsif (m/- T2/){ $hashes->{src}->{"T2"}++; }
elsif (m/- T3/){ $hashes->{src}->{"T3"}++; }
elsif (m/- A1/){ $hashes->{src}->{"A1"}++; }
elsif (m/- B1/){ $hashes->{src}->{"B1"}++; }
elsif (m/- B4/){ $hashes->{src}->{"B4"}++; }
Expand All @@ -2396,6 +2403,7 @@ sub parseLineNormal
$resourceUnavailCount++;
if (m/- T1/){ $hashes->{rsrc}->{"T1"}++; }
elsif (m/- T2/){ $hashes->{rsrc}->{"T2"}++; }
elsif (m/- T3/){ $hashes->{rsrc}->{"T3"}++; }
elsif (m/- A1/){ $hashes->{rsrc}->{"A1"}++; }
elsif (m/- B1/){ $hashes->{rsrc}->{"B1"}++; }
elsif (m/- B4/){ $hashes->{rsrc}->{"B4"}++; }
Expand Down Expand Up @@ -2494,6 +2502,20 @@ sub parseLineNormal
}
}
}
if (m/- T3/){
if ($_ =~ /conn= *([0-9A-Z]+)/i) {
$exc = "no";
$ip = getIPfromConn($1, $serverRestartCount);
for (my $xxx = 0; $xxx < $#excludeIP; $xxx++){
if ($ip eq $excludeIP[$xxx]){$exc = "yes";}
}
if ($exc ne "yes"){
$hashes->{T3}->{$ip}++;
$hashes->{conncount}->{"T3"}++;
$connCodeCount++;
}
}
}
if (m/- B2/){
if ($_ =~ /conn= *([0-9A-Z]+)/i) {
$exc = "no";
Expand Down Expand Up @@ -2852,12 +2874,13 @@ sub parseLineNormal
$stats->{'unbind'},
$stats->{'notesA'},
$stats->{'notesU'},
$stats->{'notesF'},
$stats->{'etime'}),
"\n" );
} else {
$stats->{'fh'}->print(
"Time,time_t,Results,Search,Add,Mod,Modrdn,Moddn,Compare,Delete,Abandon,".
"Connections,SSL Conns,Bind,Anon Bind,Unbind,Unindexed search,Unindexed component,ElapsedTime\n"
"Connections,SSL Conns,Bind,Anon Bind,Unbind,Unindexed search,Unindexed component,Invalid filter,ElapsedTime\n"
);
}
}
Expand Down
6 changes: 3 additions & 3 deletions ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
* END COPYRIGHT BLOCK **/


#include <sys/types.h>
#include <sys/statvfs.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "bdb_layer.h"
#include <sys/types.h>
#include <sys/statvfs.h>
#include <prthread.h>
#include <prclist.h>
#include <glob.h>
Expand Down Expand Up @@ -7198,7 +7198,7 @@ bdb_dblayer_cursor_iterate(dbi_cursor_t *cursor, dbi_iterate_cb_t *action_cb,
dbi_val_t key = {0};
dbi_val_t data = {0};
int rc = 0;

if (bdb_cur == NULL) {
return DBI_RC_INVALID;
}
Expand Down
4 changes: 2 additions & 2 deletions ldap/servers/slapd/daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -1567,9 +1567,9 @@ setup_pr_read_pds(Connection_Table *ct, int listnum)
int add_fd = 1;
/* check timeout for PAGED RESULTS */
if (pagedresults_is_timedout_nolock(c)) {
/* Exceeded the timelimit; disconnect the client */
/* Exceeded the paged search timelimit; disconnect the client */
disconnect_server_nomutex(c, c->c_connid, -1,
SLAPD_DISCONNECT_IO_TIMEOUT,
SLAPD_DISCONNECT_PAGED_SEARCH_LIMIT,
0);
connection_table_move_connection_out_of_active_list(ct,
c);
Expand Down
1 change: 1 addition & 0 deletions ldap/servers/slapd/disconnect_error_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ ER2(SLAPD_DISCONNECT_BER_FLUSH, "Server failed to flush response back to Client
ER2(SLAPD_DISCONNECT_IDLE_TIMEOUT, "Idle Timeout (nsslapd-idletimeout) - T1")
ER2(SLAPD_DISCONNECT_REVENTS, "Poll revents - R1")
ER2(SLAPD_DISCONNECT_IO_TIMEOUT, "IO Block Timeout (nsslapd-ioblocktimeout) - T2")
ER2(SLAPD_DISCONNECT_PAGED_SEARCH_LIMIT, "Paged Search Time Limit Exceeded - T3")
ER2(SLAPD_DISCONNECT_PLUGIN, "Plugin - P1")
ER2(SLAPD_DISCONNECT_UNBIND, "Cleanly Closed Connection - U1")
ER2(SLAPD_DISCONNECT_POLL, "Poll - P2")
Expand Down
2 changes: 1 addition & 1 deletion ldap/servers/slapd/disconnect_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@
#define SLAPD_DISCONNECT_SASL_FAIL SLAPD_DISCONNECT_ERROR_BASE + 12
#define SLAPD_DISCONNECT_PROXY_INVALID_HEADER SLAPD_DISCONNECT_ERROR_BASE + 13
#define SLAPD_DISCONNECT_PROXY_UNKNOWN SLAPD_DISCONNECT_ERROR_BASE + 14

#define SLAPD_DISCONNECT_PAGED_SEARCH_LIMIT SLAPD_DISCONNECT_ERROR_BASE + 15

#endif /* __DISCONNECT_ERRORS_H_ */
22 changes: 20 additions & 2 deletions ldap/servers/slapd/pw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,7 @@ int
check_pw_syntax_ext(Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, char **old_pw, Slapi_Entry *e, int mod_op, Slapi_Mods *smods)
{
Slapi_Attr *attr;
Slapi_Value **va = NULL;
int i, pwresponse_req = 0;
int is_replication = 0;
int internal_op = 0;
Expand Down Expand Up @@ -1124,7 +1125,24 @@ check_pw_syntax_ext(Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, c
report_pw_violation(pb, dn, pwresponse_req, "invalid password syntax - passwords with storage scheme are not allowed");
return (1);
} else {
/* We want to skip syntax checking since this is a pre-hashed password */
/* We want to skip syntax checking since this is a pre-hashed password. But if the user
* has thrown caution to wind and allowed hashed passwords, we capture the history
*/
if (config_get_allow_hashed_pw() && pwpolicy->pw_history) {
e = get_entry(pb, dn);
if (e == NULL) {
return -1;
}
attr = attrlist_find(e->e_attrs, SLAPI_USERPWD_ATTR);
if (attr && !valueset_isempty(&attr->a_present_values)) {
if (old_pw && (va = valueset_get_valuearray(&attr->a_present_values))) {
*old_pw = slapi_ch_strdup(slapi_value_get_string(va[0]));
} else {
*old_pw = NULL;
}
}
slapi_entry_free(e);
}
return (0);
}
}
Expand Down Expand Up @@ -1335,7 +1353,6 @@ check_pw_syntax_ext(Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, c

/* check for password history */
if (pwpolicy->pw_history == 1) {
Slapi_Value **va = NULL;
attr = attrlist_find(e->e_attrs, "passwordHistory");
if (pwpolicy->pw_inhistory && attr && !valueset_isempty(&attr->a_present_values)) {
/* Resetting password history array if necessary. */
Expand Down Expand Up @@ -1908,6 +1925,7 @@ pw_is_pwp_admin(Slapi_PBlock *pb, passwdPolicy *pwp, int rootdn_flag)
/* first check if it's root */
if (is_requestor_root && rootdn_flag == PWP_ADMIN_OR_ROOTDN) {
return 1;

}
/* now check if it's a Password Policy Administrator */
slapi_pblock_get(pb, SLAPI_REQUESTOR_SDN, &bind_sdn);
Expand Down
1 change: 1 addition & 0 deletions ldap/servers/slapd/slap.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ static char ptokPBE[34] = "Internal (Software) Token ";
#include <cert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/socket.h>
#include <netinet/in.h>

Expand Down
11 changes: 2 additions & 9 deletions src/lib389/cli/dsconf
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,13 @@ from lib389.cli_base import disconnect_instance, connect_instance
from lib389.cli_base.dsrc import dsrc_to_ldap, dsrc_arg_concat
from lib389.cli_base import setup_script_logger
from lib389.cli_base import format_error_to_dict
from lib389.cli_base import parent_argparser
from lib389.utils import instance_choices

parser = argparse.ArgumentParser(allow_abbrev=True)
parser = argparse.ArgumentParser(allow_abbrev=True, parents=[parent_argparser])
parser.add_argument('instance',
help="The name of the instance or its LDAP URL, such as ldap://server.example.com:389",
).completer = instance_choices
parser.add_argument('-v', '--verbose',
help="Display verbose operation tracing during command execution",
action='store_true', default=False
)
parser.add_argument('-D', '--binddn',
help="The account to bind as for executing operations",
default=None
Expand All @@ -67,10 +64,6 @@ parser.add_argument('-Z', '--starttls',
help="Connect with StartTLS",
default=False, action='store_true'
)
parser.add_argument('-j', '--json',
help="Return result in JSON object",
default=False, action='store_true'
)

subparsers = parser.add_subparsers(help="resources to act upon")

Expand Down
Loading

0 comments on commit 7a1ad80

Please sign in to comment.