|
Packit Service |
6d40f9 |
/*
|
|
Packit Service |
6d40f9 |
* adcli
|
|
Packit Service |
6d40f9 |
*
|
|
Packit Service |
6d40f9 |
* Copyright (C) 2013 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@redhat.com>
|
|
Packit Service |
6d40f9 |
*/
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#include "config.h"
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#include "adentry.h"
|
|
Packit Service |
6d40f9 |
#include "adprivate.h"
|
|
Packit Service |
6d40f9 |
#include "seq.h"
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
#include <assert.h>
|
|
Packit Service |
6d40f9 |
#include <stdio.h>
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
typedef adcli_result (* entry_builder) (adcli_entry *, adcli_attrs *);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
struct _adcli_entry {
|
|
Packit Service |
6d40f9 |
int refs;
|
|
Packit Service |
6d40f9 |
adcli_conn *conn;
|
|
Packit Service |
6d40f9 |
const char *object_class;
|
|
Packit Service |
6d40f9 |
entry_builder builder;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
char *sam_name;
|
|
Packit Service |
6d40f9 |
char *entry_dn;
|
|
Packit Service |
6d40f9 |
char *domain_ou;
|
|
Packit Service |
6d40f9 |
char *entry_container;
|
|
Packit Service |
6d40f9 |
};
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_entry *
|
|
Packit Service |
6d40f9 |
entry_new (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *object_class,
|
|
Packit Service |
6d40f9 |
entry_builder builder,
|
|
Packit Service |
6d40f9 |
const char *sam_name)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_entry *entry;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
entry = calloc (1, sizeof (adcli_entry));
|
|
Packit Service |
6d40f9 |
return_val_if_fail (entry != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
entry->conn = adcli_conn_ref (conn);
|
|
Packit Service |
6d40f9 |
entry->refs = 1;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
entry->sam_name = strdup (sam_name);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (entry->sam_name != NULL, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
entry->builder = builder;
|
|
Packit Service |
6d40f9 |
entry->object_class = object_class;
|
|
Packit Service |
6d40f9 |
return entry;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_entry *
|
|
Packit Service |
6d40f9 |
adcli_entry_ref (adcli_entry *entry)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (entry != NULL, NULL);
|
|
Packit Service |
6d40f9 |
entry->refs++;
|
|
Packit Service |
6d40f9 |
return entry;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static void
|
|
Packit Service |
6d40f9 |
entry_free (adcli_entry *entry)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
free (entry->sam_name);
|
|
Packit Service |
6d40f9 |
free (entry->entry_container);
|
|
Packit Service |
6d40f9 |
free (entry->entry_dn);
|
|
Packit Service |
6d40f9 |
free (entry->domain_ou);
|
|
Packit Service |
6d40f9 |
adcli_conn_unref (entry->conn);
|
|
Packit Service |
6d40f9 |
free (entry);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_entry_unref (adcli_entry *entry)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
if (entry == NULL)
|
|
Packit Service |
6d40f9 |
return;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (--(entry->refs) > 0)
|
|
Packit Service |
6d40f9 |
return;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
entry_free (entry);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
update_entry_from_domain (adcli_entry *entry,
|
|
Packit Service |
6d40f9 |
LDAP *ldap)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
const char *attrs[] = { "1.1", NULL };
|
|
Packit Service |
6d40f9 |
LDAPMessage *results;
|
|
Packit Service |
6d40f9 |
LDAPMessage *first;
|
|
Packit Service |
6d40f9 |
const char *base;
|
|
Packit Service |
6d40f9 |
char *filter;
|
|
Packit Service |
6d40f9 |
char *value;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
value = _adcli_ldap_escape_filter (entry->sam_name);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (value != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (asprintf (&filter, "(&(objectClass=%s)(sAMAccountName=%s))", entry->object_class, value) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
base = adcli_conn_get_default_naming_context (entry->conn);
|
|
Packit Service |
6d40f9 |
ret = ldap_search_ext_s (ldap, base, LDAP_SCOPE_SUB, filter, (char **)attrs,
|
|
Packit Service |
6d40f9 |
0, NULL, NULL, NULL, -1, &results);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (filter);
|
|
Packit Service |
6d40f9 |
free (value);
|
|
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 search for %s entry: %s",
|
|
Packit Service |
6d40f9 |
entry->object_class, entry->sam_name);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap_memfree (entry->entry_dn);
|
|
Packit Service |
6d40f9 |
entry->entry_dn = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Entry, use its dn */
|
|
Packit Service |
6d40f9 |
first = ldap_first_entry (ldap, results);
|
|
Packit Service |
6d40f9 |
if (first != NULL) {
|
|
Packit Service |
6d40f9 |
entry->entry_dn = ldap_get_dn (ldap, first);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (entry->entry_dn != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap_msgfree (results);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_result
|
|
Packit Service |
6d40f9 |
adcli_entry_load (adcli_entry *entry)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = adcli_conn_get_ldap_connection (entry->conn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (ldap != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return update_entry_from_domain (entry, ldap);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
lookup_entry_container (adcli_entry *entry,
|
|
Packit Service |
6d40f9 |
LDAP *ldap)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *attrs[] = { "wellKnownObjects", NULL };
|
|
Packit Service |
6d40f9 |
char *prefix = "B:32:A9D1CA15768811D1ADED00C04FD8D5CD:";
|
|
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 (entry->entry_container)
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
base = entry->domain_ou;
|
|
Packit Service |
6d40f9 |
if (base == NULL)
|
|
Packit Service |
6d40f9 |
base = adcli_conn_get_default_naming_context (entry->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 && entry->domain_ou) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("The organizational unit does not exist: %s", entry->domain_ou);
|
|
Packit Service |
6d40f9 |
return 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 %s container",
|
|
Packit Service |
6d40f9 |
entry->object_class);
|
|
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 |
entry->entry_container = strdup (values[i] + prefix_len);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (entry->entry_container != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_info ("Found well known %s container at: %s",
|
|
Packit Service |
6d40f9 |
entry->object_class, entry->entry_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 (!entry->entry_container) {
|
|
Packit Service |
6d40f9 |
ret = ldap_search_ext_s (ldap, base, LDAP_SCOPE_BASE,
|
|
Packit Service |
6d40f9 |
"(&(objectClass=container)(cn=Users))",
|
|
Packit Service |
6d40f9 |
attrs, 0, NULL, NULL, NULL, -1, &results);
|
|
Packit Service |
6d40f9 |
if (ret == LDAP_SUCCESS) {
|
|
Packit Service |
6d40f9 |
entry->entry_container = _adcli_ldap_parse_dn (ldap, results);
|
|
Packit Service |
6d40f9 |
if (entry->entry_container) {
|
|
Packit Service |
6d40f9 |
_adcli_info ("Well known %s container not "
|
|
Packit Service |
6d40f9 |
"found, but found suitable one at: %s",
|
|
Packit Service |
6d40f9 |
entry->object_class, entry->entry_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 (!entry->entry_container && entry->domain_ou) {
|
|
Packit Service |
6d40f9 |
_adcli_warn ("Couldn't find a %s container in the ou, "
|
|
Packit Service |
6d40f9 |
"creating %s entry directly in: %s", entry->object_class,
|
|
Packit Service |
6d40f9 |
entry->object_class, entry->domain_ou);
|
|
Packit Service |
6d40f9 |
entry->entry_container = strdup (entry->domain_ou);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (entry->entry_container != NULL);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!entry->entry_container) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Couldn't find location to create %s entry", entry->object_class);
|
|
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_entry_dn (adcli_entry *entry,
|
|
Packit Service |
6d40f9 |
LDAP *ldap)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Now need to find or validate the container */
|
|
Packit Service |
6d40f9 |
res = lookup_entry_container (entry, ldap);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (entry->entry_container);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
free (entry->entry_dn);
|
|
Packit Service |
6d40f9 |
entry->entry_dn = NULL;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (asprintf (&entry->entry_dn, "CN=%s,%s", entry->sam_name, entry->entry_container) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_info ("Calculated %s entry: %s", entry->object_class, entry->entry_dn);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_result
|
|
Packit Service |
6d40f9 |
adcli_entry_create (adcli_entry *entry,
|
|
Packit Service |
6d40f9 |
adcli_attrs *attrs)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
char *string;
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = adcli_conn_get_ldap_connection (entry->conn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (ldap != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Find the entry */
|
|
Packit Service |
6d40f9 |
res = update_entry_from_domain (entry, ldap);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (entry->entry_dn) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("The %s entry %s already exists in the domain",
|
|
Packit Service |
6d40f9 |
entry->object_class, entry->sam_name);
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
res = calculate_entry_dn (entry, ldap);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (entry->entry_dn);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_attrs_replace (attrs, "objectClass", entry->object_class, NULL);
|
|
Packit Service |
6d40f9 |
adcli_attrs_replace (attrs, "cn", entry->sam_name, NULL);
|
|
Packit Service |
6d40f9 |
adcli_attrs_replace (attrs, "sAMAccountName", entry->sam_name, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
assert (entry->builder != NULL);
|
|
Packit Service |
6d40f9 |
res = (entry->builder) (entry, attrs);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
string = _adcli_ldap_mods_to_string (attrs->mods);
|
|
Packit Service |
6d40f9 |
_adcli_info ("Creating %s with attributes: %s", entry->object_class, string);
|
|
Packit Service |
6d40f9 |
free (string);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Fill in the work attributes */
|
|
Packit Service |
6d40f9 |
seq_filter (attrs->mods, &attrs->len, NULL,
|
|
Packit Service |
6d40f9 |
_adcli_ldap_filter_for_add, _adcli_ldap_mod_free);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ret = ldap_add_ext_s (ldap, entry->entry_dn, attrs->mods, NULL, NULL);
|
|
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 create %s entry: %s",
|
|
Packit Service |
6d40f9 |
entry->object_class, entry->entry_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 %s entry: %s",
|
|
Packit Service |
6d40f9 |
entry->object_class, entry->entry_dn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_info ("Created %s entry: %s", entry->object_class, entry->entry_dn);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_result
|
|
Packit Service |
6d40f9 |
adcli_entry_modify (adcli_entry *entry,
|
|
Packit Service |
6d40f9 |
adcli_attrs *attrs)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
char *string;
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = adcli_conn_get_ldap_connection (entry->conn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (ldap != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Find the entry */
|
|
Packit Service |
6d40f9 |
res = update_entry_from_domain (entry, ldap);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!entry->entry_dn) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Cannot find the %s entry %s in the domain",
|
|
Packit Service |
6d40f9 |
entry->object_class, entry->sam_name);
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
string = _adcli_ldap_mods_to_string (attrs->mods);
|
|
Packit Service |
6d40f9 |
_adcli_info ("Modifying %s entry attributes: %s", entry->object_class, string);
|
|
Packit Service |
6d40f9 |
free (string);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ret = ldap_modify_ext_s (ldap, entry->entry_dn, attrs->mods, NULL, NULL);
|
|
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 modify %s entry: %s",
|
|
Packit Service |
6d40f9 |
entry->object_class, entry->entry_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 modify %s entry: %s",
|
|
Packit Service |
6d40f9 |
entry->object_class, entry->entry_dn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_info ("Modified %s entry: %s", entry->object_class, entry->entry_dn);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_result
|
|
Packit Service |
6d40f9 |
adcli_entry_delete (adcli_entry *entry)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
adcli_result res;
|
|
Packit Service |
6d40f9 |
LDAP *ldap;
|
|
Packit Service |
6d40f9 |
int ret;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ldap = adcli_conn_get_ldap_connection (entry->conn);
|
|
Packit Service |
6d40f9 |
return_unexpected_if_fail (ldap != NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
/* Find the user */
|
|
Packit Service |
6d40f9 |
res = update_entry_from_domain (entry, ldap);
|
|
Packit Service |
6d40f9 |
if (res != ADCLI_SUCCESS)
|
|
Packit Service |
6d40f9 |
return res;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
if (!entry->entry_dn) {
|
|
Packit Service |
6d40f9 |
_adcli_err ("Cannot find the %s entry %s in the domain",
|
|
Packit Service |
6d40f9 |
entry->object_class, entry->sam_name);
|
|
Packit Service |
6d40f9 |
return ADCLI_ERR_CONFIG;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
ret = ldap_delete_ext_s (ldap, entry->entry_dn, NULL, NULL);
|
|
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 delete %s entry: %s",
|
|
Packit Service |
6d40f9 |
entry->object_class, entry->entry_dn);
|
|
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 %s entry: %s",
|
|
Packit Service |
6d40f9 |
entry->object_class, entry->entry_dn);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
_adcli_info ("Deleted %s: %s", entry->object_class, entry->entry_dn);
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_entry_get_sam_name (adcli_entry *entry)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (entry != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return entry->sam_name;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_entry_get_dn (adcli_entry *entry)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (entry != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return entry->entry_dn;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
const char *
|
|
Packit Service |
6d40f9 |
adcli_entry_get_domain_ou (adcli_entry *entry)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (entry != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return entry->domain_ou;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
void
|
|
Packit Service |
6d40f9 |
adcli_entry_set_domain_ou (adcli_entry *entry,
|
|
Packit Service |
6d40f9 |
const char *ou)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_if_fail (entry != NULL);
|
|
Packit Service |
6d40f9 |
_adcli_str_set (&entry->domain_ou, ou);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
user_entry_builder (adcli_entry *entry,
|
|
Packit Service |
6d40f9 |
adcli_attrs *attrs)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
char *string;
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_attrs_replace (attrs, "userAccountControl", "514", NULL) /* NORMAL_ACCOUNT | ACCOUNTDISABLE */;
|
|
Packit Service |
6d40f9 |
if (!adcli_attrs_have (attrs, "displayName"))
|
|
Packit Service |
6d40f9 |
adcli_attrs_replace (attrs, "displayName", entry->sam_name, NULL);
|
|
Packit Service |
6d40f9 |
if (!adcli_attrs_have (attrs, "name"))
|
|
Packit Service |
6d40f9 |
adcli_attrs_replace (attrs, "name", entry->sam_name, NULL);
|
|
Packit Service |
6d40f9 |
if (!adcli_attrs_have (attrs, "userPrincipalName")) {
|
|
Packit Service |
6d40f9 |
if (asprintf (&string, "%s@%s", entry->sam_name, adcli_conn_get_domain_name (entry->conn)) < 0)
|
|
Packit Service |
6d40f9 |
return_unexpected_if_reached ();
|
|
Packit Service |
6d40f9 |
adcli_attrs_replace (attrs, "userPrincipalName", string, NULL);
|
|
Packit Service |
6d40f9 |
free (string);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_entry *
|
|
Packit Service |
6d40f9 |
adcli_entry_new_user (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *sam_name)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (sam_name != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return entry_new (conn, "user", user_entry_builder, sam_name);
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
static adcli_result
|
|
Packit Service |
6d40f9 |
group_entry_builder (adcli_entry *entry,
|
|
Packit Service |
6d40f9 |
adcli_attrs *attrs)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
if (!adcli_attrs_have (attrs, "description"))
|
|
Packit Service |
6d40f9 |
adcli_attrs_replace (attrs, "description", entry->sam_name, NULL);
|
|
Packit Service |
6d40f9 |
if (!adcli_attrs_have (attrs, "name"))
|
|
Packit Service |
6d40f9 |
adcli_attrs_replace (attrs, "name", entry->sam_name, NULL);
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
return ADCLI_SUCCESS;
|
|
Packit Service |
6d40f9 |
}
|
|
Packit Service |
6d40f9 |
|
|
Packit Service |
6d40f9 |
adcli_entry *
|
|
Packit Service |
6d40f9 |
adcli_entry_new_group (adcli_conn *conn,
|
|
Packit Service |
6d40f9 |
const char *sam_name)
|
|
Packit Service |
6d40f9 |
{
|
|
Packit Service |
6d40f9 |
return_val_if_fail (conn != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return_val_if_fail (sam_name != NULL, NULL);
|
|
Packit Service |
6d40f9 |
return entry_new (conn, "group", group_entry_builder, sam_name);
|
|
Packit Service |
6d40f9 |
}
|