|
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 "adcli.h"
|
|
Packit Service |
6d40f9 |
#include "adprivate.h"
|
|
Packit Service |
6d40f9 |
#include "addisco.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 |
#include <sys/stat.h>
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#include <assert.h>
|
|
Packit Service |
6d40f9 |
#include <errno.h>
|
|
Packit Service |
6d40f9 |
#include <netdb.h>
|
|
Packit Service |
6d40f9 |
#include <stdio.h>
|
|
Packit Service |
6d40f9 |
#include <stdlib.h>
|
|
Packit Service |
6d40f9 |
#include <string.h>
|
|
Packit Service |
6d40f9 |
#include <unistd.h>
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
struct _adcli_conn_ctx {
|
|
Packit Service |
6d40f9 |
int refs;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Input/output params */
|
|
Packit Service |
6d40f9 |
char *user_name;
|
|
Packit Service |
6d40f9 |
char *user_password;
|
|
Packit Service |
6d40f9 |
char *computer_name;
|
|
Packit Service |
6d40f9 |
char *computer_password;
|
|
Packit Service |
6d40f9 |
char *login_ccache_name;
|
|
Packit Service |
6d40f9 |
int login_ccache_name_is_krb5;
|
|
Packit Service |
6d40f9 |
char *login_keytab_name;
|
|
Packit Service |
6d40f9 |
int login_keytab_name_is_krb5;
|
|
Packit Service |
6d40f9 |
adcli_login_type login_type;
|
|
Packit Service |
6d40f9 |
int logins_allowed;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
char *krb5_conf_dir;
|
|
Packit Service |
6d40f9 |
char *krb5_conf_snippet;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_password_func password_func;
|
|
Packit Service |
6d40f9 |
adcli_destroy_func password_destroy;
|
|
Packit Service |
6d40f9 |
void *password_data;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
char *host_fqdn;
|
|
Packit Service |
6d40f9 |
char *domain_name;
|
|
Packit Service |
6d40f9 |
char *domain_realm;
|
|
Packit Service |
6d40f9 |
char *domain_controller;
|
|
Packit Service |
6d40f9 |
char *canonical_host;
|
|
Packit Service |
6d40f9 |
char *domain_short;
|
|
Packit Service |
47fa62 |
char *domain_sid;
|
|
Packit Service |
6d40f9 |
adcli_disco *domain_disco;
|
|
Packit Service |
6d40f9 |
char *default_naming_context;
|
|
Packit Service |
6d40f9 |
char *configuration_naming_context;
|
|
Packit Service |
6d40f9 |
char **supported_capabilities;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Connect state */
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
int ldap_authenticated;
|
|
Packit Service |
6d40f9 |
krb5_context k5;
|
|
Packit Service |
6d40f9 |
krb5_ccache ccache;
|
|
Packit Service |
6d40f9 |
krb5_keytab keytab;
|
|
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_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char hostname[HOST_NAME_MAX + 1];
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->host_fqdn) {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Using fully qualified name: %s", conn->host_fqdn);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ret = gethostname (hostname, sizeof (hostname));
|
|
Packit Service |
6d40f9 |
if (ret < 0) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't get local hostname: %s", strerror (errno));
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_UNEXPECTED;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn->host_fqdn = strdup (hostname);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (conn->host_fqdn != NULL);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static void
|
|
Packit Service |
6d40f9 |
disco_dance_if_necessary (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
if (conn->domain_disco)
|
|
Packit Service |
6d40f9 |
return;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->domain_controller)
|
|
Packit Service |
6d40f9 |
adcli_disco_host (conn->domain_controller, &conn->domain_disco);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
else if (conn->domain_name)
|
|
Packit Service |
6d40f9 |
adcli_disco_domain (conn->domain_name, &conn->domain_disco);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->domain_disco) {
|
|
Packit Service |
6d40f9 |
if (!conn->domain_short && conn->domain_disco->domain_short) {
|
|
Packit Service |
6d40f9 |
conn->domain_short = strdup (conn->domain_disco->domain_short);
|
|
Packit Service |
6d40f9 |
return_if_fail (conn->domain_short != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static void
|
|
Packit Service |
6d40f9 |
no_more_disco (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
if (conn->domain_disco)
|
|
Packit Service |
6d40f9 |
adcli_disco_free (conn->domain_disco);
|
|
Packit Service |
6d40f9 |
conn->domain_disco = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
ensure_domain_and_host (adcli_result res,
|
|
Packit Service |
6d40f9 |
adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
const char *dom;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->domain_name) {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Using domain name: %s", conn->domain_name);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (conn->host_fqdn != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
disco_dance_if_necessary (conn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->domain_disco && conn->domain_disco->domain) {
|
|
Packit Service |
6d40f9 |
conn->domain_name = strdup (conn->domain_disco->domain);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (conn->domain_name != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_info ("Discovered domain name: %s", conn->domain_name);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Use the FQDN minus the last part */
|
|
Packit Service |
6d40f9 |
dom = strchr (conn->host_fqdn, '.');
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* If no dot, or dot is first or last, then fail */
|
|
Packit Service |
6d40f9 |
if (dom == NULL || dom == conn->host_fqdn || dom[1] == '\0') {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't determine the domain name from host name: %s",
|
|
Packit Service |
6d40f9 |
conn->host_fqdn);
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_FAIL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn->domain_name = strdup (dom + 1);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (conn->domain_name != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_info ("Calculated domain name from host fqdn: %s",
|
|
Packit Service |
6d40f9 |
conn->domain_name);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
char *
|
|
Packit Service |
6d40f9 |
_adcli_calc_netbios_name (const char *host_fqdn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
const char *dom;
|
|
Packit Service |
6d40f9 |
char *computer_name;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Use the FQDN minus the last part */
|
|
Packit Service |
6d40f9 |
dom = strchr (host_fqdn, '.');
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* If dot is first then fail */
|
|
Packit Service |
6d40f9 |
if (dom == host_fqdn) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't determine the computer account name from host name: %s",
|
|
Packit Service |
6d40f9 |
host_fqdn);
|
|
Packit Service |
6d40f9 |
return NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else if (dom == NULL) {
|
|
Packit Service |
6d40f9 |
computer_name = strdup (host_fqdn);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (computer_name != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
computer_name = strndup (host_fqdn, dom - host_fqdn);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (computer_name != NULL, NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_str_up (computer_name);
|
|
Packit Service |
6d40f9 |
if (strlen (computer_name) > 15) {
|
|
Packit Service |
6d40f9 |
computer_name[15] = 0;
|
|
Packit Service |
6d40f9 |
_adcli_info ("Truncated computer account name from fqdn: %s", computer_name);
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Calculated computer account name from fqdn: %s", computer_name);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return computer_name;
|
|
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_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->computer_name) {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Using computer account name: %s", conn->computer_name);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (conn->host_fqdn != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn->computer_name = _adcli_calc_netbios_name (conn->host_fqdn);
|
|
Packit Service |
6d40f9 |
if (conn->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 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
ensure_domain_realm (adcli_result res,
|
|
Packit Service |
6d40f9 |
adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->domain_realm) {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Using domain realm: %s", conn->domain_name);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn->domain_realm = strdup (conn->domain_name);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (conn->domain_realm != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_str_up (conn->domain_realm);
|
|
Packit Service |
6d40f9 |
_adcli_info ("Calculated domain realm from name: %s",
|
|
Packit Service |
6d40f9 |
conn->domain_realm);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
ensure_user_password (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
if (conn->login_ccache_name != NULL ||
|
|
Packit Service |
6d40f9 |
conn->user_password != NULL)
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->password_func) {
|
|
Packit Service |
6d40f9 |
conn->user_password = (conn->password_func) (ADCLI_LOGIN_USER_ACCOUNT,
|
|
Packit Service |
6d40f9 |
conn->user_name, 0,
|
|
Packit Service |
6d40f9 |
conn->password_data);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->user_password == NULL) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("No admin password or credential cache specified");
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CREDENTIALS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
char *
|
|
Packit Service |
6d40f9 |
_adcli_calc_reset_password (const char *computer_name)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *password;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (computer_name != NULL);
|
|
Packit Service |
6d40f9 |
password = strdup (computer_name);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (password != NULL, NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_down (password);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return password;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
handle_kinit_krb5_code (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
adcli_login_type type,
|
|
Packit Service |
6d40f9 |
const char *name,
|
|
Packit Service |
6d40f9 |
krb5_error_code code)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
if (code == 0) {
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else if (code == ENOMEM) {
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else if (code == KRB5KDC_ERR_PREAUTH_FAILED ||
|
|
Packit Service |
6d40f9 |
code == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN ||
|
|
Packit Service |
6d40f9 |
code == KRB5KDC_ERR_KEY_EXP ||
|
|
Packit Service |
6d40f9 |
code == KRB5KDC_ERR_CLIENT_REVOKED ||
|
|
Packit Service |
6d40f9 |
code == KRB5KDC_ERR_POLICY ||
|
|
Packit Service |
6d40f9 |
code == KRB5KDC_ERR_ETYPE_NOSUPP ||
|
|
Packit Service |
6d40f9 |
code == KRB5_PREAUTH_FAILED) {
|
|
Packit Service |
6d40f9 |
if (type == ADCLI_LOGIN_COMPUTER_ACCOUNT) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't authenticate as machine account: %s: %s",
|
|
Packit Service |
6d40f9 |
name, krb5_get_error_message (conn->k5, code));
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't authenticate as: %s: %s",
|
|
Packit Service |
6d40f9 |
name, krb5_get_error_message (conn->k5, code));
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CREDENTIALS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
if (type == ADCLI_LOGIN_COMPUTER_ACCOUNT) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't get kerberos ticket for machine account: %s: %s",
|
|
Packit Service |
6d40f9 |
name, krb5_get_error_message (conn->k5, code));
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't get kerberos ticket for: %s: %s",
|
|
Packit Service |
6d40f9 |
name, krb5_get_error_message (conn->k5, code));
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_DIRECTORY;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static void
|
|
Packit Service |
6d40f9 |
clear_krb5_conf_snippet (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
if (conn->krb5_conf_snippet) {
|
|
Packit Service |
6d40f9 |
if (unlink (conn->krb5_conf_snippet) < 0) {
|
|
Packit Service |
6d40f9 |
_adcli_warn ("Couldn't remove krb5.conf snippet file: %s: %s",
|
|
Packit Service |
6d40f9 |
conn->krb5_conf_snippet, strerror (errno));
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
free (conn->krb5_conf_snippet);
|
|
Packit Service |
6d40f9 |
conn->krb5_conf_snippet = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
setup_krb5_conf_snippet (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *filename;
|
|
Packit Service |
6d40f9 |
char *snippet;
|
|
Packit Service |
6d40f9 |
char *controller;
|
|
Packit Service |
6d40f9 |
int errn;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
int fd;
|
|
Packit Service |
6d40f9 |
mode_t old_mask;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!conn->krb5_conf_dir)
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Already written out the conf snippet */
|
|
Packit Service |
6d40f9 |
if (conn->krb5_conf_snippet)
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
clear_krb5_conf_snippet (conn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (asprintf (&filename, "%s/adcli-krb5-conf-XXXXXX", conn->krb5_conf_dir) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (strchr (conn->domain_controller, ':')) {
|
|
Packit Service |
6d40f9 |
if (asprintf (&controller, "[%s]", conn->domain_controller) < 0)
|
|
Packit Service |
6d40f9 |
controller = NULL;
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
controller = strdup (conn->domain_controller);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (controller != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (asprintf (&snippet, "[realms]\n"
|
|
Packit Service |
6d40f9 |
" %s = {\n"
|
|
Packit Service |
6d40f9 |
" kdc = %s:88\n"
|
|
Packit Service |
6d40f9 |
" master_kdc = %s:88\n"
|
|
Packit Service |
6d40f9 |
" kpasswd_server = %s\n"
|
|
Packit Service |
6d40f9 |
" }\n"
|
|
Packit Service |
6d40f9 |
"[domain_realm]\n"
|
|
Packit Service |
6d40f9 |
" %s = %s\n"
|
|
Packit Service |
6d40f9 |
" %s = %s\n",
|
|
Packit Service |
6d40f9 |
conn->domain_realm, controller, controller, controller,
|
|
Packit Service |
6d40f9 |
conn->canonical_host, conn->domain_realm,
|
|
Packit Service |
6d40f9 |
conn->domain_controller, conn->domain_realm) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
old_mask = umask (0177);
|
|
Packit Service |
6d40f9 |
fd = mkstemp (filename);
|
|
Packit Service |
6d40f9 |
umask (old_mask);
|
|
Packit Service |
6d40f9 |
if (fd < 0) {
|
|
Packit Service |
6d40f9 |
_adcli_warn ("Couldn't create krb5.conf snippet file in: %s: %s",
|
|
Packit Service |
6d40f9 |
conn->krb5_conf_dir, strerror (errno));
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
conn->krb5_conf_snippet = filename;
|
|
Packit Service |
6d40f9 |
ret = _adcli_write_all (fd, snippet, -1);
|
|
Packit Service |
6d40f9 |
errn = errno;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ret >= 0) {
|
|
Packit Service |
6d40f9 |
ret = close (fd);
|
|
Packit Service |
6d40f9 |
errn = errno;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
close (fd);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ret < 0) {
|
|
Packit Service |
6d40f9 |
_adcli_warn ("Couldn't write krb5.conf snippet file in: %s: %s",
|
|
Packit Service |
6d40f9 |
filename, strerror (errn));
|
|
Packit Service |
6d40f9 |
clear_krb5_conf_snippet (conn);
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Wrote out krb5.conf snippet to %s", filename);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (controller);
|
|
Packit Service |
6d40f9 |
free (snippet);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* This shouldn't stop joining */
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* HACK: This is to work around a bug in krb5 where if an empty password
|
|
Packit Service |
6d40f9 |
* preauth will fail unless a prompter is present.
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
static krb5_error_code
|
|
Packit Service |
6d40f9 |
null_prompter (krb5_context context,
|
|
Packit Service |
6d40f9 |
void *data,
|
|
Packit Service |
6d40f9 |
const char *name,
|
|
Packit Service |
6d40f9 |
const char *banner,
|
|
Packit Service |
6d40f9 |
int num_prompts,
|
|
Packit Service |
6d40f9 |
krb5_prompt prompts[])
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
int i;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (i = 0; i < num_prompts; i++)
|
|
Packit Service |
6d40f9 |
prompts[i].reply->length = 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return 0;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_error_code
|
|
Packit Service |
6d40f9 |
_adcli_kinit_computer_creds (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *in_tkt_service,
|
|
Packit Service |
6d40f9 |
krb5_ccache ccache,
|
|
Packit Service |
6d40f9 |
krb5_creds *creds)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
krb5_get_init_creds_opt *opt;
|
|
Packit Service |
6d40f9 |
krb5_principal principal;
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
krb5_context k5;
|
|
Packit Service |
6d40f9 |
krb5_creds dummy;
|
|
Packit Service |
6d40f9 |
char *new_password;
|
|
Packit Service |
6d40f9 |
const char *password;
|
|
Packit Service |
6d40f9 |
char *sam;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (conn != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (conn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (asprintf (&sam, "%s$", conn->computer_name) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = _adcli_krb5_build_principal (k5, sam, conn->domain_realm, &principal);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (code == 0, code);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = krb5_get_init_creds_opt_alloc (k5, &opt;;
|
|
Packit Service |
6d40f9 |
return_val_if_fail (code == 0, code);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ccache) {
|
|
Packit Service |
6d40f9 |
code = krb5_get_init_creds_opt_set_out_ccache (k5, opt, ccache);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (code == 0, code);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
memset (&dummy, 0, sizeof (dummy));
|
|
Packit Service |
6d40f9 |
if (!creds)
|
|
Packit Service |
6d40f9 |
creds = &dummy;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
password = conn->computer_password;
|
|
Packit Service |
6d40f9 |
new_password = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* Note that we only prompt for computer account passwords if
|
|
Packit Service |
6d40f9 |
* explicitly requested.
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->keytab) {
|
|
Packit Service |
6d40f9 |
code = krb5_get_init_creds_keytab (k5, creds, principal, conn->keytab,
|
|
Packit Service |
6d40f9 |
0, (char *)in_tkt_service, opt);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
if (!password && conn->password_func &&
|
|
Packit Service |
6d40f9 |
conn->logins_allowed == ADCLI_LOGIN_COMPUTER_ACCOUNT) {
|
|
Packit Service |
6d40f9 |
new_password = (conn->password_func) (ADCLI_LOGIN_COMPUTER_ACCOUNT,
|
|
Packit Service |
6d40f9 |
sam, 0, conn->password_data);
|
|
Packit Service |
6d40f9 |
password = new_password;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (password == NULL) {
|
|
Packit Service |
6d40f9 |
new_password = _adcli_calc_reset_password (conn->computer_name);
|
|
Packit Service |
6d40f9 |
password = new_password;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = krb5_get_init_creds_password (k5, creds, principal, (char *)password,
|
|
Packit Service |
6d40f9 |
null_prompter, NULL, 0, (char *)in_tkt_service, opt);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (code == 0 && new_password) {
|
|
Packit Service |
6d40f9 |
_adcli_password_free (conn->computer_password);
|
|
Packit Service |
6d40f9 |
conn->computer_password = new_password;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_free_principal (k5, principal);
|
|
Packit Service |
6d40f9 |
krb5_get_init_creds_opt_free (k5, opt);
|
|
Packit Service |
6d40f9 |
krb5_free_cred_contents (k5, &dummy);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (sam);
|
|
Packit Service |
6d40f9 |
return code;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_error_code
|
|
Packit Service |
6d40f9 |
_adcli_kinit_user_creds (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *in_tkt_service,
|
|
Packit Service |
6d40f9 |
krb5_ccache ccache,
|
|
Packit Service |
6d40f9 |
krb5_creds *creds)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
krb5_get_init_creds_opt *opt;
|
|
Packit Service |
6d40f9 |
krb5_principal principal;
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
krb5_context k5;
|
|
Packit Service |
6d40f9 |
krb5_creds dummy;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (conn != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
k5 = adcli_conn_get_krb5_context (conn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = krb5_parse_name (k5, conn->user_name, &principal);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (code == 0, code);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = krb5_get_init_creds_opt_alloc (k5, &opt;;
|
|
Packit Service |
6d40f9 |
return_val_if_fail (code == 0, code);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ccache) {
|
|
Packit Service |
6d40f9 |
code = krb5_get_init_creds_opt_set_out_ccache (k5, opt, ccache);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (code == 0, code);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
memset (&dummy, 0, sizeof (dummy));
|
|
Packit Service |
6d40f9 |
if (!creds)
|
|
Packit Service |
6d40f9 |
creds = &dummy;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = krb5_get_init_creds_password (k5, creds, principal,
|
|
Packit Service |
6d40f9 |
conn->user_password, null_prompter, NULL,
|
|
Packit Service |
6d40f9 |
0, (char *)in_tkt_service, opt);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_free_principal (k5, principal);
|
|
Packit Service |
6d40f9 |
krb5_get_init_creds_opt_free (k5, opt);
|
|
Packit Service |
6d40f9 |
krb5_free_cred_contents (k5, &dummy);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return code;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
kinit_with_computer_credentials (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
krb5_ccache ccache)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
int use_default;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
use_default = (conn->computer_password == NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = _adcli_kinit_computer_creds (conn, NULL, ccache, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (code == 0) {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Authenticated as %scomputer account: %s",
|
|
Packit Service |
6d40f9 |
use_default ? "default/reset " : "", conn->computer_name);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn->login_type = ADCLI_LOGIN_COMPUTER_ACCOUNT;
|
|
Packit Service |
6d40f9 |
res = ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
res = handle_kinit_krb5_code (conn, ADCLI_LOGIN_COMPUTER_ACCOUNT,
|
|
Packit Service |
6d40f9 |
conn->computer_name, code);
|
|
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 |
kinit_with_user_credentials (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
krb5_ccache ccache)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
char *name;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Build out the admin principal name */
|
|
Packit Service |
6d40f9 |
if (!conn->user_name) {
|
|
Packit Service |
6d40f9 |
if (asprintf (&conn->user_name, "Administrator@%s", conn->domain_realm) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
} else if (strchr (conn->user_name, '@') == NULL) {
|
|
Packit Service |
6d40f9 |
if (asprintf (&name, "%s@%s", conn->user_name, conn->domain_realm) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
free (conn->user_name);
|
|
Packit Service |
6d40f9 |
conn->user_name = name;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res = ensure_user_password (conn);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
code = _adcli_kinit_user_creds (conn, NULL, ccache, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (code == 0) {
|
|
Packit Service |
6d40f9 |
conn->login_type = ADCLI_LOGIN_USER_ACCOUNT;
|
|
Packit Service |
6d40f9 |
_adcli_info ("Authenticated as user: %s", conn->user_name);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return handle_kinit_krb5_code (conn, ADCLI_LOGIN_USER_ACCOUNT, conn->user_name, code);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
prep_kerberos_and_kinit (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
krb5_error_code code;
|
|
Packit Service |
6d40f9 |
int logged_in = 0;
|
|
Packit Service |
6d40f9 |
krb5_ccache ccache;
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->login_ccache_name != NULL) {
|
|
Packit Service |
6d40f9 |
if (!conn->ccache) {
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* If we already have a kerberos ccache file, just open it. This
|
|
Packit Service |
6d40f9 |
* serves two purposes:
|
|
Packit Service |
6d40f9 |
* a) We want to make sure it's present, so we can provide more
|
|
Packit Service |
6d40f9 |
* intelligible messages than ldap_sasl_interactive_bind_s()
|
|
Packit Service |
6d40f9 |
* b) We want to have the ccache member populated so we can use
|
|
Packit Service |
6d40f9 |
* it in other operations such as changing the computer password.
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (strcmp (conn->login_ccache_name, "") == 0) {
|
|
Packit Service |
6d40f9 |
code = krb5_cc_default (conn->k5, &conn->ccache);
|
|
Packit Service |
6d40f9 |
if (code == 0) {
|
|
Packit Service |
6d40f9 |
free (conn->login_ccache_name);
|
|
Packit Service |
6d40f9 |
conn->login_ccache_name = NULL;
|
|
Packit Service |
6d40f9 |
code = krb5_cc_get_full_name (conn->k5, conn->ccache,
|
|
Packit Service |
6d40f9 |
&conn->login_ccache_name);
|
|
Packit Service |
6d40f9 |
conn->login_ccache_name_is_krb5 = 1;
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (code == 0);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
code = krb5_cc_resolve (conn->k5, conn->login_ccache_name, &conn->ccache);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (code != 0) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't open kerberos credential cache: %s: %s",
|
|
Packit Service |
6d40f9 |
conn->login_ccache_name, krb5_get_error_message (NULL, code));
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->login_keytab_name != NULL) {
|
|
Packit Service |
6d40f9 |
if (!conn->keytab) {
|
|
Packit Service |
6d40f9 |
res = _adcli_krb5_open_keytab (conn->k5, conn->login_keytab_name, &conn->keytab);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS) {
|
|
Packit Service |
6d40f9 |
if (res == ADCLI_ERR_FAIL)
|
|
Packit Service |
6d40f9 |
res = ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (strcmp (conn->login_keytab_name, "") == 0) {
|
|
Packit Service |
6d40f9 |
free (conn->login_keytab_name);
|
|
Packit Service |
6d40f9 |
conn->login_keytab_name = malloc (MAX_KEYTAB_NAME_LEN);
|
|
Packit Service |
6d40f9 |
code = krb5_kt_get_name (conn->k5, conn->keytab,
|
|
Packit Service |
6d40f9 |
conn->login_keytab_name, MAX_KEYTAB_NAME_LEN);
|
|
Packit Service |
6d40f9 |
conn->login_keytab_name_is_krb5 = 1;
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (code == 0);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Initialize the credential cache */
|
|
Packit Service |
6d40f9 |
code = krb5_cc_new_unique (conn->k5, "MEMORY", NULL, &ccache);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (code == 0);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* Should we try to connect with computer account default password?
|
|
Packit Service |
6d40f9 |
* This is the password set by 'Reset Accuont' on a computer object.
|
|
Packit Service |
6d40f9 |
* If the caller explicitly specified a login name or password, then
|
|
Packit Service |
6d40f9 |
* go straight to that.
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->logins_allowed & ADCLI_LOGIN_COMPUTER_ACCOUNT) {
|
|
Packit Service |
6d40f9 |
res = kinit_with_computer_credentials (conn, ccache);
|
|
Packit Service |
6d40f9 |
logged_in = (res == ADCLI_SUCCESS);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Use login credentials */
|
|
Packit Service |
6d40f9 |
if (!logged_in && (conn->logins_allowed & ADCLI_LOGIN_USER_ACCOUNT)) {
|
|
Packit Service |
6d40f9 |
res = kinit_with_user_credentials (conn, ccache);
|
|
Packit Service |
6d40f9 |
logged_in = (res == ADCLI_SUCCESS);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (logged_in) {
|
|
Packit Service |
6d40f9 |
code = krb5_cc_get_full_name (conn->k5, ccache,
|
|
Packit Service |
6d40f9 |
&conn->login_ccache_name);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (code == 0);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn->ccache = ccache;
|
|
Packit Service |
6d40f9 |
conn->login_ccache_name_is_krb5 = 1;
|
|
Packit Service |
6d40f9 |
ccache = NULL;
|
|
Packit Service |
6d40f9 |
res = ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
res = ADCLI_ERR_FAIL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ccache != NULL)
|
|
Packit Service |
6d40f9 |
krb5_cc_close (conn->k5, ccache);
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Not included in ldap.h but documented */
|
|
Packit Service |
6d40f9 |
int ldap_init_fd (ber_socket_t fd, int proto, LDAP_CONST char *url, struct ldap **ldp);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static LDAP *
|
|
Packit Service |
6d40f9 |
connect_to_address (const char *host,
|
|
Packit Service |
6d40f9 |
const char *canonical_host)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
struct addrinfo *res = NULL;
|
|
Packit Service |
6d40f9 |
struct addrinfo *ai;
|
|
Packit Service |
6d40f9 |
struct addrinfo hints;
|
|
Packit Service |
6d40f9 |
LDAP *ldap = NULL;
|
|
Packit Service |
6d40f9 |
int error = 0;
|
|
Packit Service |
6d40f9 |
char *url;
|
|
Packit Service |
6d40f9 |
int sock;
|
|
Packit Service |
6d40f9 |
int rc;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
memset (&hints, '\0', sizeof(hints));
|
|
Packit Service |
6d40f9 |
#ifdef AI_ADDRCONFIG
|
|
Packit Service |
6d40f9 |
hints.ai_flags |= AI_ADDRCONFIG;
|
|
Packit Service |
6d40f9 |
#endif
|
|
Packit Service |
6d40f9 |
hints.ai_socktype = SOCK_STREAM;
|
|
Packit Service |
6d40f9 |
hints.ai_protocol = IPPROTO_TCP;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!canonical_host)
|
|
Packit Service |
6d40f9 |
canonical_host = host;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
rc = getaddrinfo (host, "389", &hints, &res;;
|
|
Packit Service |
6d40f9 |
if (rc != 0) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't resolve host name: %s: %s", host, gai_strerror (rc));
|
|
Packit Service |
6d40f9 |
return NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (ai = res; ai != NULL; ai = ai->ai_next) {
|
|
Packit Service |
6d40f9 |
/* coverity[overwrite_var] */
|
|
Packit Service |
6d40f9 |
sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
|
Packit Service |
6d40f9 |
if (sock < 0) {
|
|
Packit Service |
6d40f9 |
error = errno;
|
|
Packit Service |
6d40f9 |
} else if (connect (sock, ai->ai_addr, ai->ai_addrlen) < 0) {
|
|
Packit Service |
6d40f9 |
error = errno;
|
|
Packit Service |
6d40f9 |
close (sock);
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
error = 0;
|
|
Packit Service |
6d40f9 |
if (asprintf (&url, "ldap://%s", canonical_host) < 0)
|
|
Packit Service |
6d40f9 |
return_val_if_reached (NULL);
|
|
Packit Service |
6d40f9 |
rc = ldap_init_fd (sock, 1, url, &ldap);
|
|
Packit Service |
6d40f9 |
free (url);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (rc != LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't initialize LDAP connection: %s:",
|
|
Packit Service |
6d40f9 |
ldap_err2string (rc));
|
|
Packit Service |
6d40f9 |
break;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!ldap && error)
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't connect to host: %s: %s", host, strerror (error));
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
freeaddrinfo (res);
|
|
Packit Service |
6d40f9 |
/* coverity[leaked_handle] - the socket is carried inside the ldap struct */
|
|
Packit Service |
6d40f9 |
return ldap;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
connect_and_lookup_naming (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
adcli_disco *disco)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *canonical_host;
|
|
Packit Service |
6d40f9 |
LDAPMessage *results;
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
int ver;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
char *attrs[] = {
|
|
Packit Service |
6d40f9 |
"defaultNamingContext",
|
|
Packit Service |
6d40f9 |
"configurationNamingContext",
|
|
Packit Service |
6d40f9 |
"supportedCapabilities",
|
|
Packit Service |
6d40f9 |
NULL
|
|
Packit Service |
6d40f9 |
};
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (conn->ldap == NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
canonical_host = disco->host_name;
|
|
Packit Service |
6d40f9 |
if (!canonical_host)
|
|
Packit Service |
6d40f9 |
canonical_host = disco->host_addr;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = connect_to_address (disco->host_addr, canonical_host);
|
|
Packit Service |
6d40f9 |
if (ldap == NULL)
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_DIRECTORY;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ver = LDAP_VERSION3;
|
|
Packit Service |
6d40f9 |
if (ldap_set_option (ldap, LDAP_OPT_PROTOCOL_VERSION, &ver) != 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ldap_set_option (ldap, LDAP_OPT_REFERRALS, LDAP_OPT_OFF) != 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Don't force GSSAPI to use reverse DNS */
|
|
Packit Service |
6d40f9 |
if (ldap_set_option (ldap, LDAP_OPT_X_SASL_NOCANON, LDAP_OPT_ON) != 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* We perform this lookup whether or not we want to lookup the
|
|
Packit Service |
6d40f9 |
* naming context, as it also connects to the LDAP server.
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
ret = ldap_search_ext_s (ldap, "", LDAP_SCOPE_BASE, "(objectClass=*)",
|
|
Packit Service |
6d40f9 |
attrs, 0, NULL, NULL, NULL, -1, &results);
|
|
Packit Service |
6d40f9 |
if (ret != LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
res = _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY,
|
|
Packit Service |
6d40f9 |
"Couldn't connect to LDAP server: %s", disco->host_addr);
|
|
Packit Service |
6d40f9 |
ldap_unbind_ext_s (ldap, NULL, NULL);
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->default_naming_context == NULL) {
|
|
Packit Service |
6d40f9 |
conn->default_naming_context = _adcli_ldap_parse_value (ldap, results,
|
|
Packit Service |
6d40f9 |
"defaultNamingContext");
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->configuration_naming_context == NULL) {
|
|
Packit Service |
6d40f9 |
conn->configuration_naming_context = _adcli_ldap_parse_value (ldap, results,
|
|
Packit Service |
6d40f9 |
"configurationNamingContext");
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->supported_capabilities == NULL) {
|
|
Packit Service |
6d40f9 |
conn->supported_capabilities = _adcli_ldap_parse_values (ldap, results,
|
|
Packit Service |
6d40f9 |
"supportedCapabilities");
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap_msgfree (results);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->default_naming_context == NULL) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("No valid LDAP naming context on domain controller: %s", disco->host_addr);
|
|
Packit Service |
6d40f9 |
ldap_unbind_ext_s (ldap, NULL, NULL);
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_DIRECTORY;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->configuration_naming_context == NULL) {
|
|
Packit Service |
6d40f9 |
if (asprintf (&conn->configuration_naming_context,
|
|
Packit Service |
6d40f9 |
"CN=Configuration,%s", conn->default_naming_context))
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn->ldap = ldap;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (conn->canonical_host);
|
|
Packit Service |
6d40f9 |
conn->canonical_host = strdup (canonical_host);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (conn->canonical_host != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_conn_set_domain_controller (conn, disco->host_addr);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static int
|
|
Packit Service |
6d40f9 |
sasl_interact (LDAP *ld,
|
|
Packit Service |
6d40f9 |
unsigned flags,
|
|
Packit Service |
6d40f9 |
void *defaults,
|
|
Packit Service |
6d40f9 |
void *interact)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
sasl_interact_t *in = (sasl_interact_t *)interact;
|
|
Packit Service |
6d40f9 |
return_val_if_fail (ld != NULL, LDAP_PARAM_ERROR);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
while (in->id != SASL_CB_LIST_END) {
|
|
Packit Service |
6d40f9 |
switch (in->id) {
|
|
Packit Service |
6d40f9 |
case SASL_CB_GETREALM:
|
|
Packit Service |
6d40f9 |
case SASL_CB_USER:
|
|
Packit Service |
6d40f9 |
case SASL_CB_PASS:
|
|
Packit Service |
6d40f9 |
if (in->defresult)
|
|
Packit Service |
6d40f9 |
in->result = in->defresult;
|
|
Packit Service |
6d40f9 |
else
|
|
Packit Service |
6d40f9 |
in->result = "";
|
|
Packit Service |
6d40f9 |
in->len = strlen (in->result);
|
|
Packit Service |
6d40f9 |
break;
|
|
Packit Service |
6d40f9 |
case SASL_CB_AUTHNAME:
|
|
Packit Service |
6d40f9 |
if (in->defresult)
|
|
Packit Service |
6d40f9 |
in->result = in->defresult;
|
|
Packit Service |
6d40f9 |
else
|
|
Packit Service |
6d40f9 |
in->result = "";
|
|
Packit Service |
6d40f9 |
in->len = strlen (in->result);
|
|
Packit Service |
6d40f9 |
break;
|
|
Packit Service |
6d40f9 |
case SASL_CB_NOECHOPROMPT:
|
|
Packit Service |
6d40f9 |
case SASL_CB_ECHOPROMPT:
|
|
Packit Service |
6d40f9 |
return LDAP_UNAVAILABLE;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
in++;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return LDAP_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_disco *
|
|
Packit Service |
6d40f9 |
desperate_for_disco (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_disco *disco;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!conn->domain_name || !conn->domain_controller)
|
|
Packit Service |
6d40f9 |
return NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
disco = calloc (1, sizeof (adcli_disco));
|
|
Packit Service |
6d40f9 |
return_val_if_fail (disco != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
disco->domain = strdup (conn->domain_name);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (disco->domain != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
disco->host_addr = strdup (conn->domain_controller);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (disco->host_addr, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
disco->host_name = strdup (conn->domain_controller);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (disco->host_name, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (adcli_disco_usable (disco) != ADCLI_DISCO_UNUSABLE);
|
|
Packit Service |
6d40f9 |
return disco;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
connect_to_directory (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res = ADCLI_ERR_UNEXPECTED;
|
|
Packit Service |
6d40f9 |
adcli_disco *disco;
|
|
Packit Service |
6d40f9 |
int had_any = 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->ldap)
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
disco_dance_if_necessary (conn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!conn->domain_disco)
|
|
Packit Service |
6d40f9 |
conn->domain_disco = desperate_for_disco (conn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (disco = conn->domain_disco; disco != NULL; disco = disco->next) {
|
|
Packit Service |
6d40f9 |
if (!adcli_disco_usable (disco))
|
|
Packit Service |
6d40f9 |
continue;
|
|
Packit Service |
6d40f9 |
res = connect_and_lookup_naming (conn, disco);
|
|
Packit Service |
6d40f9 |
if (res == ADCLI_SUCCESS || res == ADCLI_ERR_UNEXPECTED)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
had_any = 1;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!had_any) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't find usable domain controller to connect to");
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
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 |
authenticate_to_directory (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
OM_uint32 status;
|
|
Packit Service |
6d40f9 |
OM_uint32 minor;
|
|
Packit Service |
6d40f9 |
ber_len_t ssf;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->ldap_authenticated)
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (conn->ldap);
|
|
Packit Service |
6d40f9 |
assert (conn->login_ccache_name != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Sets the credential cache GSSAPI to use (for this thread) */
|
|
Packit Service |
6d40f9 |
status = gss_krb5_ccache_name (&minor, conn->login_ccache_name, NULL);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (status == 0);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Clumsily tell ldap + cyrus-sasl that we want encryption */
|
|
Packit Service |
6d40f9 |
ssf = 1;
|
|
Packit Service |
6d40f9 |
ret = ldap_set_option (conn->ldap, LDAP_OPT_X_SASL_SSF_MIN, &ssf;;
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (ret == 0);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ret = ldap_sasl_interactive_bind_s (conn->ldap, NULL, "GSSAPI", NULL, NULL,
|
|
Packit Service |
6d40f9 |
LDAP_SASL_QUIET, sasl_interact, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Clear the credential cache GSSAPI to use (for this thread) */
|
|
Packit Service |
6d40f9 |
status = gss_krb5_ccache_name (&minor, NULL, NULL);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (status == 0);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ret != 0) {
|
|
Packit Service |
6d40f9 |
return _adcli_ldap_handle_failure (conn->ldap, ADCLI_ERR_CREDENTIALS,
|
|
Packit Service |
6d40f9 |
"Couldn't authenticate to active directory");
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn->ldap_authenticated = 1;
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static void
|
|
Packit Service |
6d40f9 |
lookup_short_name (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *attrs[] = { "nETBIOSName", NULL, };
|
|
Packit Service |
6d40f9 |
LDAPMessage *results;
|
|
Packit Service |
6d40f9 |
char *partition_dn;
|
|
Packit Service |
6d40f9 |
char *value;
|
|
Packit Service |
6d40f9 |
char *filter;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (conn->domain_short);
|
|
Packit Service |
6d40f9 |
conn->domain_short = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (asprintf (&partition_dn, "CN=Partitions,%s", conn->configuration_naming_context) < 0)
|
|
Packit Service |
6d40f9 |
return_if_reached ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
value = _adcli_ldap_escape_filter (conn->default_naming_context);
|
|
Packit Service |
6d40f9 |
return_if_fail (value != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (asprintf (&filter, "(&(nCName=%s)(nETBIOSName=*))", value) < 0)
|
|
Packit Service |
6d40f9 |
return_if_reached ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ret = ldap_search_ext_s (conn->ldap, partition_dn, LDAP_SCOPE_ONELEVEL,
|
|
Packit Service |
6d40f9 |
filter, attrs, 0, NULL, NULL, NULL, -1, &results);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (partition_dn);
|
|
Packit Service |
6d40f9 |
free (filter);
|
|
Packit Service |
6d40f9 |
free (value);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ret == LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
conn->domain_short = _adcli_ldap_parse_value (conn->ldap, results, "nETBIOSName");
|
|
Packit Service |
6d40f9 |
ldap_msgfree (results);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->domain_short)
|
|
Packit Service |
6d40f9 |
_adcli_info ("Looked up short domain name: %s", conn->domain_short);
|
|
Packit Service |
6d40f9 |
else
|
|
Packit Service |
6d40f9 |
_adcli_err ("No short domain name found");
|
|
Packit Service |
6d40f9 |
} else {
|
|
Packit Service |
6d40f9 |
_adcli_ldap_handle_failure (conn->ldap, ADCLI_ERR_DIRECTORY,
|
|
Packit Service |
6d40f9 |
"Couldn't lookup domain short name");
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static void
|
|
Packit Service |
47fa62 |
lookup_domain_sid (adcli_conn *conn)
|
|
Packit Service |
47fa62 |
{
|
|
Packit Service |
47fa62 |
char *attrs[] = { "objectSid", NULL, };
|
|
Packit Service |
47fa62 |
LDAPMessage *results;
|
|
Packit Service |
47fa62 |
int ret;
|
|
Packit Service |
47fa62 |
|
|
Packit Service |
47fa62 |
free (conn->domain_sid);
|
|
Packit Service |
47fa62 |
conn->domain_sid = NULL;
|
|
Packit Service |
47fa62 |
|
|
Packit Service |
47fa62 |
ret = ldap_search_ext_s (conn->ldap, conn->default_naming_context, LDAP_SCOPE_BASE,
|
|
Packit Service |
47fa62 |
NULL, attrs, 0, NULL, NULL, NULL, -1, &results);
|
|
Packit Service |
47fa62 |
if (ret == LDAP_SUCCESS) {
|
|
Packit Service |
47fa62 |
conn->domain_sid = _adcli_ldap_parse_sid (conn->ldap, results, "objectSid");
|
|
Packit Service |
47fa62 |
ldap_msgfree (results);
|
|
Packit Service |
47fa62 |
|
|
Packit Service |
47fa62 |
if (conn->domain_sid)
|
|
Packit Service |
47fa62 |
_adcli_info ("Looked up domain SID: %s", conn->domain_sid);
|
|
Packit Service |
47fa62 |
else
|
|
Packit Service |
47fa62 |
_adcli_err ("No domain SID found");
|
|
Packit Service |
47fa62 |
} else {
|
|
Packit Service |
47fa62 |
_adcli_ldap_handle_failure (conn->ldap, ADCLI_ERR_DIRECTORY,
|
|
Packit Service |
47fa62 |
"Couldn't lookup domain SID");
|
|
Packit Service |
47fa62 |
}
|
|
Packit Service |
47fa62 |
}
|
|
Packit Service |
47fa62 |
|
|
Packit Service |
47fa62 |
static void
|
|
Packit Service |
6d40f9 |
conn_clear_state (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
conn->ldap_authenticated = 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->ldap)
|
|
Packit Service |
6d40f9 |
ldap_unbind_ext_s (conn->ldap, NULL, NULL);
|
|
Packit Service |
6d40f9 |
conn->ldap = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (conn->canonical_host);
|
|
Packit Service |
6d40f9 |
conn->canonical_host = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->ccache)
|
|
Packit Service |
6d40f9 |
krb5_cc_close (conn->k5, conn->ccache);
|
|
Packit Service |
6d40f9 |
conn->ccache = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->keytab)
|
|
Packit Service |
6d40f9 |
krb5_kt_close (conn->k5, conn->keytab);
|
|
Packit Service |
6d40f9 |
conn->keytab = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->k5)
|
|
Packit Service |
6d40f9 |
krb5_free_context (conn->k5);
|
|
Packit Service |
6d40f9 |
conn->k5 = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_result
|
|
Packit Service |
6d40f9 |
adcli_conn_discover (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res = ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_clear_last_error ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Basic discovery and figuring out conn params */
|
|
Packit Service |
6d40f9 |
res = ensure_host_fqdn (res, conn);
|
|
Packit Service |
6d40f9 |
res = ensure_domain_and_host (res, conn);
|
|
Packit Service |
6d40f9 |
res = ensure_computer_name (res, conn);
|
|
Packit Service |
6d40f9 |
res = ensure_domain_realm (res, conn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_result
|
|
Packit Service |
6d40f9 |
adcli_conn_connect (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res = ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res = adcli_conn_discover (conn);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* - Connect to LDAP server */
|
|
Packit Service |
6d40f9 |
res = connect_to_directory (conn);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Guarantee consistency and communication with one dc */
|
|
Packit Service |
6d40f9 |
res = setup_krb5_conf_snippet (conn);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (conn->k5 == NULL);
|
|
Packit Service |
6d40f9 |
res = _adcli_krb5_init_context (&conn->k5);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Login with admin credentials now, setup login ccache */
|
|
Packit Service |
6d40f9 |
res = prep_kerberos_and_kinit (conn);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* - And finally authenticate */
|
|
Packit Service |
6d40f9 |
res = authenticate_to_directory (conn);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
lookup_short_name (conn);
|
|
Packit Service |
47fa62 |
lookup_domain_sid (conn);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_conn *
|
|
Packit Service |
6d40f9 |
adcli_conn_new (const char *domain_name)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_conn *conn;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn = calloc (1, sizeof (adcli_conn));
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn->refs = 1;
|
|
Packit Service |
6d40f9 |
conn->logins_allowed = ADCLI_LOGIN_COMPUTER_ACCOUNT | ADCLI_LOGIN_USER_ACCOUNT;
|
|
Packit Service |
6d40f9 |
adcli_conn_set_domain_name (conn, domain_name);
|
|
Packit Service |
6d40f9 |
return conn;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static void
|
|
Packit Service |
6d40f9 |
conn_free (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
free (conn->domain_name);
|
|
Packit Service |
6d40f9 |
free (conn->domain_realm);
|
|
Packit Service |
6d40f9 |
free (conn->domain_controller);
|
|
Packit Service |
6d40f9 |
free (conn->domain_short);
|
|
Packit Service |
6d40f9 |
free (conn->default_naming_context);
|
|
Packit Service |
6d40f9 |
free (conn->configuration_naming_context);
|
|
Packit Service |
6d40f9 |
_adcli_strv_free (conn->supported_capabilities);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (conn->computer_name);
|
|
Packit Service |
6d40f9 |
free (conn->host_fqdn);
|
|
Packit Service |
6d40f9 |
free (conn->krb5_conf_dir);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->krb5_conf_snippet) {
|
|
Packit Service |
6d40f9 |
unlink (conn->krb5_conf_snippet);
|
|
Packit Service |
6d40f9 |
free (conn->krb5_conf_snippet);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_conn_set_login_user (conn, NULL);
|
|
Packit Service |
6d40f9 |
adcli_conn_set_user_password (conn, NULL);
|
|
Packit Service |
6d40f9 |
adcli_conn_set_password_func (conn, NULL, NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn_clear_state (conn);
|
|
Packit Service |
6d40f9 |
no_more_disco (conn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (conn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_conn *
|
|
Packit Service |
6d40f9 |
adcli_conn_ref (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn->refs++;
|
|
Packit Service |
6d40f9 |
return conn;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_unref (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
if (conn == NULL)
|
|
Packit Service |
6d40f9 |
return;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (--(conn->refs) > 0)
|
|
Packit Service |
6d40f9 |
return;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn_free (conn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_host_fqdn (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->host_fqdn;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_set_host_fqdn (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&conn->host_fqdn, value);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_computer_name (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->computer_name;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_set_computer_name (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&conn->computer_name, value);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_computer_password (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->computer_password;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_set_computer_password (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *password)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *newval = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_if_fail (conn != 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 (conn->computer_password)
|
|
Packit Service |
6d40f9 |
_adcli_password_free (conn->computer_password);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn->computer_password = newval;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_domain_name (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->domain_name;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_set_domain_name (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&conn->domain_name, value);
|
|
Packit Service |
6d40f9 |
no_more_disco (conn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_domain_realm (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->domain_realm;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_set_domain_realm (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&conn->domain_realm, value);
|
|
Packit Service |
6d40f9 |
no_more_disco (conn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_domain_controller (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->domain_controller;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_set_domain_controller (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&conn->domain_controller, value);
|
|
Packit Service |
6d40f9 |
no_more_disco (conn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_domain_short (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->domain_short;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
9338d0 |
const char *
|
|
Packit Service |
9338d0 |
adcli_conn_get_domain_sid (adcli_conn *conn)
|
|
Packit Service |
9338d0 |
{
|
|
Packit Service |
9338d0 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
9338d0 |
return conn->domain_sid;
|
|
Packit Service |
9338d0 |
}
|
|
Packit Service |
9338d0 |
|
|
Packit Service |
9338d0 |
|
|
Packit Service |
6d40f9 |
LDAP *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_ldap_connection (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->ldap;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_context
|
|
Packit Service |
6d40f9 |
adcli_conn_get_krb5_context (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn->k5 != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->k5;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_login_user (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->user_name;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_set_login_user (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&conn->user_name, value);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_user_password (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->user_password;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_set_user_password (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&conn->user_password, value);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_set_password_func (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
adcli_password_func password_func,
|
|
Packit Service |
6d40f9 |
void *data,
|
|
Packit Service |
6d40f9 |
adcli_destroy_func destroy_data)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->password_destroy)
|
|
Packit Service |
6d40f9 |
(conn->password_destroy) (conn->password_data);
|
|
Packit Service |
6d40f9 |
conn->password_func = password_func;
|
|
Packit Service |
6d40f9 |
conn->password_data = data;
|
|
Packit Service |
6d40f9 |
conn->password_destroy = destroy_data;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_login_type
|
|
Packit Service |
6d40f9 |
adcli_conn_get_login_type (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, ADCLI_LOGIN_UNKNOWN);
|
|
Packit Service |
6d40f9 |
return conn->login_type;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_login_type
|
|
Packit Service |
6d40f9 |
adcli_conn_get_allowed_login_types (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, ADCLI_LOGIN_UNKNOWN);
|
|
Packit Service |
6d40f9 |
return conn->logins_allowed;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_set_allowed_login_types (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
adcli_login_type types)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
conn->logins_allowed = types;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
krb5_ccache
|
|
Packit Service |
6d40f9 |
adcli_conn_get_login_ccache (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->ccache;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_login_ccache_name (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->login_ccache_name;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_set_login_ccache_name (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *ccname)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *newval = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ccname) {
|
|
Packit Service |
6d40f9 |
newval = strdup (ccname);
|
|
Packit Service |
6d40f9 |
return_if_fail (newval != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->login_ccache_name) {
|
|
Packit Service |
6d40f9 |
if (conn->login_ccache_name_is_krb5)
|
|
Packit Service |
6d40f9 |
krb5_free_string (conn->k5, conn->login_ccache_name);
|
|
Packit Service |
6d40f9 |
else
|
|
Packit Service |
6d40f9 |
free (conn->login_ccache_name);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->ccache) {
|
|
Packit Service |
6d40f9 |
krb5_cc_close (conn->k5, conn->ccache);
|
|
Packit Service |
6d40f9 |
conn->ccache = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn->login_ccache_name = newval;
|
|
Packit Service |
6d40f9 |
conn->login_ccache_name_is_krb5 = 0;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_login_keytab_name (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->login_keytab_name;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_set_login_keytab_name (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *ktname)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *newval = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (ktname) {
|
|
Packit Service |
6d40f9 |
newval = strdup (ktname);
|
|
Packit Service |
6d40f9 |
return_if_fail (newval != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->login_keytab_name) {
|
|
Packit Service |
6d40f9 |
if (conn->login_keytab_name_is_krb5)
|
|
Packit Service |
6d40f9 |
krb5_free_string (conn->k5, conn->login_keytab_name);
|
|
Packit Service |
6d40f9 |
else
|
|
Packit Service |
6d40f9 |
free (conn->login_keytab_name);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (conn->keytab) {
|
|
Packit Service |
6d40f9 |
krb5_kt_close (conn->k5, conn->keytab);
|
|
Packit Service |
6d40f9 |
conn->keytab = NULL;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
conn->login_keytab_name = newval;
|
|
Packit Service |
6d40f9 |
conn->login_keytab_name_is_krb5 = 0;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_default_naming_context (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return conn->default_naming_context;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_conn_get_krb5_conf_dir (adcli_conn *conn)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return conn->krb5_conf_dir;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_conn_set_krb5_conf_dir (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *value)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (conn != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&conn->krb5_conf_dir, value);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
int
|
|
Packit Service |
6d40f9 |
adcli_conn_server_has_capability (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *capability)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
int i;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, 0);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (capability != NULL, 0);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!conn->supported_capabilities)
|
|
Packit Service |
6d40f9 |
return 0;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
for (i = 0; conn->supported_capabilities[i] != NULL; i++) {
|
|
Packit Service |
6d40f9 |
if (strcmp (capability, conn->supported_capabilities[i]) == 0)
|
|
Packit Service |
6d40f9 |
return 1;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return 0;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
74437d |
|
|
Packit Service |
74437d |
bool adcli_conn_is_writeable (adcli_conn *conn)
|
|
Packit Service |
74437d |
{
|
|
Packit Service |
74437d |
disco_dance_if_necessary (conn);
|
|
Packit Service |
74437d |
return ( (conn->domain_disco->flags & ADCLI_DISCO_WRITABLE) != 0);
|
|
Packit Service |
74437d |
}
|