"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "msktldap.cpp" between
msktutil-1.1.tar.bz2 and msktutil-1.2.1.tar.gz

About: msktutil is a program for interoperability with Active Directory.

msktldap.cpp  (msktutil-1.1.tar.bz2):msktldap.cpp  (msktutil-1.2.1)
skipping to change at line 37 skipping to change at line 37
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*----------------------------------------------------------------------------- *-----------------------------------------------------------------------------
*/ */
#include "msktutil.h" #include "msktutil.h"
#include <algorithm> #include <algorithm>
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
/* Check if string <s> ends with string <suffix> */
static bool endswith(std::string const &s, std::string const &suffix)
{
if (s.length() < suffix.length())
return false;
return s.compare(s.length() - suffix.length(),
suffix.length(), suffix) == 0;
}
void get_default_ou(msktutil_flags *flags) void get_default_ou(msktutil_flags *flags)
{ {
if (flags->ldap_ou.empty()) { /* If OU was given explicitly, we just need to make sure it's a
/* Only do this on an empty value */ * valid dn below our base dn.
*/
if (!flags->ldap_ou.empty()) {
if (!endswith(flags->ldap_ou, flags->base_dn))
flags->ldap_ou = flags->ldap_ou + "," + flags->base_dn;
VERBOSE("Using OU: %s", flags->ldap_ou.c_str());
return;
}
LDAPConnection *ldap = flags->ldap; /* Otherwise, probe AD for its default OU */
std::string wkguid; LDAPConnection *ldap = flags->ldap;
if (flags->use_service_account) {
wkguid = sform("<WKGUID=a9d1ca15768811d1aded00c04fd8d5cd,%s>",
flags->base_dn.c_str());
} else {
wkguid = sform("<WKGUID=aa312825768811d1aded00c04fd8d5cd,%s>",
flags->base_dn.c_str());
}
LDAPMessage *mesg = ldap->search(wkguid, LDAP_SCOPE_BASE,
"objectClass=*",
"distinguishedName");
std::string dn; std::string wkguid;
if (ldap->count_entries(mesg) == 1) { if (flags->use_service_account) {
mesg = ldap->first_entry(mesg); wkguid = sform("<WKGUID=a9d1ca15768811d1aded00c04fd8d5cd,%s>",
dn = ldap->get_one_val(mesg, "distinguishedName"); flags->base_dn.c_str());
} } else {
ldap_msgfree(mesg); wkguid = sform("<WKGUID=aa312825768811d1aded00c04fd8d5cd,%s>",
if (dn.empty()) { flags->base_dn.c_str());
fprintf(stderr, }
"Warning: could not get default computer OU from AD.\n" LDAPMessage *mesg = ldap->search(wkguid, LDAP_SCOPE_BASE,
); "objectClass=*",
flags->ldap_ou = "CN=Computers," + flags->base_dn; "distinguishedName");
} else {
flags->ldap_ou = dn; std::string dn;
} if (ldap->count_entries(mesg) == 1) {
VERBOSE("Determining default OU: %s", flags->ldap_ou.c_str()); mesg = ldap->first_entry(mesg);
dn = ldap->get_one_val(mesg, "distinguishedName");
}
ldap_msgfree(mesg);
if (dn.empty()) {
fprintf(stderr,
"Warning: could not get default computer OU from AD.\n"
);
std::string default_ou = flags->use_service_account ?
"CN=Users," : "CN=Computers,";
flags->ldap_ou = default_ou + flags->base_dn;
} else { } else {
flags->ldap_ou = flags->ldap_ou + "," + flags->base_dn; flags->ldap_ou = dn;
} }
VERBOSE("Determined default OU: %s", flags->ldap_ou.c_str());
} }
void ldap_get_base_dn(msktutil_flags *flags) void ldap_get_base_dn(msktutil_flags *flags)
{ {
if (flags->base_dn.empty()) { if (flags->base_dn.empty()) {
std::string out; std::string out;
bool first = true; bool first = true;
std::string &base = flags->realm_name; std::string &base = flags->realm_name;
size_t last_pos = 0; size_t last_pos = 0;
skipping to change at line 96 skipping to change at line 113
if (first) { if (first) {
out.append("dc="); out.append("dc=");
first = false; first = false;
} else } else
out.append(",dc="); out.append(",dc=");
out.append(base.substr(last_pos, pos - last_pos)); out.append(base.substr(last_pos, pos - last_pos));
last_pos = pos + 1; last_pos = pos + 1;
} while (last_pos != 0); } while (last_pos != 0);
flags->base_dn = out; flags->base_dn = out;
VERBOSE("Determining default LDAP base: %s", flags->base_dn.c_str()); VERBOSE("Determined default LDAP base: %s", flags->base_dn.c_str());
} }
} }
void ldap_cleanup(msktutil_flags *flags) void ldap_cleanup(msktutil_flags *flags)
{ {
VERBOSE("Disconnecting from LDAP server"); VERBOSE("Disconnecting from LDAP server");
delete flags->ldap; delete flags->ldap;
flags->ldap = NULL; flags->ldap = NULL;
} }
skipping to change at line 188 skipping to change at line 205
/* This must be a Windows 2000 domain, which does support /* This must be a Windows 2000 domain, which does support
* have KVNO's. */ * have KVNO's. */
kvno = KVNO_WIN_2000; kvno = KVNO_WIN_2000;
VERBOSE("Unable to find KVNO attribute on domain controller " VERBOSE("Unable to find KVNO attribute on domain controller "
"%s - This must be running windows 2000", "%s - This must be running windows 2000",
flags->server.c_str()); flags->server.c_str());
} }
} }
ldap_msgfree(mesg); ldap_msgfree(mesg);
VERBOSE("KVNO is %d", kvno); VERBOSE("Found KVNO: %d", kvno);
return kvno; return kvno;
} }
std::string ldap_get_pwdLastSet(msktutil_flags *flags) std::string ldap_get_pwdLastSet(msktutil_flags *flags)
{ {
std::string pwdLastSet; std::string pwdLastSet;
const char *attrs[] = {"pwdLastSet", NULL}; const char *attrs[] = {"pwdLastSet", NULL};
LDAPConnection *ldap = flags->ldap; LDAPConnection *ldap = flags->ldap;
skipping to change at line 356 skipping to change at line 373
} }
break; break;
case 1: { case 1: {
/* Check if we are the owner of the this principal or /* Check if we are the owner of the this principal or
* not */ * not */
mesg = ldap->first_entry(mesg); mesg = ldap->first_entry(mesg);
std::string found_dn = flags->ldap->get_one_val(mesg, std::string found_dn = flags->ldap->get_one_val(mesg,
"distinguishedName") ; "distinguishedName") ;
if (found_dn.empty()) { if (found_dn.empty()) {
fprintf(stderr, fprintf(stderr,
"Error: Inconsistent LDAP entry: No DN value present\n" "Error: inconsistent LDAP entry: No DN value present\n"
); );
ret = -1; ret = -1;
} else if (dn != found_dn) { } else if (dn != found_dn) {
fprintf(stderr, fprintf(stderr,
"Error: Another computer account (%s) has the " "Error: another computer account (%s) has the "
"principal %s\n", "principal %s\n",
found_dn.c_str(), found_dn.c_str(),
principal.c_str() principal.c_str()
); );
ret = -1; ret = -1;
} else } else
ret = 0; ret = 0;
break; break;
} }
default: default:
fprintf(stderr, fprintf(stderr,
"Error: Multiple (%d) LDAP entries were found containing " "Error: multiple (%d) LDAP entries were found containing "
"the principal %s\n", "the principal %s\n",
num_entries, num_entries,
principal.c_str() principal.c_str()
); );
ret = num_entries; ret = num_entries;
} }
ldap_msgfree(mesg); ldap_msgfree(mesg);
return ret; return ret;
} }
skipping to change at line 451 skipping to change at line 468
flags->realm_name.c_str()); flags->realm_name.c_str());
} }
/* let's see if userPrincipalName is already set to the /* let's see if userPrincipalName is already set to the
* desired value in AD... */ * desired value in AD... */
LDAPMessage *mesg = ldap_get_account_attrs(flags, attrs); LDAPMessage *mesg = ldap_get_account_attrs(flags, attrs);
if (ldap->count_entries(mesg) == 1) { if (ldap->count_entries(mesg) == 1) {
mesg = ldap->first_entry(mesg); mesg = ldap->first_entry(mesg);
upn_found = ldap->get_one_val(mesg, "userPrincipalName"); upn_found = ldap->get_one_val(mesg, "userPrincipalName");
} }
ldap_msgfree(mesg); ldap_msgfree(mesg);
VERBOSE("Found userPrincipalName = %s", upn_found.c_str()); VERBOSE("Found userPrincipalName: %s", upn_found.c_str());
VERBOSE("userPrincipalName should be %s", VERBOSE("userPrincipalName should be %s",
userPrincipalName_string.c_str()); userPrincipalName_string.c_str());
if (upn_found.compare(userPrincipalName_string)) { if (upn_found.compare(userPrincipalName_string)) {
ldap_simple_set_attr(dn, ldap_simple_set_attr(dn,
"userPrincipalName", "userPrincipalName",
userPrincipalName_string, userPrincipalName_string,
flags); flags);
} else { } else {
VERBOSE("Nothing to do"); VERBOSE("Nothing to do");
} }
} }
ldap_set_supportedEncryptionTypes(dn, flags); ldap_set_supportedEncryptionTypes(dn, flags);
msktutil_val des_only; msktutil_val des_only;
if (flags->supportedEncryptionTypes == (MS_KERB_ENCTYPE_DES_CBC_CRC | if (flags->supportedEncryptionTypes == MS_KERB_DES_ENCTYPES) {
MS_KERB_ENCTYPE_DES_CBC_MD5)) {
des_only = VALUE_ON; des_only = VALUE_ON;
} else { } else {
des_only = VALUE_OFF; des_only = VALUE_OFF;
} }
ldap_set_userAccountControl_flag(dn, UF_USE_DES_KEY_ONLY, des_only, flags); ldap_set_userAccountControl_flag(dn, UF_USE_DES_KEY_ONLY, des_only, flags);
/* If msDS-supportedEncryptionTypes isn't set, ad_enctypes will be /* If msDS-supportedEncryptionTypes isn't set, ad_enctypes will be
* VALUE_OFF. In that case, reset ad_supportedEncryptionTypes * VALUE_OFF. In that case, reset ad_supportedEncryptionTypes
* according to the DES flag, in case we changed it. */ * according to the DES flag, in case we changed it. */
if (flags->ad_enctypes == VALUE_OFF) { if (flags->ad_enctypes == VALUE_OFF) {
flags->ad_supportedEncryptionTypes = flags->ad_supportedEncryptionTypes = MS_KERB_DES_ENCTYPES;
MS_KERB_ENCTYPE_DES_CBC_CRC | if (!(flags->ad_userAccountControl & UF_USE_DES_KEY_ONLY)) {
MS_KERB_ENCTYPE_DES_CBC_MD5;
if (! (flags->ad_userAccountControl & UF_USE_DES_KEY_ONLY)) {
flags->ad_supportedEncryptionTypes |= MS_KERB_ENCTYPE_RC4_HMAC_MD5; flags->ad_supportedEncryptionTypes |= MS_KERB_ENCTYPE_RC4_HMAC_MD5;
} }
} }
ldap_set_userAccountControl_flag(dn, ldap_set_userAccountControl_flag(dn,
UF_NO_AUTH_DATA_REQUIRED, UF_NO_AUTH_DATA_REQUIRED,
flags->no_pac, flags->no_pac,
flags); flags);
ldap_set_userAccountControl_flag(dn, ldap_set_userAccountControl_flag(dn,
UF_TRUSTED_FOR_DELEGATION, UF_TRUSTED_FOR_DELEGATION,
skipping to change at line 558 skipping to change at line 572
flags->sAMAccountName.c_str()); flags->sAMAccountName.c_str());
mesg = ldap_get_account_attrs(flags, machine_attrs); mesg = ldap_get_account_attrs(flags, machine_attrs);
} }
if (ldap->count_entries(mesg) == 0) { if (ldap->count_entries(mesg) == 0) {
return false; return false;
} }
/* Account already exists */ /* Account already exists */
if (flags->use_service_account) { if (flags->use_service_account) {
VERBOSE("Checking service account - found"); VERBOSE("Found service account");
} else { } else {
VERBOSE("Checking computer account - found"); VERBOSE("Found computer account");
} }
mesg = ldap->first_entry(mesg); mesg = ldap->first_entry(mesg);
flags->ad_computerDn = ldap->get_one_val(mesg, "distinguishedName"); flags->ad_computerDn = ldap->get_one_val(mesg, "distinguishedName");
std::string uac = ldap->get_one_val(mesg, "userAccountControl"); std::string uac = ldap->get_one_val(mesg, "userAccountControl");
if (!uac.empty()) { if (!uac.empty()) {
flags->ad_userAccountControl = atoi(uac.c_str()); flags->ad_userAccountControl = atoi(uac.c_str());
VERBOSE("Found userAccountControl = 0x%x", flags->ad_userAccountControl) ; VERBOSE("Found userAccountControl: 0x%x", flags->ad_userAccountControl);
} }
/* save the current msDs-supportedEncryptionTypes */ /* save the current msDs-supportedEncryptionTypes */
std::string supportedEncryptionTypes = std::string supportedEncryptionTypes =
flags->ldap->get_one_val(mesg, "msDs-supportedEncryptionTypes"); flags->ldap->get_one_val(mesg, "msDs-supportedEncryptionTypes");
if (!supportedEncryptionTypes.empty()) { if (!supportedEncryptionTypes.empty()) {
flags->ad_supportedEncryptionTypes = atoi(supportedEncryptionTypes.c_str ()); flags->ad_supportedEncryptionTypes = atoi(supportedEncryptionTypes.c_str ());
flags->ad_enctypes = VALUE_ON; /* actual value found in AD */ flags->ad_enctypes = VALUE_ON; /* actual value found in AD */
VERBOSE("Found supportedEncryptionTypes = %d", VERBOSE("Found supportedEncryptionTypes: %d",
flags->ad_supportedEncryptionTypes); flags->ad_supportedEncryptionTypes);
} else { } else {
/* Not in current LDAP entry set defaults */ /* Not in current LDAP entry set defaults */
flags->ad_supportedEncryptionTypes = flags->ad_supportedEncryptionTypes = MS_KERB_DES_ENCTYPES;
MS_KERB_ENCTYPE_DES_CBC_CRC | if (!(flags->ad_userAccountControl & UF_USE_DES_KEY_ONLY)) {
MS_KERB_ENCTYPE_DES_CBC_MD5;
if (! (flags->ad_userAccountControl & UF_USE_DES_KEY_ONLY)) {
flags->ad_supportedEncryptionTypes |= MS_KERB_ENCTYPE_RC4_HMAC_MD5; flags->ad_supportedEncryptionTypes |= MS_KERB_ENCTYPE_RC4_HMAC_MD5;
} }
flags->ad_enctypes = VALUE_OFF; /* this is the assumed default */ flags->ad_enctypes = VALUE_OFF; /* this is the assumed default */
VERBOSE("Found default supportedEncryptionTypes = %d", VERBOSE("Found default supportedEncryptionTypes: %d",
flags->ad_supportedEncryptionTypes); flags->ad_supportedEncryptionTypes);
} }
if (!flags->use_service_account) { if (!flags->use_service_account) {
/* Save current dNSHostName */ /* Save current dNSHostName */
flags->ad_dnsHostName = ldap->get_one_val(mesg, "dNSHostName"); flags->ad_dnsHostName = ldap->get_one_val(mesg, "dNSHostName");
VERBOSE("Found dNSHostName = %s", flags->ad_dnsHostName.c_str()); VERBOSE("Found dNSHostName: %s", flags->ad_dnsHostName.c_str());
} }
/* Save current servicePrincipalName and userPrincipalName /* Save current servicePrincipalName and userPrincipalName
* attrs */ * attrs */
if (ldap->count_entries(mesg) == 1) { if (ldap->count_entries(mesg) == 1) {
mesg = ldap->first_entry(mesg); /* TODO Why first_entry ?? mesg = ldap->first_entry(mesg); /* TODO Why first_entry ??
* already at first entry! */ * already at first entry! */
std::vector<std::string> vals = ldap->get_all_vals(mesg, std::vector<std::string> vals = ldap->get_all_vals(mesg,
"servicePrincipalName "); "servicePrincipalName ");
for (size_t i = 0; i < vals.size(); ++i) { for (size_t i = 0; i < vals.size(); ++i) {
/* translate HOST/ to host/ */ /* translate HOST/ to host/ */
if (vals[i].compare(0, 5, "HOST/") == 0) { if (vals[i].compare(0, 5, "HOST/") == 0) {
vals[i].replace(0, 5, "host/"); vals[i].replace(0, 5, "host/");
} }
flags->ad_principals.push_back(vals[i]); flags->ad_principals.push_back(vals[i]);
VERBOSE("Found Principal: %s", vals[i].c_str()); VERBOSE("Found servicePrincipalName: %s", vals[i].c_str());
} }
if (flags->set_userPrincipalName) { if (flags->set_userPrincipalName) {
VERBOSE("userPrincipal specified on command line"); VERBOSE("User principal specified on command line");
} else { } else {
std::string upn = ldap->get_one_val(mesg, "userPrincipalName"); std::string upn = ldap->get_one_val(mesg, "userPrincipalName");
if (!upn.empty()) { if (!upn.empty()) {
VERBOSE("Found userPrincipalName: %s", upn.c_str());
size_t pos = upn.find('@'); size_t pos = upn.find('@');
if (pos != std::string::npos) { if (pos != std::string::npos) {
upn.erase(pos); upn.erase(pos);
} }
VERBOSE("Found User Principal: %s", upn.c_str());
/* update userPrincipalName for salt generation */ /* update userPrincipalName for salt generation */
flags->userPrincipalName = upn.c_str(); flags->userPrincipalName = upn.c_str();
} }
} }
} }
ldap_msgfree(mesg); ldap_msgfree(mesg);
ldap_check_account_strings(flags); ldap_check_account_strings(flags);
return true; return true;
} }
skipping to change at line 650 skipping to change at line 662
"user"}; "user"};
std::vector<std::string> v_user_objectClass(vals_objectClass, std::vector<std::string> v_user_objectClass(vals_objectClass,
myend(vals_objectClass)); myend(vals_objectClass));
std::vector<std::string> v_machine_objectClass(vals_objectClass, std::vector<std::string> v_machine_objectClass(vals_objectClass,
myend(vals_objectClass)); myend(vals_objectClass));
v_machine_objectClass.push_back("computer"); v_machine_objectClass.push_back("computer");
LDAPConnection *ldap = flags->ldap; LDAPConnection *ldap = flags->ldap;
/* No computer account found, so let's add one in the OU specified */ /* No computer account found, so let's add one in the OU specified */
if (flags->use_service_account) { if (flags->use_service_account) {
VERBOSE("Service account not found, create the account"); VERBOSE("Service account not found, creating one");
fprintf(stdout, fprintf(stdout,
"No service account for %s found, creating a new one.\n", "No service account for %s found, creating a new one.\n",
flags->sAMAccountName.c_str() flags->sAMAccountName.c_str()
); );
} else { } else {
VERBOSE("Computer account not found, create the account"); VERBOSE("Computer account not found, create one");
fprintf(stdout, fprintf(stdout,
"No computer account for %s found, creating a new one.\n", "No computer account for %s found, creating a new one.\n",
flags->sAMAccountName_nodollar.c_str() flags->sAMAccountName_nodollar.c_str()
); );
} }
flags->ad_computerDn = sform("cn=%s,%s", flags->ad_computerDn = sform("cn=%s,%s",
flags->sAMAccountName_nodollar.c_str(), flags->sAMAccountName_nodollar.c_str(),
flags->ldap_ou.c_str()); flags->ldap_ou.c_str());
LDAP_mod mod_attrs; LDAP_mod mod_attrs;
skipping to change at line 689 skipping to change at line 701
userAcctFlags = UF_WORKSTATION_TRUST_ACCOUNT; userAcctFlags = UF_WORKSTATION_TRUST_ACCOUNT;
} }
mod_attrs.add("userAccountControl", sform("%d", userAcctFlags)); mod_attrs.add("userAccountControl", sform("%d", userAcctFlags));
mod_attrs.add("sAMAccountName", flags->sAMAccountName); mod_attrs.add("sAMAccountName", flags->sAMAccountName);
mod_attrs.add("unicodePwd", "\"" + flags->password + "\"", true); mod_attrs.add("unicodePwd", "\"" + flags->password + "\"", true);
ldap->add(flags->ad_computerDn, mod_attrs); ldap->add(flags->ad_computerDn, mod_attrs);
/* Defaults, will attempt to reset later */ /* Defaults, will attempt to reset later */
flags->ad_supportedEncryptionTypes = flags->ad_supportedEncryptionTypes =
MS_KERB_ENCTYPE_DES_CBC_CRC | MS_KERB_DES_ENCTYPES |
MS_KERB_ENCTYPE_DES_CBC_MD5 |
MS_KERB_ENCTYPE_RC4_HMAC_MD5; MS_KERB_ENCTYPE_RC4_HMAC_MD5;
flags->ad_enctypes = VALUE_OFF; flags->ad_enctypes = VALUE_OFF;
flags->ad_userAccountControl = userAcctFlags; flags->ad_userAccountControl = userAcctFlags;
ldap_check_account_strings(flags); ldap_check_account_strings(flags);
} }
int ldap_delete_account(msktutil_flags *flags)
{
std::string dn;
int ret;
VERBOSE("Deleting LDAP entry of %s", flags->sAMAccountName.c_str());
LDAPMessage *mesg = ldap_get_account_attrs(flags, "distinguishedName");
if (flags->ldap->count_entries(mesg) == 1) {
mesg = flags->ldap->first_entry(mesg);
dn = flags->ldap->get_one_val(mesg, "distinguishedName");
}
ldap_msgfree(mesg);
if (dn.empty()) {
fprintf(stderr,
"Error: account for %s was not found\n",
flags->sAMAccountName.c_str()
);
return -1;
}
ret = flags->ldap->del(dn);
return ret;
}
 End of changes. 30 change blocks. 
59 lines changed or deleted 70 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)