|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* adcli
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* Copyright (C) 2012 Red Hat Inc.
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit Service |
6d40f9 |
* it under the terms of the GNU Lesser General Public License as
|
|
Packit Service |
6d40f9 |
* published by the Free Software Foundation; either version 2.1 of
|
|
Packit Service |
6d40f9 |
* the License, or (at your option) any later version.
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit Service |
6d40f9 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
6d40f9 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
6d40f9 |
* Lesser General Public License for more details.
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
6d40f9 |
* License along with this program; if not, write to the Free Software
|
|
Packit Service |
6d40f9 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
Packit Service |
6d40f9 |
* MA 02110-1301 USA
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* Author: Stef Walter <stefw@gnome.org>
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#include "config.h"
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#include "adenroll.h"
|
|
Packit Service |
6d40f9 |
#include "adprivate.h"
|
|
Packit Service |
6d40f9 |
#include "seq.h"
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#include <gssapi/gssapi_krb5.h>
|
|
Packit Service |
6d40f9 |
#include <krb5/krb5.h>
|
|
Packit Service |
6d40f9 |
#include <ldap.h>
|
|
Packit Service |
6d40f9 |
#include <sasl/sasl.h>
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#include <sys/types.h>
|
|
Packit Service |
6d40f9 |
#include <sys/socket.h>
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#include <assert.h>
|
|
Packit Service |
6d40f9 |
#include <ctype.h>
|
|
Packit Service |
6d40f9 |
#include <errno.h>
|
|
Packit Service |
6d40f9 |
#include <netdb.h>
|
|
Packit Service |
6d40f9 |
#include <stdio.h>
|
|
Packit Service |
6d40f9 |
#include <unistd.h>
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static krb5_enctype v60_later_enctypes[] = {
|
|
Packit Service |
6d40f9 |
ENCTYPE_AES256_CTS_HMAC_SHA1_96,
|
|
Packit Service |
6d40f9 |
ENCTYPE_AES128_CTS_HMAC_SHA1_96,
|
|
Packit Service |
6d40f9 |
ENCTYPE_DES3_CBC_SHA1,
|
|
Packit Service |
6d40f9 |
ENCTYPE_ARCFOUR_HMAC,
|
|
Packit Service |
6d40f9 |
ENCTYPE_DES_CBC_MD5,
|
|
Packit Service |
6d40f9 |
ENCTYPE_DES_CBC_CRC,
|
|
Packit Service |
6d40f9 |
0
|
|
Packit Service |
6d40f9 |
};
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static krb5_enctype v51_earlier_enctypes[] = {
|
|
Packit Service |
6d40f9 |
ENCTYPE_DES_CBC_CRC,
|
|
Packit Service |
6d40f9 |
ENCTYPE_DES_CBC_MD5,
|
|
Packit Service |
6d40f9 |
ENCTYPE_ARCFOUR_HMAC,
|
|
Packit Service |
6d40f9 |
0
|
|
Packit Service |
6d40f9 |
};
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
struct _adcli_enroll {
|
|
Packit Service |
6d40f9 |
int refs;
|
|
Packit Service |
6d40f9 |
adcli_conn *conn;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
char *host_fqdn;
|
|
Packit Service |
6d40f9 |
int host_fqdn_explicit;
|
|
Packit Service |
6d40f9 |
char *computer_name;
|
|
Packit Service |
6d40f9 |
int computer_name_explicit;
|
|
Packit Service |
6d40f9 |
char *computer_sam;
|
|
Packit Service |
6d40f9 |
char *computer_password;
|
|
Packit Service |
6d40f9 |
int computer_password_explicit;
|
|
Packit Service |
6d40f9 |
int reset_password;
|
|
Packit Service |
6d40f9 |
krb5_principal computer_principal;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
char *domain_ou;
|
|
Packit Service |
6d40f9 |
int domain_ou_validated;
|
|
Packit Service |
6d40f9 |
int domain_ou_explicit;
|
|
Packit Service |
6d40f9 |
char *computer_dn;
|
|
Packit Service |
6d40f9 |
char *computer_container;
|
|
Packit Service |
6d40f9 |
LDAPMessage *computer_attributes;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
char **service_names;
|
|
Packit Service |
6d40f9 |
char **service_principals;
|
|
Packit Service |
6d40f9 |
int service_principals_explicit;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
char *user_principal;
|
|
Packit Service |
6d40f9 |
int user_princpal_generate;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
char *os_name;
|
|
Packit Service |
6d40f9 |
char *os_version;
|
|
Packit Service |
6d40f9 |
char *os_service_pack;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_kvno kvno;
|
|
Packit Service |
6d40f9 |
char *keytab_name;
|
|
Packit Service |
6d40f9 |
int keytab_name_is_krb5;
|
|
Packit Service |
6d40f9 |
krb5_keytab keytab;
|
|
Packit Service |
6d40f9 |
krb5_principal *keytab_principals;
|
|
Packit Service |
6d40f9 |
krb5_enctype *keytab_enctypes;
|
|
Packit Service |
6d40f9 |
int keytab_enctypes_explicit;
|
|
Packit Service |
6d40f9 |
unsigned int computer_password_lifetime;
|
|
Packit Service |
6d40f9 |
int computer_password_lifetime_explicit;
|
|
Packit Service |
6d40f9 |
};
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
ensure_host_fqdn (adcli_result res,
|
|
Packit Service |
6d40f9 |
adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
const char *fqdn;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->host_fqdn) {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Using fully qualified name: %s",
|
|
Packit Service |
6d40f9 |
enroll->host_fqdn);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->host_fqdn_explicit) {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Not setting fully qualified name");
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* By default use our actual host name discovered during connecting */
|
|
Packit Service |
6d40f9 |
fqdn = adcli_conn_get_host_fqdn (enroll->conn);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&enroll->host_fqdn, fqdn);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
ensure_computer_name (adcli_result res,
|
|
Packit Service |
6d40f9 |
adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->computer_name) {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Enrolling computer name: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_name);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!enroll->host_fqdn) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("No host name from which to determine the computer name");
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enroll->computer_name = _adcli_calc_netbios_name (enroll->host_fqdn);
|
|
Packit Service |
6d40f9 |
if (enroll->computer_name == NULL)
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
ensure_computer_sam (adcli_result res,
|
|
Packit Service |
6d40f9 |
adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
krb5_context k5;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (enroll->computer_sam);
|
|
Packit Service |
6d40f9 |
enroll->computer_sam = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (asprintf (&enroll->computer_sam, "%s$", enroll->computer_name) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (enroll->computer_sam != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (k5 != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->computer_principal)
|
|
Packit Service |
6d40f9 |
krb5_free_principal (k5, enroll->computer_principal);
|
|
Packit Service |
6d40f9 |
enroll->computer_principal = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = _adcli_krb5_build_principal (k5, enroll->computer_sam,
|
|
Packit Service |
6d40f9 |
adcli_conn_get_domain_realm (enroll->conn),
|
|
Packit Service |
6d40f9 |
&enroll->computer_principal);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (code == 0);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static int
|
|
Packit Service |
6d40f9 |
filter_password_chars (char *password,
|
|
Packit Service |
6d40f9 |
int length)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
int i, j;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* The MS documentation says their servers only use ASCII characters
|
|
Packit Service |
6d40f9 |
* between 32 and 122 inclusive. We do that as well, and filter out
|
|
Packit Service |
6d40f9 |
* all other random characters. We also remove certain characters
|
|
Packit Service |
6d40f9 |
* special for use in a shell.
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
for (i = 0, j = 0; i < length; i++) {
|
|
Packit Service |
6d40f9 |
if (password[i] >= 32 && password[i] <= 122 &&
|
|
Packit Service |
6d40f9 |
strchr (" !'\"$`", password[i]) == NULL)
|
|
Packit Service |
6d40f9 |
password[j++] = password[i];
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* return the number of valid characters remaining */
|
|
Packit Service |
6d40f9 |
return j;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static char *
|
|
Packit Service |
6d40f9 |
generate_host_password (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
size_t length)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *password;
|
|
Packit Service |
6d40f9 |
krb5_context k5;
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
krb5_data buffer;
|
|
Packit Service |
6d40f9 |
int at;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (k5 != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
password = malloc (length + 1);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (password != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
at = 0;
|
|
Packit Service |
6d40f9 |
while (at != length) {
|
|
Packit Service |
6d40f9 |
buffer.length = length - at;
|
|
Packit Service |
6d40f9 |
buffer.data = password + at;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = krb5_c_random_make_octets (k5, &buffer);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (code == 0, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
at += filter_password_chars (buffer.data, buffer.length);
|
|
Packit Service |
6d40f9 |
assert (at <= length);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* This null termination works around a bug in krb5 */
|
|
Packit Service |
6d40f9 |
password[length] = '\0';
|
|
Packit Service |
6d40f9 |
return password;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
ensure_computer_password (adcli_result res,
|
|
Packit Service |
6d40f9 |
adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
const int length = 120;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->computer_password)
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->reset_password) {
|
|
Packit Service |
6d40f9 |
assert (enroll->computer_name != NULL);
|
|
Packit Service |
6d40f9 |
enroll->computer_password = _adcli_calc_reset_password (enroll->computer_name);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (enroll->computer_password != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_info ("Using default reset computer password");
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
enroll->computer_password = generate_host_password (enroll, length);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (enroll->computer_password != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_info ("Generated %d character computer password", length);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
ensure_service_names (adcli_result res,
|
|
Packit Service |
6d40f9 |
adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
int length = 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->service_names || enroll->service_principals)
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* The default ones specified by MS */
|
|
Packit Service |
6d40f9 |
enroll->service_names = _adcli_strv_add (enroll->service_names,
|
|
Packit Service |
6d40f9 |
strdup ("host"), &length);
|
|
Packit Service |
6d40f9 |
enroll->service_names = _adcli_strv_add (enroll->service_names,
|
|
Packit Service |
6d40f9 |
strdup ("RestrictedKrbHost"), &length);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
ensure_service_principals (adcli_result res,
|
|
Packit Service |
6d40f9 |
adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *name;
|
|
Packit Service |
6d40f9 |
int length = 0;
|
|
Packit Service |
6d40f9 |
int i;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (enroll->keytab_principals == NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!enroll->service_principals) {
|
|
Packit Service |
6d40f9 |
assert (enroll->service_names != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (i = 0; enroll->service_names[i] != NULL; i++) {
|
|
Packit Service |
6d40f9 |
if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->computer_name) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
enroll->service_principals = _adcli_strv_add (enroll->service_principals,
|
|
Packit Service |
6d40f9 |
name, &length);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->host_fqdn) {
|
|
Packit Service |
6d40f9 |
if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->host_fqdn) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
enroll->service_principals = _adcli_strv_add (enroll->service_principals,
|
|
Packit Service |
6d40f9 |
name, &length);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
ensure_keytab_principals (adcli_result res,
|
|
Packit Service |
6d40f9 |
adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
krb5_context k5;
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
int count;
|
|
Packit Service |
6d40f9 |
int at, i;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Prepare the principals we're going to add to the keytab */
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (enroll->service_principals);
|
|
Packit Service |
6d40f9 |
count = _adcli_strv_len (enroll->service_principals);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (k5 != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enroll->keytab_principals = calloc (count + 3, sizeof (krb5_principal));
|
|
Packit Service |
6d40f9 |
at = 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* First add the principal for the computer account name */
|
|
Packit Service |
6d40f9 |
code = krb5_copy_principal (k5, enroll->computer_principal,
|
|
Packit Service |
6d40f9 |
&enroll->keytab_principals[at++]);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (code == 0);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Next, optionally add the user principal */
|
|
Packit Service |
6d40f9 |
if (enroll->user_principal) {
|
|
Packit Service |
6d40f9 |
code = krb5_parse_name (k5, enroll->user_principal,
|
|
Packit Service |
6d40f9 |
&enroll->keytab_principals[at++]);
|
|
Packit Service |
6d40f9 |
if (code != 0) {
|
|
Packit Service |
6d40f9 |
if (code != 0) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't parse kerberos user principal: %s: %s",
|
|
Packit Service |
6d40f9 |
enroll->user_principal,
|
|
Packit Service |
6d40f9 |
krb5_get_error_message (k5, code));
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Now add the principals for all the various services */
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (i = 0; i < count; i++) {
|
|
Packit Service |
6d40f9 |
code = _adcli_krb5_build_principal (k5, enroll->service_principals[i],
|
|
Packit Service |
6d40f9 |
adcli_conn_get_domain_realm (enroll->conn),
|
|
Packit Service |
6d40f9 |
&enroll->keytab_principals[at++]);
|
|
Packit Service |
6d40f9 |
if (code != 0) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't parse kerberos service principal: %s: %s",
|
|
Packit Service |
6d40f9 |
enroll->service_principals[i],
|
|
Packit Service |
6d40f9 |
krb5_get_error_message (k5, code));
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
ensure_user_principal (adcli_result res,
|
|
Packit Service |
6d40f9 |
adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *name;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->user_princpal_generate) {
|
|
Packit Service |
6d40f9 |
name = strdup (enroll->computer_name);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (name != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_str_down (name);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (enroll->user_principal == NULL);
|
|
Packit Service |
6d40f9 |
if (asprintf (&enroll->user_principal, "host/%s@%s",
|
|
Packit Service |
6d40f9 |
name, adcli_conn_get_domain_realm (enroll->conn)) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (name);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->user_principal)
|
|
Packit Service |
6d40f9 |
_adcli_info ("With user principal: %s", enroll->user_principal);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
lookup_computer_container (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
LDAP *ldap)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *attrs[] = { "wellKnownObjects", NULL };
|
|
Packit Service |
6d40f9 |
char *prefix = "B:32:AA312825768811D1ADED00C04FD8D5CD:";
|
|
Packit Service |
6d40f9 |
int prefix_len;
|
|
Packit Service |
6d40f9 |
LDAPMessage *results;
|
|
Packit Service |
6d40f9 |
const char *base;
|
|
Packit Service |
6d40f9 |
char **values;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
int i;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->computer_container)
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
base = enroll->domain_ou;
|
|
Packit Service |
6d40f9 |
if (base == NULL)
|
|
Packit Service |
6d40f9 |
base = adcli_conn_get_default_naming_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
assert (base != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ret = ldap_search_ext_s (ldap, base, LDAP_SCOPE_BASE,
|
|
Packit Service |
6d40f9 |
"(objectClass=*)", attrs, 0, NULL, NULL,
|
|
Packit Service |
6d40f9 |
NULL, -1, &results);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ret == LDAP_NO_SUCH_OBJECT && enroll->domain_ou) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("The organizational unit does not exist: %s", enroll->domain_ou);
|
|
Packit Service |
6d40f9 |
return enroll->domain_ou_explicit ? ADCLI_ERR_CONFIG : ADCLI_ERR_DIRECTORY;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else if (ret != LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY,
|
|
Packit Service |
6d40f9 |
"Couldn't lookup computer container: %s", base);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
values = _adcli_ldap_parse_values (ldap, results, "wellKnownObjects");
|
|
Packit Service |
6d40f9 |
ldap_msgfree (results);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
prefix_len = strlen (prefix);
|
|
Packit Service |
6d40f9 |
for (i = 0; values && values[i]; i++) {
|
|
Packit Service |
6d40f9 |
if (strncmp (values[i], prefix, prefix_len) == 0) {
|
|
Packit Service |
6d40f9 |
enroll->computer_container = strdup (values[i] + prefix_len);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (enroll->computer_container != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_info ("Found well known computer container at: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_container);
|
|
Packit Service |
6d40f9 |
break;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_strv_free (values);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Try harder */
|
|
Packit Service |
6d40f9 |
if (!enroll->computer_container) {
|
|
Packit Service |
6d40f9 |
ret = ldap_search_ext_s (ldap, base, LDAP_SCOPE_BASE,
|
|
Packit Service |
6d40f9 |
"(&(objectClass=container)(cn=Computers))",
|
|
Packit Service |
6d40f9 |
attrs, 0, NULL, NULL, NULL, -1, &results);
|
|
Packit Service |
6d40f9 |
if (ret == LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
enroll->computer_container = _adcli_ldap_parse_dn (ldap, results);
|
|
Packit Service |
6d40f9 |
if (enroll->computer_container) {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Well known computer container not "
|
|
Packit Service |
6d40f9 |
"found, but found suitable one at: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_container);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap_msgfree (results);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!enroll->computer_container && enroll->domain_ou) {
|
|
Packit Service |
6d40f9 |
_adcli_warn ("Couldn't find a computer container in the ou, "
|
|
Packit Service |
6d40f9 |
"creating computer account directly in: %s", enroll->domain_ou);
|
|
Packit Service |
6d40f9 |
enroll->computer_container = strdup (enroll->domain_ou);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (enroll->computer_container != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!enroll->computer_container) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't find location to create computer accounts");
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_DIRECTORY;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
calculate_computer_account (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
LDAP *ldap)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (enroll->computer_dn == NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Now need to find or validate the computer container */
|
|
Packit Service |
6d40f9 |
res = lookup_computer_container (enroll, ldap);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (enroll->computer_container);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
enroll->computer_dn = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (asprintf (&enroll->computer_dn, "CN=%s,%s", enroll->computer_name, enroll->computer_container) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_info ("Calculated computer account: %s", enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
create_computer_account (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
LDAP *ldap)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *vals_objectClass[] = { "computer", NULL };
|
|
Packit Service |
6d40f9 |
LDAPMod objectClass = { LDAP_MOD_ADD, "objectClass", { vals_objectClass, } };
|
|
Packit Service |
6d40f9 |
char *vals_sAMAccountName[] = { enroll->computer_sam, NULL };
|
|
Packit Service |
6d40f9 |
LDAPMod sAMAccountName = { LDAP_MOD_ADD, "sAMAccountName", { vals_sAMAccountName, } };
|
|
Packit Service |
6d40f9 |
char *vals_userAccountControl[] = { "69632", NULL }; /* WORKSTATION_TRUST_ACCOUNT | DONT_EXPIRE_PASSWD */
|
|
Packit Service |
6d40f9 |
LDAPMod userAccountControl = { LDAP_MOD_REPLACE, "userAccountControl", { vals_userAccountControl, } };
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
LDAPMod *mods[] = {
|
|
Packit Service |
6d40f9 |
&objectClass,
|
|
Packit Service |
6d40f9 |
&sAMAccountName,
|
|
Packit Service |
6d40f9 |
&userAccountControl,
|
|
Packit Service |
6d40f9 |
NULL,
|
|
Packit Service |
6d40f9 |
};
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ret = ldap_add_ext_s (ldap, enroll->computer_dn, mods, NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* Hand to head. This is really dumb... AD returns
|
|
Packit Service |
6d40f9 |
* OBJECT_CLASS_VIOLATION when the 'admin' account doesn't have
|
|
Packit Service |
6d40f9 |
* enough permission to create this computer account.
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* Additionally LDAP_UNWILLING_TO_PERFORM and LDAP_CONSTRAINT_VIOLATION
|
|
Packit Service |
6d40f9 |
* are seen on various Windows Servers as responses to this case.
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* TODO: Perhaps some missing attributes are auto-generated when
|
|
Packit Service |
6d40f9 |
* the administrative credentials have sufficient permissions, and
|
|
Packit Service |
6d40f9 |
* those missing attributes cause the object class violation. However
|
|
Packit Service |
6d40f9 |
* I've tried to screw around with this, and can't find the missing
|
|
Packit Service |
6d40f9 |
* attributes. They may be hidden, like unicodePwd.
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ret == LDAP_INSUFFICIENT_ACCESS || ret == LDAP_OBJECT_CLASS_VIOLATION ||
|
|
Packit Service |
6d40f9 |
ret == LDAP_UNWILLING_TO_PERFORM || ret == LDAP_CONSTRAINT_VIOLATION) {
|
|
Packit Service |
6d40f9 |
return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_CREDENTIALS,
|
|
Packit Service |
6d40f9 |
"Insufficient permissions to modify computer account: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else if (ret != LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY,
|
|
Packit Service |
6d40f9 |
"Couldn't create computer account: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_info ("Created computer account: %s", enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static int
|
|
Packit Service |
6d40f9 |
filter_for_necessary_updates (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
LDAP *ldap,
|
|
Packit Service |
6d40f9 |
LDAPMessage *entry,
|
|
Packit Service |
6d40f9 |
LDAPMod **mods)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
struct berval **vals;
|
|
Packit Service |
6d40f9 |
int match;
|
|
Packit Service |
6d40f9 |
int out;
|
|
Packit Service |
6d40f9 |
int in;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (in = 0, out = 0; mods[in] != NULL; in++) {
|
|
Packit Service |
6d40f9 |
match = 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Never update these attributes */
|
|
Packit Service |
6d40f9 |
if (strcasecmp (mods[in]->mod_type, "objectClass") == 0)
|
|
Packit Service |
6d40f9 |
continue;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* If no entry, then no filtering */
|
|
Packit Service |
6d40f9 |
if (entry != NULL) {
|
|
Packit Service |
6d40f9 |
vals = ldap_get_values_len (ldap, entry, mods[in]->mod_type);
|
|
Packit Service |
6d40f9 |
if (vals != NULL) {
|
|
Packit Service |
6d40f9 |
match = _adcli_ldap_have_in_mod (mods[in], vals);
|
|
Packit Service |
6d40f9 |
ldap_value_free_len (vals);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!match)
|
|
Packit Service |
6d40f9 |
mods[out++] = mods[in];
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
mods[out] = NULL;
|
|
Packit Service |
6d40f9 |
return out;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
validate_computer_account (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
int allow_overwrite,
|
|
Packit Service |
6d40f9 |
int already_exists)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
assert (enroll->computer_dn != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (already_exists && !allow_overwrite) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("The computer account %s already exists",
|
|
Packit Service |
6d40f9 |
enroll->computer_name);
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Do we have an explicitly requested ou? */
|
|
Packit Service |
6d40f9 |
if (enroll->domain_ou && enroll->domain_ou_explicit && already_exists) {
|
|
Packit Service |
6d40f9 |
if (!_adcli_ldap_dn_has_ancestor (enroll->computer_dn, enroll->domain_ou)) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("The computer account %s already exists, "
|
|
Packit Service |
6d40f9 |
"but is not in the desired organizational unit.",
|
|
Packit Service |
6d40f9 |
enroll->computer_name);
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
delete_computer_account (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
LDAP *ldap)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ret = ldap_delete_ext_s (ldap, enroll->computer_dn, NULL, NULL);
|
|
Packit Service |
6d40f9 |
if (ret == LDAP_INSUFFICIENT_ACCESS) {
|
|
Packit Service |
6d40f9 |
return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_CREDENTIALS,
|
|
Packit Service |
6d40f9 |
"Insufficient permissions to delete computer account: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else if (ret != LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY,
|
|
Packit Service |
6d40f9 |
"Couldn't delete computer account: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Deleted computer account at: %s", enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
locate_computer_account (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
LDAP *ldap,
|
|
Packit Service |
6d40f9 |
LDAPMessage **rresults,
|
|
Packit Service |
6d40f9 |
LDAPMessage **rentry)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *attrs[] = { "1.1", NULL };
|
|
Packit Service |
6d40f9 |
LDAPMessage *results = NULL;
|
|
Packit Service |
6d40f9 |
LDAPMessage *entry = NULL;
|
|
Packit Service |
6d40f9 |
const char *base;
|
|
Packit Service |
6d40f9 |
char *value;
|
|
Packit Service |
6d40f9 |
char *filter;
|
|
Packit Service |
6d40f9 |
char *dn;
|
|
Packit Service |
6d40f9 |
int ret = 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* If we don't yet know our computer dn, then try and find it */
|
|
Packit Service |
6d40f9 |
value = _adcli_ldap_escape_filter (enroll->computer_sam);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (value != NULL);
|
|
Packit Service |
6d40f9 |
if (asprintf (&filter, "(&(objectClass=computer)(sAMAccountName=%s))", value) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
free (value);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
base = adcli_conn_get_default_naming_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
ret = ldap_search_ext_s (ldap, base, LDAP_SCOPE_SUB, filter, attrs, 0,
|
|
Packit Service |
6d40f9 |
NULL, NULL, NULL, 1, &results);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (filter);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* ldap_search_ext_s() can return results *and* an error. */
|
|
Packit Service |
6d40f9 |
if (ret == LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
entry = ldap_first_entry (ldap, results);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* If we found a computer account, make note of dn */
|
|
Packit Service |
6d40f9 |
if (entry) {
|
|
Packit Service |
6d40f9 |
dn = ldap_get_dn (ldap, entry);
|
|
Packit Service |
6d40f9 |
free (enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
enroll->computer_dn = strdup (dn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (enroll->computer_dn != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_info ("Found computer account for %s at: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_sam, dn);
|
|
Packit Service |
6d40f9 |
ldap_memfree (dn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
ldap_msgfree (results);
|
|
Packit Service |
6d40f9 |
results = NULL;
|
|
Packit Service |
6d40f9 |
_adcli_info ("Computer account for %s does not exist",
|
|
Packit Service |
6d40f9 |
enroll->computer_sam);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY,
|
|
Packit Service |
6d40f9 |
"Couldn't lookup computer account: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_sam);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (rresults)
|
|
Packit Service |
6d40f9 |
*rresults = results;
|
|
Packit Service |
6d40f9 |
else
|
|
Packit Service |
6d40f9 |
ldap_msgfree (results);
|
|
Packit Service |
6d40f9 |
if (rentry) {
|
|
Packit Service |
6d40f9 |
assert (rresults != NULL);
|
|
Packit Service |
6d40f9 |
*rentry = entry;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
load_computer_account (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
LDAP *ldap,
|
|
Packit Service |
6d40f9 |
LDAPMessage **rresults,
|
|
Packit Service |
6d40f9 |
LDAPMessage **rentry)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *attrs[] = { "1.1", NULL };
|
|
Packit Service |
6d40f9 |
LDAPMessage *results = NULL;
|
|
Packit Service |
6d40f9 |
LDAPMessage *entry = NULL;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ret = ldap_search_ext_s (ldap, enroll->computer_dn, LDAP_SCOPE_BASE,
|
|
Packit Service |
6d40f9 |
"(objectClass=computer)", attrs, 0,
|
|
Packit Service |
6d40f9 |
NULL, NULL, NULL, -1, &results);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ret == LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
entry = ldap_first_entry (ldap, results);
|
|
Packit Service |
6d40f9 |
if (entry) {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Found computer account for %s at: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_sam, enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else if (ret == LDAP_NO_SUCH_OBJECT) {
|
|
Packit Service |
6d40f9 |
results = entry = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY,
|
|
Packit Service |
6d40f9 |
"Couldn't check computer account: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (rresults)
|
|
Packit Service |
6d40f9 |
*rresults = results;
|
|
Packit Service |
6d40f9 |
else
|
|
Packit Service |
6d40f9 |
ldap_msgfree (results);
|
|
Packit Service |
6d40f9 |
if (rentry) {
|
|
Packit Service |
6d40f9 |
assert (rresults != NULL);
|
|
Packit Service |
6d40f9 |
*rentry = entry;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
locate_or_create_computer_account (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
int allow_overwrite)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
LDAPMessage *results = NULL;
|
|
Packit Service |
6d40f9 |
LDAPMessage *entry = NULL;
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
int searched = 0;
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = adcli_conn_get_ldap_connection (enroll->conn);
|
|
Packit Service |
6d40f9 |
assert (ldap != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Try to find the computer account */
|
|
Packit Service |
6d40f9 |
if (!enroll->computer_dn) {
|
|
Packit Service |
6d40f9 |
res = locate_computer_account (enroll, ldap, &results, &entry);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
searched = 1;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Next try and come up with where we think it should be */
|
|
Packit Service |
6d40f9 |
if (enroll->computer_dn == NULL) {
|
|
Packit Service |
6d40f9 |
res = calculate_computer_account (enroll, ldap);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (enroll->computer_dn != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Have we seen an account yet? */
|
|
Packit Service |
6d40f9 |
if (!searched) {
|
|
Packit Service |
6d40f9 |
res = load_computer_account (enroll, ldap, &results, &entry);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res = validate_computer_account (enroll, allow_overwrite, entry != NULL);
|
|
Packit Service |
6d40f9 |
if (res == ADCLI_SUCCESS && entry == NULL)
|
|
Packit Service |
6d40f9 |
res = create_computer_account (enroll, ldap);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (results)
|
|
Packit Service |
6d40f9 |
ldap_msgfree (results);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
set_password_with_user_creds (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
krb5_ccache ccache;
|
|
Packit Service |
6d40f9 |
krb5_context k5;
|
|
Packit Service |
6d40f9 |
krb5_data result_string = { 0, };
|
|
Packit Service |
6d40f9 |
krb5_data result_code_string = { 0, };
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
int result_code;
|
|
Packit Service |
6d40f9 |
char *message;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (enroll->computer_password != NULL);
|
|
Packit Service |
6d40f9 |
assert (enroll->computer_principal != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (k5 != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ccache = adcli_conn_get_login_ccache (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (ccache != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
memset (&result_string, 0, sizeof (result_string));
|
|
Packit Service |
6d40f9 |
memset (&result_code_string, 0, sizeof (result_code_string));
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = krb5_set_password_using_ccache (k5, ccache, enroll->computer_password,
|
|
Packit Service |
6d40f9 |
enroll->computer_principal, &result_code,
|
|
Packit Service |
6d40f9 |
&result_code_string, &result_string);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (code != 0) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't set password for computer account: %s: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_sam, krb5_get_error_message (k5, code));
|
|
Packit Service |
6d40f9 |
/* TODO: Parse out these values */
|
|
Packit Service |
6d40f9 |
res = ADCLI_ERR_DIRECTORY;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else if (result_code != 0) {
|
|
Packit Service |
6d40f9 |
#ifdef HAVE_KRB5_CHPW_MESSAGE
|
|
Packit Service |
6d40f9 |
if (krb5_chpw_message (k5, &result_string, &message) != 0)
|
|
Packit Service |
6d40f9 |
message = NULL;
|
|
Packit Service |
6d40f9 |
#else
|
|
Packit Service |
6d40f9 |
message = NULL;
|
|
Packit Service |
6d40f9 |
if (result_string.length)
|
|
Packit Service |
6d40f9 |
message = _adcli_str_dupn (result_string.data, result_string.length);
|
|
Packit Service |
6d40f9 |
#endif
|
|
Packit Service |
6d40f9 |
_adcli_err ("Cannot set computer password: %.*s%s%s",
|
|
Packit Service |
6d40f9 |
(int)result_code_string.length, result_code_string.data,
|
|
Packit Service |
6d40f9 |
message ? ": " : "", message ? message : "");
|
|
Packit Service |
6d40f9 |
res = ADCLI_ERR_CREDENTIALS;
|
|
Packit Service |
6d40f9 |
#ifdef HAVE_KRB5_CHPW_MESSAGE
|
|
Packit Service |
6d40f9 |
krb5_free_string (k5, message);
|
|
Packit Service |
6d40f9 |
#else
|
|
Packit Service |
6d40f9 |
free (message);
|
|
Packit Service |
6d40f9 |
#endif
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Set computer password");
|
|
Packit Service |
6d40f9 |
res = ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_free_data_contents (k5, &result_string);
|
|
Packit Service |
6d40f9 |
krb5_free_data_contents (k5, &result_code_string);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
set_password_with_computer_creds (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
krb5_creds creds;
|
|
Packit Service |
6d40f9 |
krb5_data result_string = { 0, };
|
|
Packit Service |
6d40f9 |
krb5_data result_code_string = { 0, };
|
|
Packit Service |
6d40f9 |
krb5_context k5;
|
|
Packit Service |
6d40f9 |
int result_code;
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
char *message;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
memset (&creds, 0, sizeof (creds));
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (k5 != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = _adcli_kinit_computer_creds (enroll->conn, "kadmin/changepw", NULL, &creds);
|
|
Packit Service |
6d40f9 |
if (code != 0) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't get change password ticket for computer account: %s: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_sam, krb5_get_error_message (k5, code));
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_DIRECTORY;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = krb5_change_password (k5, &creds, enroll->computer_password,
|
|
Packit Service |
6d40f9 |
&result_code, &result_code_string, &result_string);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_free_cred_contents (k5, &creds);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (code != 0) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't change password for computer account: %s: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_sam, krb5_get_error_message (k5, code));
|
|
Packit Service |
6d40f9 |
/* TODO: Parse out these values */
|
|
Packit Service |
6d40f9 |
res = ADCLI_ERR_DIRECTORY;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else if (result_code != 0) {
|
|
Packit Service |
6d40f9 |
#ifdef HAVE_KRB5_CHPW_MESSAGE
|
|
Packit Service |
6d40f9 |
if (krb5_chpw_message (k5, &result_string, &message) != 0)
|
|
Packit Service |
6d40f9 |
message = NULL;
|
|
Packit Service |
6d40f9 |
#else
|
|
Packit Service |
6d40f9 |
message = NULL;
|
|
Packit Service |
6d40f9 |
if (result_string.length)
|
|
Packit Service |
6d40f9 |
message = _adcli_str_dupn (result_string.data, result_string.length);
|
|
Packit Service |
6d40f9 |
#endif
|
|
Packit Service |
6d40f9 |
_adcli_err ("Cannot change computer password: %.*s%s%s",
|
|
Packit Service |
6d40f9 |
(int)result_code_string.length, result_code_string.data,
|
|
Packit Service |
6d40f9 |
message ? ": " : "", message ? message : "");
|
|
Packit Service |
6d40f9 |
res = ADCLI_ERR_CREDENTIALS;
|
|
Packit Service |
6d40f9 |
#ifdef HAVE_KRB5_CHPW_MESSAGE
|
|
Packit Service |
6d40f9 |
krb5_free_string (k5, message);
|
|
Packit Service |
6d40f9 |
#else
|
|
Packit Service |
6d40f9 |
free (message);
|
|
Packit Service |
6d40f9 |
#endif
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Changed computer password");
|
|
Packit Service |
6d40f9 |
if (enroll->kvno > 0) {
|
|
Packit Service |
6d40f9 |
enroll->kvno++;
|
|
Packit Service |
6d40f9 |
_adcli_info ("kvno incremented to %d", enroll->kvno);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
res = ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_free_data_contents (k5, &result_string);
|
|
Packit Service |
6d40f9 |
krb5_free_data_contents (k5, &result_code_string);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
set_computer_password (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
if (adcli_conn_get_login_type (enroll->conn) == ADCLI_LOGIN_COMPUTER_ACCOUNT)
|
|
Packit Service |
6d40f9 |
return set_password_with_computer_creds (enroll);
|
|
Packit Service |
6d40f9 |
else
|
|
Packit Service |
6d40f9 |
return set_password_with_user_creds (enroll);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
retrieve_computer_account (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res = ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
unsigned long kvno;
|
|
Packit Service |
6d40f9 |
char *value;
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
char *end;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
char *attrs[] = {
|
|
Packit Service |
6d40f9 |
"msDS-KeyVersionNumber",
|
|
Packit Service |
6d40f9 |
"msDS-supportedEncryptionTypes",
|
|
Packit Service |
6d40f9 |
"dNSHostName",
|
|
Packit Service |
6d40f9 |
"servicePrincipalName",
|
|
Packit Service |
6d40f9 |
"operatingSystem",
|
|
Packit Service |
6d40f9 |
"operatingSystemVersion",
|
|
Packit Service |
6d40f9 |
"operatingSystemServicePack",
|
|
Packit Service |
6d40f9 |
"pwdLastSet",
|
|
Packit Service |
6d40f9 |
NULL,
|
|
Packit Service |
6d40f9 |
};
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (enroll->computer_dn != NULL);
|
|
Packit Service |
6d40f9 |
assert (enroll->computer_attributes == NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = adcli_conn_get_ldap_connection (enroll->conn);
|
|
Packit Service |
6d40f9 |
assert (ldap != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ret = ldap_search_ext_s (ldap, enroll->computer_dn, LDAP_SCOPE_BASE,
|
|
Packit Service |
6d40f9 |
"(objectClass=*)", attrs, 0, NULL, NULL, NULL, -1,
|
|
Packit Service |
6d40f9 |
&enroll->computer_attributes);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ret != LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY,
|
|
Packit Service |
6d40f9 |
"Couldn't retrieve computer account info: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Update the kvno */
|
|
Packit Service |
6d40f9 |
if (enroll->kvno == 0) {
|
|
Packit Service |
6d40f9 |
value = _adcli_ldap_parse_value (ldap, enroll->computer_attributes, "msDS-KeyVersionNumber");
|
|
Packit Service |
6d40f9 |
if (value != NULL) {
|
|
Packit Service |
6d40f9 |
kvno = strtoul (value, &end, 10);
|
|
Packit Service |
6d40f9 |
if (end == NULL || *end != '\0') {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Invalid kvno '%s' for computer account in directory: %s",
|
|
Packit Service |
6d40f9 |
value, enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
res = ADCLI_ERR_DIRECTORY;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
enroll->kvno = kvno;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_info ("Retrieved kvno '%s' for computer account in directory: %s",
|
|
Packit Service |
6d40f9 |
value, enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (value);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
/* Apparently old AD didn't have this attribute, use zero */
|
|
Packit Service |
6d40f9 |
enroll->kvno = 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_info ("No kvno found for computer account in directory: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
update_and_calculate_enctypes (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *value = NULL;
|
|
Packit Service |
6d40f9 |
krb5_enctype *read_enctypes;
|
|
Packit Service |
6d40f9 |
char *vals_supportedEncryptionTypes[] = { NULL, NULL };
|
|
Packit Service |
6d40f9 |
LDAPMod mod = { LDAP_MOD_REPLACE, "msDS-supportedEncryptionTypes", { vals_supportedEncryptionTypes, } };
|
|
Packit Service |
6d40f9 |
LDAPMod *mods[2] = { &mod, NULL };
|
|
Packit Service |
6d40f9 |
int is_2008_or_later;
|
|
Packit Service |
6d40f9 |
char *new_value;
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* Because we're using a keytab we want the server to be aware of the
|
|
Packit Service |
6d40f9 |
* encryption types supported on the client, because we can't dynamically
|
|
Packit Service |
6d40f9 |
* use a new one that's thrown at us.
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* If the encryption types are not explicitly set by the caller of this
|
|
Packit Service |
6d40f9 |
* library, then see if the account already has some encryption types
|
|
Packit Service |
6d40f9 |
* marked on it.
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* If not, write our default set to the account.
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* Note that Windows 2003 and earlier have a standard set of encryption
|
|
Packit Service |
6d40f9 |
* types, and no msDS-supportedEncryptionTypes attribute.
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = adcli_conn_get_ldap_connection (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (ldap != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
is_2008_or_later = adcli_conn_server_has_capability (enroll->conn, ADCLI_CAP_V60_OID);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* In 2008 or later, use the msDS-supportedEncryptionTypes attribute */
|
|
Packit Service |
6d40f9 |
if (is_2008_or_later) {
|
|
Packit Service |
6d40f9 |
value = _adcli_ldap_parse_value (ldap, enroll->computer_attributes,
|
|
Packit Service |
6d40f9 |
"msDS-supportedEncryptionTypes");
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!enroll->keytab_enctypes_explicit && value != NULL) {
|
|
Packit Service |
6d40f9 |
read_enctypes = _adcli_krb5_parse_enctypes (value);
|
|
Packit Service |
6d40f9 |
if (read_enctypes == NULL) {
|
|
Packit Service |
6d40f9 |
_adcli_warn ("Invalid or unsupported encryption types are set on "
|
|
Packit Service |
6d40f9 |
"the computer account (%s).", value);
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
free (enroll->keytab_enctypes);
|
|
Packit Service |
6d40f9 |
enroll->keytab_enctypes = read_enctypes;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* In 2003 or earlier, standard set of enc types */
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
value = _adcli_krb5_format_enctypes (v51_earlier_enctypes);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
new_value = _adcli_krb5_format_enctypes (adcli_enroll_get_keytab_enctypes (enroll));
|
|
Packit Service |
6d40f9 |
if (new_value == NULL) {
|
|
Packit Service |
6d40f9 |
free (value);
|
|
Packit Service |
6d40f9 |
_adcli_warn ("The encryption types desired are not available in active directory");
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* If we already have this value, then don't need to update */
|
|
Packit Service |
6d40f9 |
if (value && strcmp (new_value, value) == 0) {
|
|
Packit Service |
6d40f9 |
free (value);
|
|
Packit Service |
6d40f9 |
free (new_value);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
free (value);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!is_2008_or_later) {
|
|
Packit Service |
6d40f9 |
free (new_value);
|
|
Packit Service |
6d40f9 |
_adcli_warn ("Server does not support setting encryption types");
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
vals_supportedEncryptionTypes[0] = new_value;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (filter_for_necessary_updates (enroll, ldap, enroll->computer_attributes, mods) == 0)
|
|
Packit Service |
6d40f9 |
ret = 0;
|
|
Packit Service |
6d40f9 |
else
|
|
Packit Service |
6d40f9 |
ret = ldap_modify_ext_s (ldap, enroll->computer_dn, mods, NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (new_value);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ret == LDAP_INSUFFICIENT_ACCESS) {
|
|
Packit Service |
6d40f9 |
return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_CREDENTIALS,
|
|
Packit Service |
6d40f9 |
"Insufficient permissions to set encryption types on computer account: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else if (ret != LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY,
|
|
Packit Service |
6d40f9 |
"Couldn't set encryption types on computer account: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
update_computer_attribute (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
LDAP *ldap,
|
|
Packit Service |
6d40f9 |
LDAPMod **mods)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res = ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
char *string;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* See if there are any changes to be made? */
|
|
Packit Service |
6d40f9 |
if (filter_for_necessary_updates (enroll, ldap, enroll->computer_attributes, mods) == 0)
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
string = _adcli_ldap_mods_to_string (mods);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (string != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_info ("Modifying computer account: %s", string);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ret = ldap_modify_ext_s (ldap, enroll->computer_dn, mods, NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ret != LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
_adcli_warn ("Couldn't set %s on computer account: %s: %s",
|
|
Packit Service |
6d40f9 |
string, enroll->computer_dn, ldap_err2string (ret));
|
|
Packit Service |
6d40f9 |
res = ADCLI_ERR_DIRECTORY;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (string);
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static void
|
|
Packit Service |
6d40f9 |
update_computer_account (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
int res = 0;
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = adcli_conn_get_ldap_connection (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_if_fail (ldap != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *vals_dNSHostName[] = { enroll->host_fqdn, NULL };
|
|
Packit Service |
6d40f9 |
LDAPMod dNSHostName = { LDAP_MOD_REPLACE, "dNSHostName", { vals_dNSHostName, } };
|
|
Packit Service |
6d40f9 |
LDAPMod *mods[] = { &dNSHostName, NULL };
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res |= update_computer_attribute (enroll, ldap, mods);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res == ADCLI_SUCCESS) {
|
|
Packit Service |
6d40f9 |
char *vals_userAccountControl[] = { "69632", NULL }; /* WORKSTATION_TRUST_ACCOUNT | DONT_EXPIRE_PASSWD */
|
|
Packit Service |
6d40f9 |
LDAPMod userAccountControl = { LDAP_MOD_REPLACE, "userAccountControl", { vals_userAccountControl, } };
|
|
Packit Service |
6d40f9 |
LDAPMod *mods[] = { &userAccountControl, NULL };
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res |= update_computer_attribute (enroll, ldap, mods);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res == ADCLI_SUCCESS) {
|
|
Packit Service |
6d40f9 |
char *vals_operatingSystem[] = { enroll->os_name, NULL };
|
|
Packit Service |
6d40f9 |
LDAPMod operatingSystem = { LDAP_MOD_REPLACE, "operatingSystem", { vals_operatingSystem, } };
|
|
Packit Service |
6d40f9 |
char *vals_operatingSystemVersion[] = { enroll->os_version, NULL };
|
|
Packit Service |
6d40f9 |
LDAPMod operatingSystemVersion = { LDAP_MOD_REPLACE, "operatingSystemVersion", { vals_operatingSystemVersion, } };
|
|
Packit Service |
6d40f9 |
char *vals_operatingSystemServicePack[] = { enroll->os_service_pack, NULL };
|
|
Packit Service |
6d40f9 |
LDAPMod operatingSystemServicePack = { LDAP_MOD_REPLACE, "operatingSystemServicePack", { vals_operatingSystemServicePack, } };
|
|
Packit Service |
6d40f9 |
LDAPMod *mods[] = { &operatingSystem, &operatingSystemVersion, &operatingSystemServicePack, NULL };
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res |= update_computer_attribute (enroll, ldap, mods);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res == ADCLI_SUCCESS) {
|
|
Packit Service |
6d40f9 |
char *vals_userPrincipalName[] = { enroll->user_principal, NULL };
|
|
Packit Service |
6d40f9 |
LDAPMod userPrincipalName = { LDAP_MOD_REPLACE, "userPrincipalName", { vals_userPrincipalName, }, };
|
|
Packit Service |
6d40f9 |
LDAPMod *mods[] = { &userPrincipalName, NULL, };
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res |= update_computer_attribute (enroll, ldap, mods);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != 0)
|
|
Packit Service |
6d40f9 |
_adcli_info ("Updated existing computer account: %s", enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
update_service_principals (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
LDAPMod servicePrincipalName = { LDAP_MOD_REPLACE, "servicePrincipalName", { enroll->service_principals, } };
|
|
Packit Service |
6d40f9 |
LDAPMod *mods[] = { &servicePrincipalName, NULL, };
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = adcli_conn_get_ldap_connection (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (ldap != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* See if there are any changes to be made? */
|
|
Packit Service |
6d40f9 |
if (filter_for_necessary_updates (enroll, ldap, enroll->computer_attributes, mods) == 0)
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ret = ldap_modify_ext_s (ldap, enroll->computer_dn, mods, NULL, NULL);
|
|
Packit Service |
6d40f9 |
if (ret == LDAP_INSUFFICIENT_ACCESS) {
|
|
Packit Service |
6d40f9 |
return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_CREDENTIALS,
|
|
Packit Service |
6d40f9 |
"Insufficient permissions to set service principals on computer account: %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else if (ret != LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY,
|
|
Packit Service |
6d40f9 |
"Couldn't set service principals on computer account %s",
|
|
Packit Service |
6d40f9 |
enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
ensure_host_keytab (adcli_result res,
|
|
Packit Service |
6d40f9 |
adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
krb5_context k5;
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
char *name;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->keytab)
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (k5 != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res = _adcli_krb5_open_keytab (k5, enroll->keytab_name, &enroll->keytab);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!enroll->keytab_name) {
|
|
Packit Service |
6d40f9 |
name = malloc (MAX_KEYTAB_NAME_LEN + 1);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (name != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = krb5_kt_get_name (k5, enroll->keytab, name, MAX_KEYTAB_NAME_LEN + 1);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (code == 0);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enroll->keytab_name = name;
|
|
Packit Service |
6d40f9 |
enroll->keytab_name_is_krb5 = 1;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_info ("Using keytab: %s", enroll->keytab_name);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static krb5_boolean
|
|
Packit Service |
6d40f9 |
load_keytab_entry (krb5_context k5,
|
|
Packit Service |
6d40f9 |
krb5_keytab_entry *entry,
|
|
Packit Service |
6d40f9 |
void *data)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_enroll *enroll = data;
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
krb5_principal principal;
|
|
Packit Service |
6d40f9 |
const char *realm;
|
|
Packit Service |
6d40f9 |
size_t len;
|
|
Packit Service |
6d40f9 |
char *value;
|
|
Packit Service |
6d40f9 |
char *name;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Skip over any entry without a principal or realm */
|
|
Packit Service |
6d40f9 |
principal = entry->principal;
|
|
Packit Service |
6d40f9 |
if (!principal || !principal->realm.length)
|
|
Packit Service |
6d40f9 |
return TRUE;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Use the first keytab entry as realm */
|
|
Packit Service |
6d40f9 |
realm = adcli_conn_get_domain_realm (enroll->conn);
|
|
Packit Service |
6d40f9 |
if (!realm) {
|
|
Packit Service |
6d40f9 |
value = _adcli_str_dupn (principal->realm.data, principal->realm.length);
|
|
Packit Service |
6d40f9 |
adcli_conn_set_domain_realm (enroll->conn, value);
|
|
Packit Service |
6d40f9 |
_adcli_info ("Found realm in keytab: %s", value);
|
|
Packit Service |
6d40f9 |
realm = adcli_conn_get_domain_realm (enroll->conn);
|
|
Packit Service |
6d40f9 |
free (value);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Only look at entries that match the realm */
|
|
Packit Service |
6d40f9 |
len = strlen (realm);
|
|
Packit Service |
6d40f9 |
if (principal->realm.length != len && strncmp (realm, principal->realm.data, len) != 0)
|
|
Packit Service |
6d40f9 |
return TRUE;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = krb5_unparse_name_flags (k5, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (code == 0, FALSE);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
len = strlen (name);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!enroll->service_principals_explicit) {
|
|
Packit Service |
6d40f9 |
if (!_adcli_strv_has (enroll->service_principals, name) && strchr (name, '/')) {
|
|
Packit Service |
6d40f9 |
value = strdup (name);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (value != NULL, FALSE);
|
|
Packit Service |
6d40f9 |
_adcli_info ("Found service principal in keytab: %s", value);
|
|
Packit Service |
6d40f9 |
enroll->service_principals = _adcli_strv_add (enroll->service_principals, value, NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!enroll->host_fqdn_explicit && !enroll->computer_name_explicit) {
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Automatically use the netbios name */
|
|
Packit Service |
e64910 |
if (!enroll->computer_name && len > 1 &&
|
|
Packit Service |
6d40f9 |
_adcli_str_has_suffix (name, "$") && !strchr (name, '/')) {
|
|
Packit Service |
6d40f9 |
enroll->computer_name = name;
|
|
Packit Service |
6d40f9 |
name[len - 1] = '\0';
|
|
Packit Service |
6d40f9 |
_adcli_info ("Found computer name in keytab: %s", name);
|
|
Packit Service |
6d40f9 |
name = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else if (!enroll->host_fqdn && _adcli_str_has_prefix (name, "host/") && strchr (name, '.')) {
|
|
Packit Service |
6d40f9 |
/* Skip host/ prefix */
|
|
Packit Service |
235f23 |
enroll->host_fqdn = strdup (name + 5);
|
|
Packit Service |
235f23 |
return_val_if_fail (enroll->host_fqdn != NULL, FALSE);
|
|
Packit Service |
235f23 |
_adcli_info ("Found host qualified name in keytab: %s", enroll->host_fqdn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (name);
|
|
Packit Service |
6d40f9 |
return TRUE;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
load_host_keytab (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
krb5_context k5;
|
|
Packit Service |
6d40f9 |
krb5_keytab keytab;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res = _adcli_krb5_init_context (&k5;;
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res = _adcli_krb5_open_keytab (k5, enroll->keytab_name, &keytab);
|
|
Packit Service |
6d40f9 |
if (res == ADCLI_SUCCESS) {
|
|
Packit Service |
6d40f9 |
code = _adcli_krb5_keytab_enumerate (k5, keytab, load_keytab_entry, enroll);
|
|
Packit Service |
6d40f9 |
if (code != 0) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't enumerate keytab: %s: %s",
|
|
Packit Service |
6d40f9 |
enroll->keytab_name, krb5_get_error_message (k5, code));
|
|
Packit Service |
6d40f9 |
res = ADCLI_ERR_FAIL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
krb5_kt_close (k5, keytab);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_free_context (k5);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
typedef struct {
|
|
Packit Service |
6d40f9 |
krb5_kvno kvno;
|
|
Packit Service |
6d40f9 |
krb5_principal principal;
|
|
Packit Service |
6d40f9 |
int matched;
|
|
Packit Service |
6d40f9 |
} match_principal_kvno;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static krb5_boolean
|
|
Packit Service |
6d40f9 |
match_principal_and_kvno (krb5_context k5,
|
|
Packit Service |
6d40f9 |
krb5_keytab_entry *entry,
|
|
Packit Service |
6d40f9 |
void *data)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
match_principal_kvno *closure = data;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (closure->principal);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* Don't match entries with kvno - 1 so that existing sessions
|
|
Packit Service |
6d40f9 |
* will still work.
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (entry->vno + 1 == closure->kvno)
|
|
Packit Service |
6d40f9 |
return 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Is this the principal we're looking for? */
|
|
Packit Service |
6d40f9 |
if (krb5_principal_compare (k5, entry->principal, closure->principal)) {
|
|
Packit Service |
6d40f9 |
closure->matched = 1;
|
|
Packit Service |
6d40f9 |
return 1;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return 0;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#define DEFAULT_SALT 1
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static krb5_data *
|
|
Packit Service |
6d40f9 |
build_principal_salts (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
krb5_context k5,
|
|
Packit Service |
6d40f9 |
krb5_principal principal)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
krb5_data *salts;
|
|
Packit Service |
6d40f9 |
const int count = 3;
|
|
Packit Service |
6d40f9 |
int i = 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
salts = calloc (count, sizeof (krb5_data));
|
|
Packit Service |
6d40f9 |
return_val_if_fail (salts != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Build up the salts, first a standard kerberos salt */
|
|
Packit Service |
6d40f9 |
code = krb5_principal2salt (k5, principal, &salts[i++]);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (code == 0, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Then a Windows 2003 computer account salt */
|
|
Packit Service |
6d40f9 |
code = _adcli_krb5_w2k3_salt (k5, principal, enroll->computer_name, &salts[i++]);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (code == 0, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* And lastly a null salt */
|
|
Packit Service |
6d40f9 |
salts[i++].data = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (count == i);
|
|
Packit Service |
6d40f9 |
return salts;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static void
|
|
Packit Service |
6d40f9 |
free_principal_salts (krb5_context k5,
|
|
Packit Service |
6d40f9 |
krb5_data *salts)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
int i;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (i = 0; salts[i].data != NULL; i++)
|
|
Packit Service |
6d40f9 |
krb5_free_data_contents (k5, salts + i);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (salts);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
add_principal_to_keytab (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
krb5_context k5,
|
|
Packit Service |
6d40f9 |
krb5_principal principal,
|
|
Packit Service |
6d40f9 |
const char *principal_name,
|
|
Packit Service |
6d40f9 |
int *which_salt)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
match_principal_kvno closure;
|
|
Packit Service |
6d40f9 |
krb5_data password;
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
krb5_data *salts;
|
|
Packit Service |
6d40f9 |
krb5_enctype *enctypes;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Remove old stuff from the keytab for this principal */
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
closure.kvno = enroll->kvno;
|
|
Packit Service |
6d40f9 |
closure.principal = principal;
|
|
Packit Service |
6d40f9 |
closure.matched = 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = _adcli_krb5_keytab_clear (k5, enroll->keytab,
|
|
Packit Service |
6d40f9 |
match_principal_and_kvno, &closure);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (code != 0) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't update keytab: %s: %s",
|
|
Packit Service |
6d40f9 |
enroll->keytab_name, krb5_get_error_message (k5, code));
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_FAIL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (closure.matched) {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Cleared old entries from keytab: %s",
|
|
Packit Service |
6d40f9 |
enroll->keytab_name);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
password.data = enroll->computer_password;
|
|
Packit Service |
6d40f9 |
password.length = strlen (enroll->computer_password);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enctypes = adcli_enroll_get_keytab_enctypes (enroll);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* So we need to discover which salt to use. As a side effect we are
|
|
Packit Service |
6d40f9 |
* also testing that our account works.
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
salts = build_principal_salts (enroll, k5, principal);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (salts != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (*which_salt < 0) {
|
|
Packit Service |
6d40f9 |
code = _adcli_krb5_keytab_discover_salt (k5, principal, enroll->kvno, &password,
|
|
Packit Service |
6d40f9 |
enctypes, salts, which_salt);
|
|
Packit Service |
6d40f9 |
if (code != 0) {
|
|
Packit Service |
6d40f9 |
_adcli_warn ("Couldn't authenticate with keytab while discovering which salt to use: %s: %s",
|
|
Packit Service |
6d40f9 |
principal_name, krb5_get_error_message (k5, code));
|
|
Packit Service |
6d40f9 |
*which_salt = DEFAULT_SALT;
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
assert (*which_salt >= 0);
|
|
Packit Service |
6d40f9 |
_adcli_info ("Discovered which keytab salt to use");
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = _adcli_krb5_keytab_add_entries (k5, enroll->keytab, principal,
|
|
Packit Service |
6d40f9 |
enroll->kvno, &password, enctypes, &salts[*which_salt]);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free_principal_salts (k5, salts);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (code != 0) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't add keytab entries: %s: %s",
|
|
Packit Service |
6d40f9 |
enroll->keytab_name, krb5_get_error_message (k5, code));
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_FAIL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_info ("Added the entries to the keytab: %s: %s",
|
|
Packit Service |
6d40f9 |
principal_name, enroll->keytab_name);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
update_keytab_for_principals (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
krb5_context k5;
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
int which_salt = -1;
|
|
Packit Service |
6d40f9 |
char *name;
|
|
Packit Service |
6d40f9 |
int i;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (enroll->keytab_principals != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (k5 != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (i = 0; enroll->keytab_principals[i] != 0; i++) {
|
|
Packit Service |
6d40f9 |
if (krb5_unparse_name (k5, enroll->keytab_principals[i], &name) != 0)
|
|
Packit Service |
6d40f9 |
name = "";
|
|
Packit Service |
6d40f9 |
res = add_principal_to_keytab (enroll, k5, enroll->keytab_principals[i],
|
|
Packit Service |
6d40f9 |
name, &which_salt);
|
|
Packit Service |
6d40f9 |
krb5_free_unparsed_name (k5, name);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static void
|
|
Packit Service |
6d40f9 |
enroll_clear_state (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
krb5_context k5;
|
|
Packit Service |
6d40f9 |
int i;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->keytab_principals) {
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_if_fail (k5 != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (i = 0; enroll->keytab_principals[i] != NULL; i++)
|
|
Packit Service |
6d40f9 |
krb5_free_principal (k5, enroll->keytab_principals[i]);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (enroll->keytab_principals);
|
|
Packit Service |
6d40f9 |
enroll->keytab_principals = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->keytab) {
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_if_fail (k5 != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_kt_close (k5, enroll->keytab);
|
|
Packit Service |
6d40f9 |
enroll->keytab = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (enroll->computer_sam);
|
|
Packit Service |
6d40f9 |
enroll->computer_sam = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->computer_principal) {
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_if_fail (k5 != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_free_principal (k5, enroll->computer_principal);
|
|
Packit Service |
6d40f9 |
enroll->computer_principal = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!enroll->computer_password_explicit) {
|
|
Packit Service |
6d40f9 |
free (enroll->computer_password);
|
|
Packit Service |
6d40f9 |
enroll->computer_password = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
enroll->computer_dn = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (enroll->computer_container);
|
|
Packit Service |
6d40f9 |
enroll->computer_container = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!enroll->service_principals_explicit) {
|
|
Packit Service |
6d40f9 |
_adcli_strv_free (enroll->service_principals);
|
|
Packit Service |
6d40f9 |
enroll->service_principals = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->user_princpal_generate) {
|
|
Packit Service |
6d40f9 |
free (enroll->user_principal);
|
|
Packit Service |
6d40f9 |
enroll->user_principal = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enroll->kvno = 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->computer_attributes) {
|
|
Packit Service |
6d40f9 |
ldap_msgfree (enroll->computer_attributes);
|
|
Packit Service |
6d40f9 |
enroll->computer_attributes = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!enroll->domain_ou_explicit) {
|
|
Packit Service |
6d40f9 |
free (enroll->domain_ou);
|
|
Packit Service |
6d40f9 |
enroll->domain_ou = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_result
|
|
Packit Service |
6d40f9 |
adcli_enroll_prepare (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
adcli_enroll_flags flags)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res = ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_clear_last_error ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Basic discovery and figuring out enroll params */
|
|
Packit Service |
6d40f9 |
res = ensure_host_fqdn (res, enroll);
|
|
Packit Service |
6d40f9 |
res = ensure_computer_name (res, enroll);
|
|
Packit Service |
6d40f9 |
res = ensure_computer_sam (res, enroll);
|
|
Packit Service |
6d40f9 |
res = ensure_user_principal (res, enroll);
|
|
Packit Service |
6d40f9 |
res = ensure_computer_password (res, enroll);
|
|
Packit Service |
6d40f9 |
if (!(flags & ADCLI_ENROLL_NO_KEYTAB))
|
|
Packit Service |
6d40f9 |
res = ensure_host_keytab (res, enroll);
|
|
Packit Service |
6d40f9 |
res = ensure_service_names (res, enroll);
|
|
Packit Service |
6d40f9 |
res = ensure_service_principals (res, enroll);
|
|
Packit Service |
6d40f9 |
res = ensure_keytab_principals (res, enroll);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
enroll_join_or_update_tasks (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
adcli_enroll_flags flags)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
966232 |
krb5_kvno old_kvno = -1;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!(flags & ADCLI_ENROLL_PASSWORD_VALID)) {
|
|
Packit Service |
966232 |
|
|
Packit Service |
966232 |
/* Handle kvno changes for read-only domain controllers
|
|
Packit Service |
966232 |
* (RODC). Since the actual password change does not happen on
|
|
Packit Service |
966232 |
* the RODC the kvno change has to be replicated back which
|
|
Packit Service |
966232 |
* might take some time. So we check the kvno before and after
|
|
Packit Service |
966232 |
* the change if we are connected to a RODC and increment the
|
|
Packit Service |
966232 |
* kvno if needed. */
|
|
Packit Service |
966232 |
if (!adcli_conn_is_writeable (enroll->conn)) {
|
|
Packit Service |
966232 |
if (enroll->computer_attributes == NULL) {
|
|
Packit Service |
966232 |
res = retrieve_computer_account (enroll);
|
|
Packit Service |
966232 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
966232 |
return res;
|
|
Packit Service |
966232 |
}
|
|
Packit Service |
966232 |
old_kvno = adcli_enroll_get_kvno (enroll);
|
|
Packit Service |
966232 |
_adcli_info ("Found old kvno '%d'", old_kvno);
|
|
Packit Service |
966232 |
|
|
Packit Service |
966232 |
ldap_msgfree (enroll->computer_attributes);
|
|
Packit Service |
966232 |
enroll->computer_attributes = NULL;
|
|
Packit Service |
966232 |
adcli_enroll_set_kvno (enroll, 0);
|
|
Packit Service |
966232 |
}
|
|
Packit Service |
966232 |
|
|
Packit Service |
6d40f9 |
res = set_computer_password (enroll);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* kvno is not needed if no keytab */
|
|
Packit Service |
6d40f9 |
if (flags & ADCLI_ENROLL_NO_KEYTAB)
|
|
Packit Service |
6d40f9 |
enroll->kvno = -1;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Get information about the computer account if needed */
|
|
Packit Service |
6d40f9 |
if (enroll->computer_attributes == NULL) {
|
|
Packit Service |
6d40f9 |
res = retrieve_computer_account (enroll);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
966232 |
/* Handle kvno changes for read-only domain controllers (RODC) */
|
|
Packit Service |
966232 |
if (!adcli_conn_is_writeable (enroll->conn) && old_kvno != -1 &&
|
|
Packit Service |
966232 |
adcli_enroll_get_kvno (enroll) != 0 &&
|
|
Packit Service |
966232 |
adcli_enroll_get_kvno (enroll) == old_kvno) {
|
|
Packit Service |
966232 |
enroll->kvno++;
|
|
Packit Service |
966232 |
_adcli_info ("No kvno change detected on read-only DC, kvno "
|
|
Packit Service |
966232 |
"will be incremented by 1 to '%d'", enroll->kvno);
|
|
Packit Service |
966232 |
}
|
|
Packit Service |
966232 |
|
|
Packit Service |
6d40f9 |
/* We ignore failures of setting these fields */
|
|
Packit Service |
6d40f9 |
update_and_calculate_enctypes (enroll);
|
|
Packit Service |
6d40f9 |
update_computer_account (enroll);
|
|
Packit Service |
6d40f9 |
update_service_principals (enroll);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (flags & ADCLI_ENROLL_NO_KEYTAB)
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* Salting in the keytab is wild, we need to autodetect the format
|
|
Packit Service |
6d40f9 |
* that we use for salting.
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return update_keytab_for_principals (enroll);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_result
|
|
Packit Service |
6d40f9 |
adcli_enroll_join (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
adcli_enroll_flags flags)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res = ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_clear_last_error ();
|
|
Packit Service |
6d40f9 |
enroll_clear_state (enroll);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res = adcli_conn_discover (enroll->conn);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res = adcli_enroll_prepare (enroll, flags);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* This is where it really happens */
|
|
Packit Service |
6d40f9 |
res = locate_or_create_computer_account (enroll, flags & ADCLI_ENROLL_ALLOW_OVERWRITE);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return enroll_join_or_update_tasks (enroll, flags);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_result
|
|
Packit Service |
6d40f9 |
adcli_enroll_load (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_clear_last_error ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Load default info from keytab */
|
|
Packit Service |
6d40f9 |
res = load_host_keytab (enroll);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->computer_name)
|
|
Packit Service |
6d40f9 |
enroll->computer_name_explicit = 1;
|
|
Packit Service |
6d40f9 |
if (enroll->host_fqdn)
|
|
Packit Service |
6d40f9 |
enroll->host_fqdn_explicit = 1;
|
|
Packit Service |
6d40f9 |
if (enroll->service_principals)
|
|
Packit Service |
6d40f9 |
enroll->service_principals_explicit = 1;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_result
|
|
Packit Service |
6d40f9 |
adcli_enroll_update (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
adcli_enroll_flags flags)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res = ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
char *value;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_clear_last_error ();
|
|
Packit Service |
6d40f9 |
enroll_clear_state (enroll);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res = adcli_conn_discover (enroll->conn);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res = adcli_enroll_prepare (enroll, flags);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = adcli_conn_get_ldap_connection (enroll->conn);
|
|
Packit Service |
6d40f9 |
assert (ldap != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Find the computer dn */
|
|
Packit Service |
6d40f9 |
if (!enroll->computer_dn) {
|
|
Packit Service |
6d40f9 |
res = locate_computer_account (enroll, ldap, NULL, NULL);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
if (!enroll->computer_dn) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("No computer account for %s exists", enroll->computer_sam);
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Get information about the computer account */
|
|
Packit Service |
6d40f9 |
res = retrieve_computer_account (enroll);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = adcli_conn_get_ldap_connection (enroll->conn);
|
|
Packit Service |
6d40f9 |
assert (ldap != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
value = _adcli_ldap_parse_value (ldap,
|
|
Packit Service |
6d40f9 |
enroll->computer_attributes,
|
|
Packit Service |
6d40f9 |
"pwdLastSet");
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (_adcli_check_nt_time_string_lifetime (value,
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_computer_password_lifetime (enroll))) {
|
|
Packit Service |
6d40f9 |
flags |= ADCLI_ENROLL_NO_KEYTAB;
|
|
Packit Service |
6d40f9 |
flags |= ADCLI_ENROLL_PASSWORD_VALID;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
free (value);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return enroll_join_or_update_tasks (enroll, flags);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_result
|
|
Packit Service |
6d40f9 |
adcli_enroll_delete (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
adcli_enroll_flags delete_flags)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res = ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_clear_last_error ();
|
|
Packit Service |
6d40f9 |
enroll_clear_state (enroll);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res = adcli_conn_discover (enroll->conn);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Basic discovery and figuring out enroll params */
|
|
Packit Service |
6d40f9 |
res = ensure_host_fqdn (res, enroll);
|
|
Packit Service |
6d40f9 |
res = ensure_computer_name (res, enroll);
|
|
Packit Service |
6d40f9 |
res = ensure_computer_sam (res, enroll);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = adcli_conn_get_ldap_connection (enroll->conn);
|
|
Packit Service |
6d40f9 |
assert (ldap != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Find the computer dn */
|
|
Packit Service |
6d40f9 |
if (!enroll->computer_dn) {
|
|
Packit Service |
6d40f9 |
res = locate_computer_account (enroll, ldap, NULL, NULL);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
if (!enroll->computer_dn) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("No computer account for %s exists",
|
|
Packit Service |
6d40f9 |
enroll->computer_sam);
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return delete_computer_account (enroll, ldap);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_result
|
|
Packit Service |
6d40f9 |
adcli_enroll_password (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
adcli_enroll_flags password_flags)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res = ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_clear_last_error ();
|
|
Packit Service |
6d40f9 |
enroll_clear_state (enroll);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res = adcli_conn_discover (enroll->conn);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Basic discovery and figuring out enroll params */
|
|
Packit Service |
6d40f9 |
res = ensure_host_fqdn (res, enroll);
|
|
Packit Service |
6d40f9 |
res = ensure_computer_name (res, enroll);
|
|
Packit Service |
6d40f9 |
res = ensure_computer_sam (res, enroll);
|
|
Packit Service |
6d40f9 |
res = ensure_computer_password (res, enroll);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = adcli_conn_get_ldap_connection (enroll->conn);
|
|
Packit Service |
6d40f9 |
assert (ldap != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Find the computer dn */
|
|
Packit Service |
6d40f9 |
if (!enroll->computer_dn) {
|
|
Packit Service |
6d40f9 |
res = locate_computer_account (enroll, ldap, NULL, NULL);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
if (!enroll->computer_dn) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("No computer account for %s exists",
|
|
Packit Service |
6d40f9 |
enroll->computer_sam);
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return set_computer_password (enroll);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_enroll *
|
|
Packit Service |
6d40f9 |
adcli_enroll_new (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_enroll *enroll;
|
|
Packit Service |
6d40f9 |
const char *value;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enroll = calloc (1, sizeof (adcli_enroll));
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enroll->conn = adcli_conn_ref (conn);
|
|
Packit Service |
6d40f9 |
enroll->refs = 1;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Use the latter sections of host triple as OS name */
|
|
Packit Service |
6d40f9 |
value = strchr (HOST_TRIPLET, '-');
|
|
Packit Service |
6d40f9 |
if (value == NULL)
|
|
Packit Service |
6d40f9 |
value = HOST_TRIPLET;
|
|
Packit Service |
6d40f9 |
else
|
|
Packit Service |
6d40f9 |
value++;
|
|
Packit Service |
6d40f9 |
enroll->os_name = strdup (value);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll->os_name != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return enroll;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_enroll *
|
|
Packit Service |
6d40f9 |
adcli_enroll_ref (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
enroll->refs++;
|
|
Packit Service |
6d40f9 |
return enroll;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static void
|
|
Packit Service |
6d40f9 |
enroll_free (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
if (enroll == NULL)
|
|
Packit Service |
6d40f9 |
return;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enroll_clear_state (enroll);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (enroll->computer_sam);
|
|
Packit Service |
6d40f9 |
free (enroll->domain_ou);
|
|
Packit Service |
6d40f9 |
free (enroll->computer_dn);
|
|
Packit Service |
6d40f9 |
free (enroll->keytab_enctypes);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (enroll->os_name);
|
|
Packit Service |
6d40f9 |
free (enroll->os_version);
|
|
Packit Service |
6d40f9 |
free (enroll->os_service_pack);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (enroll->user_principal);
|
|
Packit Service |
6d40f9 |
_adcli_strv_free (enroll->service_names);
|
|
Packit Service |
6d40f9 |
_adcli_strv_free (enroll->service_principals);
|
|
Packit Service |
6d40f9 |
_adcli_password_free (enroll->computer_password);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_keytab_name (enroll, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_conn_unref (enroll->conn);
|
|
Packit Service |
6d40f9 |
free (enroll);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_unref (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
if (enroll == NULL)
|
|
Packit Service |
6d40f9 |
return;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (--(enroll->refs) > 0)
|
|
Packit Service |
6d40f9 |
return;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enroll_free (enroll);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_host_fqdn (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return enroll->host_fqdn;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_host_fqdn (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&enroll->host_fqdn, value);
|
|
Packit Service |
6d40f9 |
enroll->host_fqdn_explicit = 1;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_computer_name (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return enroll->computer_name;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_computer_name (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&enroll->computer_name, value);
|
|
Packit Service |
6d40f9 |
enroll->computer_name_explicit = (value != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_domain_ou (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return enroll->domain_ou;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_domain_ou (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enroll->domain_ou_validated = 0;
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&enroll->domain_ou, value);
|
|
Packit Service |
6d40f9 |
enroll->domain_ou_explicit = (value != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_computer_dn (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return enroll->computer_dn;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_computer_dn (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&enroll->computer_dn, value);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_computer_password (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return enroll->computer_password;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_computer_password (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
const char *password)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *newval = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (password) {
|
|
Packit Service |
6d40f9 |
newval = strdup (password);
|
|
Packit Service |
6d40f9 |
return_if_fail (newval != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->computer_password)
|
|
Packit Service |
6d40f9 |
_adcli_password_free (enroll->computer_password);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enroll->computer_password = newval;
|
|
Packit Service |
6d40f9 |
enroll->computer_password_explicit = (newval != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_reset_computer_password (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_password_free (enroll->computer_password);
|
|
Packit Service |
6d40f9 |
enroll->computer_password = NULL;
|
|
Packit Service |
6d40f9 |
enroll->computer_password_explicit = 0;
|
|
Packit Service |
6d40f9 |
enroll->reset_password = 1;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char **
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_service_names (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ensure_service_names (ADCLI_SUCCESS, enroll) != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return_val_if_reached (NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return (const char **)enroll->service_names;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_service_names (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
const char **value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_strv_set (&enroll->service_names, value);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_add_service_name (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
return_if_fail (value != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enroll->service_names = _adcli_strv_add (enroll->service_names, strdup (value), NULL);
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll->service_names != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char **
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_service_principals (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return (const char **)enroll->service_principals;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_service_principals (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
const char **value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_strv_set (&enroll->service_principals, value);
|
|
Packit Service |
6d40f9 |
enroll->service_principals_explicit = (value != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_kvno
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_kvno (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, 0);
|
|
Packit Service |
6d40f9 |
return enroll->kvno;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_kvno (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
krb5_kvno value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
enroll->kvno = value;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_keytab
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_keytab (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return enroll->keytab;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_keytab_name (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return enroll->keytab_name;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_keytab_name (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *newval = NULL;
|
|
Packit Service |
6d40f9 |
krb5_context k5;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->keytab_name) {
|
|
Packit Service |
6d40f9 |
if (enroll->keytab_name_is_krb5) {
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_if_fail (k5 != NULL);
|
|
Packit Service |
6d40f9 |
krb5_free_string (k5, enroll->keytab_name);
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
free (enroll->keytab_name);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (enroll->keytab) {
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (enroll->conn);
|
|
Packit Service |
6d40f9 |
return_if_fail (k5 != NULL);
|
|
Packit Service |
6d40f9 |
krb5_kt_close (k5, enroll->keytab);
|
|
Packit Service |
6d40f9 |
enroll->keytab = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (value) {
|
|
Packit Service |
6d40f9 |
newval = strdup (value);
|
|
Packit Service |
6d40f9 |
return_if_fail (newval != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enroll->keytab_name = newval;
|
|
Packit Service |
6d40f9 |
enroll->keytab_name_is_krb5 = 0;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_enctype *
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_keytab_enctypes (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
if (enroll->keytab_enctypes)
|
|
Packit Service |
6d40f9 |
return enroll->keytab_enctypes;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (adcli_conn_server_has_capability (enroll->conn, ADCLI_CAP_V60_OID))
|
|
Packit Service |
6d40f9 |
return v60_later_enctypes;
|
|
Packit Service |
6d40f9 |
else
|
|
Packit Service |
6d40f9 |
return v51_earlier_enctypes;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_keytab_enctypes (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
krb5_enctype *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
krb5_enctype *newval = NULL;
|
|
Packit Service |
6d40f9 |
int len;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (value) {
|
|
Packit Service |
6d40f9 |
for (len = 0; value[len] != 0; len++);
|
|
Packit Service |
6d40f9 |
newval = malloc (sizeof (krb5_enctype) * (len + 1));
|
|
Packit Service |
6d40f9 |
return_if_fail (newval != NULL);
|
|
Packit Service |
6d40f9 |
memcpy (newval, value, sizeof (krb5_enctype) * (len + 1));
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (enroll->keytab_enctypes);
|
|
Packit Service |
6d40f9 |
enroll->keytab_enctypes = newval;
|
|
Packit Service |
6d40f9 |
enroll->keytab_enctypes_explicit = (newval != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_os_name (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return enroll->os_name;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_os_name (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
if (value && value[0] == '\0')
|
|
Packit Service |
6d40f9 |
value = NULL;
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&enroll->os_name, value);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_os_version (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return enroll->os_version;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_os_version (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
if (value && value[0] == '\0')
|
|
Packit Service |
6d40f9 |
value = NULL;
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&enroll->os_version, value);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_os_service_pack (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return enroll->os_service_pack;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_os_service_pack (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
if (value && value[0] == '\0')
|
|
Packit Service |
6d40f9 |
value = NULL;
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&enroll->os_service_pack, value);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_user_principal (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return enroll->user_principal;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_user_principal (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&enroll->user_principal, value);
|
|
Packit Service |
6d40f9 |
enroll->user_princpal_generate = 0;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_auto_user_principal (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&enroll->user_principal, NULL);
|
|
Packit Service |
6d40f9 |
enroll->user_princpal_generate = 1;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#define DEFAULT_HOST_PW_LIFETIME 30
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
unsigned int
|
|
Packit Service |
6d40f9 |
adcli_enroll_get_computer_password_lifetime (adcli_enroll *enroll)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (enroll != NULL, DEFAULT_HOST_PW_LIFETIME);
|
|
Packit Service |
6d40f9 |
if (enroll->computer_password_lifetime_explicit) {
|
|
Packit Service |
6d40f9 |
return enroll->computer_password_lifetime;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
return DEFAULT_HOST_PW_LIFETIME;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_enroll_set_computer_password_lifetime (adcli_enroll *enroll,
|
|
Packit Service |
6d40f9 |
unsigned int lifetime)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (enroll != NULL);
|
|
Packit Service |
6d40f9 |
enroll->computer_password_lifetime = lifetime;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
enroll->computer_password_lifetime_explicit = 1;
|
|
Packit Service |
6d40f9 |
}
|