Skip to content

Commit

Permalink
Merge pull request #8457 from RocketChat/improvements/ldap-memory-leak
Browse files Browse the repository at this point in the history
[FIX] LDAP memory issues when pagination is not available
  • Loading branch information
rodrigok committed Oct 11, 2017
1 parent 2d95ca1 commit 47afc0b
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 32 deletions.
65 changes: 46 additions & 19 deletions packages/rocketchat-ldap/server/ldap.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,15 @@ export default class LDAP {
const searchOptions = {
filter: this.getUserFilter(username),
scope: this.options.User_Search_Scope || 'sub',
sizeLimit: this.options.Search_Size_Limit,
paged: {
sizeLimit: this.options.Search_Size_Limit
};

if (this.options.Search_Page_Size > 0) {
searchOptions.paged = {
pageSize: this.options.Search_Page_Size,
pagePause: !!page
}
};
};
}

logger.search.info('Searching user', username);
logger.search.debug('searchOptions', searchOptions);
Expand Down Expand Up @@ -362,23 +365,50 @@ export default class LDAP {
});

let entries = [];
const jsonEntries = [];

const internalPageSize = options.paged && options.paged.pageSize > 0 ? options.paged.pageSize * 2 : 500;

res.on('searchEntry', (entry) => {
entries.push(entry);
jsonEntries.push(entry.json);
const values = entry.raw;
Object.keys(values).forEach((key) => {
const value = values[key];
if (!['thumbnailPhoto', 'jpegPhoto'].includes(key) && value instanceof Buffer) {
values[key] = value.toString();
}
});

entries.push(values);

if (entries.length >= internalPageSize) {
logger.search.info('Internal Page');
this.client._updateIdle(true);
page(null, entries, {end: false, next: () => {
// Reset idle timer
this.client._updateIdle();
}});
entries = [];
}
});

res.on('page', (result, next) => {
logger.search.debug('Page');
// Force LDAP idle to wait the record processing
this.client._updateIdle(true);
page(null, entries, {end: !next, next: () => {
// Reset idle timer
this.client._updateIdle();
next && next();
}});
entries = [];
if (!next) {
logger.search.debug('Final Page');
this.client._updateIdle(true);
page(null, entries, {end: true, next: () => {
// Reset idle timer
this.client._updateIdle();
}});
} else if (entries.length) {
logger.search.info('Page');
// Force LDAP idle to wait the record processing
this.client._updateIdle(true);
page(null, entries, {end: !next, next: () => {
// Reset idle timer
this.client._updateIdle();
next();
}});
entries = [];
}
});
});
}
Expand All @@ -400,16 +430,13 @@ export default class LDAP {
});

const entries = [];
const jsonEntries = [];

res.on('searchEntry', (entry) => {
entries.push(entry);
jsonEntries.push(entry.json);
});

res.on('end', () => {
logger.search.info('Search result count', entries.length);
// logger.search.debug('Search result', JSON.stringify(jsonEntries, null, 2));
callback(null, entries);
});
});
Expand Down
26 changes: 13 additions & 13 deletions packages/rocketchat-ldap/server/sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ export function getLdapUsername(ldapUser) {

if (usernameField.indexOf('#{') > -1) {
return usernameField.replace(/#{(.+?)}/g, function(match, field) {
return ldapUser.object[field];
return ldapUser[field];
});
}

return ldapUser.object[usernameField];
return ldapUser[usernameField];
}


Expand All @@ -47,12 +47,12 @@ export function getLdapUserUniqueID(ldapUser) {

if (Unique_Identifier_Field.length > 0) {
Unique_Identifier_Field = Unique_Identifier_Field.find((field) => {
return !_.isEmpty(ldapUser.object[field]);
return !_.isEmpty(ldapUser[field]);
});
if (Unique_Identifier_Field) {
Unique_Identifier_Field = {
attribute: Unique_Identifier_Field,
value: ldapUser.raw[Unique_Identifier_Field].toString('hex')
value: new Buffer(ldapUser[Unique_Identifier_Field]).toString('hex')
};
}
return Unique_Identifier_Field;
Expand All @@ -72,17 +72,17 @@ export function getDataToSyncUserData(ldapUser, user) {
_.map(fieldMap, function(userField, ldapField) {
switch (userField) {
case 'email':
if (!ldapUser.object.hasOwnProperty(ldapField)) {
if (!ldapUser.hasOwnProperty(ldapField)) {
logger.debug(`user does not have attribute: ${ ldapField }`);
return;
}

if (_.isObject(ldapUser.object[ldapField])) {
_.map(ldapUser.object[ldapField], function(item) {
if (_.isObject(ldapUser[ldapField])) {
_.map(ldapUser[ldapField], function(item) {
emailList.push({ address: item, verified: true });
});
} else {
emailList.push({ address: ldapUser.object[ldapField], verified: true });
emailList.push({ address: ldapUser[ldapField], verified: true });
}
break;

Expand All @@ -92,7 +92,7 @@ export function getDataToSyncUserData(ldapUser, user) {
return;
}

const tmpLdapField = RocketChat.templateVarHandler(ldapField, ldapUser.object);
const tmpLdapField = RocketChat.templateVarHandler(ldapField, ldapUser);
const userFieldValue = _.reduce(userField.split('.'), (acc, el) => acc[el], user);

if (tmpLdapField && userFieldValue !== tmpLdapField) {
Expand Down Expand Up @@ -129,7 +129,7 @@ export function getDataToSyncUserData(ldapUser, user) {
export function syncUserData(user, ldapUser) {
logger.info('Syncing user data');
logger.debug('user', {'email': user.email, '_id': user._id});
logger.debug('ldapUser', ldapUser.object);
logger.debug('ldapUser', ldapUser);

const userData = getDataToSyncUserData(ldapUser, user);
if (user && user._id && userData) {
Expand All @@ -151,7 +151,7 @@ export function syncUserData(user, ldapUser) {
}

if (user && user._id && RocketChat.settings.get('LDAP_Sync_User_Avatar') === true) {
const avatar = ldapUser.raw.thumbnailPhoto || ldapUser.raw.jpegPhoto;
const avatar = ldapUser.thumbnailPhoto || ldapUser.jpegPhoto;
if (avatar) {
logger.info('Syncing user avatar');

Expand Down Expand Up @@ -193,8 +193,8 @@ export function addLdapUser(ldapUser, username, password) {
} else {
userObject.email = userData.emails[0].address;
}
} else if (ldapUser.object.mail && ldapUser.object.mail.indexOf('@') > -1) {
userObject.email = ldapUser.object.mail;
} else if (ldapUser.mail && ldapUser.mail.indexOf('@') > -1) {
userObject.email = ldapUser.mail;
} else if (RocketChat.settings.get('LDAP_Default_Domain') !== '') {
userObject.email = `${ username || uniqueId.value }@${ RocketChat.settings.get('LDAP_Default_Domain') }`;
} else {
Expand Down

0 comments on commit 47afc0b

Please sign in to comment.