mecano
Version:
Common functions for system deployment.
206 lines (200 loc) • 6.72 kB
JavaScript
// Generated by CoffeeScript 1.11.1
var each, ldap, misc, string;
module.exports = function(options, callback) {
var modified;
if (options.acls == null) {
options.acls = [{}];
}
modified = false;
return each(options.acls).call((function(_this) {
return function(acl, callback) {
var do_diff, do_end, do_getacls, do_getdn, do_save;
do_getdn = function() {
if (options.hdb_dn) {
return do_getacls();
}
options.log({
message: "Get DN of the HDB to modify",
level: 'DEBUG',
module: 'mecano/ldap/acl'
});
return _this.execute({
cmd: "ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b cn=config \"(olcSuffix= " + options.suffix + ")\" dn 2>/dev/null | egrep '^dn' | sed -e 's/^dn:\\s*olcDatabase=\\(.*\\)$/\\1/g'"
}, function(err, _, hdb_dn) {
if (err) {
return callback(err);
}
options.hdb_dn = hdb_dn.trim();
return do_getacls();
});
};
do_getacls = function() {
options.log({
message: "List all ACL of the directory",
level: 'DEBUG',
module: 'mecano/ldap/acl'
});
return _this.execute({
cmd: "ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b olcDatabase=" + options.hdb_dn + " \"(olcAccess=*)\" olcAccess"
}, function(err, _, stdout) {
var current, j, len, line, match, olcAccesses, ref;
if (err) {
return callback(err);
}
current = null;
olcAccesses = [];
ref = string.lines(stdout);
for (j = 0, len = ref.length; j < len; j++) {
line = ref[j];
if (match = /^olcAccess: (.*)$/.exec(line)) {
if (current != null) {
olcAccesses.push(current);
}
current = match[1];
} else if (current != null) {
if (/^ /.test(line)) {
current += line.substr(1);
} else {
olcAccesses.push(current);
current = null;
}
}
}
return do_diff(ldap.acl.parse(olcAccesses));
});
};
do_diff = function(olcAccesses) {
var access, access_by, acl_by, found, i, index, is_perfect_match, j, k, l, len, len1, len2, len3, len4, len5, m, n, not_found_acl, o, olcAccess, ref, ref1, ref2;
olcAccess = null;
for (i = j = 0, len = olcAccesses.length; j < len; i = ++j) {
access = olcAccesses[i];
if (acl.to === access.to) {
olcAccess = misc.object.clone(access);
olcAccess.old = access;
break;
}
}
if (olcAccess) {
is_perfect_match = true;
not_found_acl = [];
if (acl.by.length !== olcAccess.by.length) {
is_perfect_match = false;
} else {
ref = acl.by;
for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
acl_by = ref[i];
if (acl_by !== olcAccess.by[i]) {
is_perfect_match = false;
}
found = true;
ref1 = olcAccess.by;
for (l = 0, len2 = ref1.length; l < len2; l++) {
access_by = ref1[l];
if (acl_by !== access_by) {
found = false;
}
}
if (!found) {
not_found_acl.push(acl_by);
}
}
}
if (is_perfect_match) {
options.log({
message: "No modification to apply",
level: 'INFO',
module: 'mecano/ldap/acl'
});
return do_end();
}
if (not_found_acl.length) {
options.log({
message: "Modify access after undefined acl",
level: 'INFO',
module: 'mecano/ldap/acl'
});
ref2 = olcAccess.by;
for (m = 0, len3 = ref2.length; m < len3; m++) {
access_by = ref2[m];
not_found_acl.push(access_by);
}
olcAccess.by = not_found_acl;
} else {
options.log({
message: "Modify access after reorder",
level: 'INFO',
module: 'mecano/ldap/acl'
});
if (typeof options.log === "function") {
options.log('mecano `ldap.acl`: m');
}
olcAccess.by = acl.by;
}
} else {
options.log({
message: "Insert a new access",
level: 'INFO',
module: 'mecano/ldap/acl'
});
index = olcAccesses.length;
if (acl.first) {
index = 0;
}
if (acl.place_before) {
for (i = n = 0, len4 = olcAccesses.length; n < len4; i = ++n) {
access = olcAccesses[i];
if (access.to === acl.place_before) {
index = i;
}
}
} else if (acl.after) {
for (i = o = 0, len5 = olcAccesses.length; o < len5; i = ++o) {
access = olcAccesses[i];
if (access.to === options.after) {
index = i + 1;
}
}
}
olcAccess = {
index: index,
to: acl.to,
by: acl.by,
add: true
};
}
return do_save(olcAccess);
};
do_save = function(olcAccess) {
var cmd, old;
if (olcAccess.old) {
old = ldap.acl.stringify(olcAccess.old);
}
olcAccess = ldap.acl.stringify(olcAccess);
if (old) {
cmd = "ldapadd -Y EXTERNAL -H ldapi:/// <<-EOF\ndn: olcDatabase=" + options.hdb_dn + "\nchangetype: modify\ndelete: olcAccess\nolcAccess: " + old + "\n-\nadd: olcAccess\nolcAccess: " + olcAccess + "\nEOF";
} else {
cmd = "ldapadd -Y EXTERNAL -H ldapi:/// <<-EOF\ndn: olcDatabase=" + options.hdb_dn + "\nchangetype: modify\nadd: olcAccess\nolcAccess: " + olcAccess + "\nEOF";
}
return _this.execute({
cmd: cmd
}, function(err, _, hdb_dn) {
if (err) {
return callback(err);
}
modified = true;
return do_end();
});
};
do_end = function() {
return callback();
};
return do_getdn();
};
})(this)).then(function(err) {
return callback(err, modified);
});
};
each = require('each');
misc = require('../misc');
ldap = require('../misc/ldap');
string = require('../misc/string');