#include "includes.h"
struct pdb_ads_state {
+ struct sockaddr_un socket_address;
struct tldap_context *ld;
struct dom_sid domainsid;
char *domaindn;
const DOM_SID *sid);
static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
DOM_SID *sid);
-static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
+static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
struct dom_sid *psid);
static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
const struct dom_sid *sid,
TALLOC_CTX *mem_ctx, char **pdn);
+static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
+static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
+ int scope, const char *attrs[], int num_attrs,
+ int attrsonly,
+ TALLOC_CTX *mem_ctx, struct tldap_message ***res,
+ const char *fmt, ...);
static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
time_t *ptime)
goto fail;
}
pdb_set_username(sam, str, PDB_SET);
- TALLOC_FREE(str);
if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
pdb_set_logon_time(sam, tmp_time, PDB_SET);
pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
}
- str = tldap_talloc_single_attribute(entry, "samAccoutName",
- talloc_tos());
- if (str != NULL) {
- pdb_set_username(sam, str, PDB_SET);
- }
-
str = tldap_talloc_single_attribute(entry, "displayName",
talloc_tos());
if (str != NULL) {
struct samu *sam)
{
bool ret = true;
+ DATA_BLOB blob;
/* TODO: All fields :-) */
existing, mem_ctx, pnum_mods, pmods, "displayName",
"%s", pdb_get_fullname(sam));
- ret &= tldap_make_mod_blob(
- existing, mem_ctx, pnum_mods, pmods, "unicodePwd",
- data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN));
+ blob = data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN);
+ if (blob.data != NULL) {
+ ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
+ "unicodePwd", 1, &blob);
+ }
- ret &= tldap_make_mod_blob(
- existing, mem_ctx, pnum_mods, pmods, "dBCSPwd",
- data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN));
+ blob = data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN);
+ if (blob.data != NULL) {
+ ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
+ "dBCSPwd", 1, &blob);
+ }
+
+ ret &= tldap_make_mod_fmt(
+ existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
+ "%d", ads_acb2uf(pdb_get_acct_ctrl(sam)));
+
+ ret &= tldap_make_mod_fmt(
+ existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
+ "%s", pdb_get_homedir(sam));
+
+ ret &= tldap_make_mod_fmt(
+ existing, mem_ctx, pnum_mods, pmods, "homeDrive",
+ "%s", pdb_get_dir_drive(sam));
+
+ ret &= tldap_make_mod_fmt(
+ existing, mem_ctx, pnum_mods, pmods, "scriptPath",
+ "%s", pdb_get_logon_script(sam));
+
+ ret &= tldap_make_mod_fmt(
+ existing, mem_ctx, pnum_mods, pmods, "profilePath",
+ "%s", pdb_get_profile_path(sam));
return ret;
}
struct tldap_message **users;
int rc, count;
- rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
- attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
- &users, "%s", filter);
+ rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
+ attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
+ &users, "%s", filter);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_search failed %s\n",
tldap_errstr(debug_ctx(), state->ld, rc)));
{
struct pdb_ads_state *state = talloc_get_type_abort(
m->private_data, struct pdb_ads_state);
+ struct tldap_context *ld;
const char *attrs[1] = { "objectSid" };
struct tldap_mod *mods = NULL;
int num_mods = 0;
return NT_STATUS_NO_MEMORY;
}
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
+ }
+
/* TODO: Create machines etc */
ok = true;
return NT_STATUS_NO_MEMORY;
}
- rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
+
+ rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_add failed %s\n",
- tldap_errstr(debug_ctx(), state->ld, rc)));
+ tldap_errstr(debug_ctx(), ld, rc)));
TALLOC_FREE(dn);
return NT_STATUS_LDAP(rc);
}
- rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
- attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
- "(&(objectclass=user)(samaccountname=%s))",
- name);
+ rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
+ attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
+ &user,
+ "(&(objectclass=user)(samaccountname=%s))",
+ name);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("Could not find just created user %s: %s\n",
name, tldap_errstr(debug_ctx(), state->ld, rc)));
{
struct pdb_ads_state *state = talloc_get_type_abort(
m->private_data, struct pdb_ads_state);
- struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
+ NTSTATUS status;
+ struct tldap_context *ld;
+ char *dn;
int rc;
- rc = tldap_delete(state->ld, priv->dn, NULL, NULL);
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
+ }
+
+ status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
+ &dn);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
+ TALLOC_FREE(dn);
if (rc != TLDAP_SUCCESS) {
- DEBUG(10, ("ldap_delete for %s failed: %s\n", priv->dn,
- tldap_errstr(debug_ctx(), state->ld, rc)));
+ DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
+ tldap_errstr(debug_ctx(), ld, rc)));
return NT_STATUS_LDAP(rc);
}
return NT_STATUS_OK;
struct pdb_ads_state *state = talloc_get_type_abort(
m->private_data, struct pdb_ads_state);
struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
+ struct tldap_context *ld;
struct tldap_mod *mods = NULL;
int rc, num_mods = 0;
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
+ }
+
if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
&num_mods, &mods, sam)) {
return NT_STATUS_NO_MEMORY;
}
- rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
+ if (num_mods == 0) {
+ /* Nothing to do, just return success */
+ return NT_STATUS_OK;
+ }
+
+ rc = tldap_modify(ld, priv->dn, num_mods, mods, NULL, 0,
+ NULL, 0);
+ TALLOC_FREE(mods);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
- tldap_errstr(debug_ctx(), state->ld, rc)));
+ tldap_errstr(debug_ctx(), ld, rc)));
return NT_STATUS_LDAP(rc);
}
- TALLOC_FREE(mods);
-
return NT_STATUS_OK;
}
uint32_t grouptype;
int rc;
- rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
- attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
- &group, "%s", filter);
+ rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
+ attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
+ &group, "%s", filter);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_search failed %s\n",
tldap_errstr(debug_ctx(), state->ld, rc)));
TALLOC_CTX *frame = talloc_stackframe();
struct pdb_ads_state *state = talloc_get_type_abort(
m->private_data, struct pdb_ads_state);
+ struct tldap_context *ld;
const char *attrs[1] = { "objectSid" };
int num_mods = 0;
struct tldap_mod *mods = NULL;
int rc;
bool ok = true;
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
+ }
+
dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
state->domaindn);
if (dn == NULL) {
return NT_STATUS_NO_MEMORY;
}
- rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
+ rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_add failed %s\n",
tldap_errstr(debug_ctx(), state->ld, rc)));
return NT_STATUS_LDAP(rc);
}
- rc = tldap_search_fmt(
- state->ld, state->domaindn, TLDAP_SCOPE_SUB,
+ rc = pdb_ads_search_fmt(
+ state, state->domaindn, TLDAP_SCOPE_SUB,
attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
"(&(objectclass=group)(samaccountname=%s))", name);
if (rc != TLDAP_SUCCESS) {
{
struct pdb_ads_state *state = talloc_get_type_abort(
m->private_data, struct pdb_ads_state);
+ struct tldap_context *ld;
struct dom_sid sid;
char *sidstr;
struct tldap_message **msg;
sidstr = sid_binstring(talloc_tos(), &sid);
NT_STATUS_HAVE_NO_MEMORY(sidstr);
- rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
- NULL, 0, 0, talloc_tos(), &msg,
- ("(&(objectSid=%s)(objectClass=group))"),
- sidstr);
+ rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
+ NULL, 0, 0, talloc_tos(), &msg,
+ ("(&(objectSid=%s)(objectClass=group))"),
+ sidstr);
TALLOC_FREE(sidstr);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_search failed %s\n",
}
if (!tldap_entry_dn(msg[0], &dn)) {
+ TALLOC_FREE(msg);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- rc = tldap_delete(state->ld, dn, NULL, NULL);
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ TALLOC_FREE(msg);
+ return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
+ }
+
+ rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
+ TALLOC_FREE(msg);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_delete failed: %s\n",
tldap_errstr(debug_ctx(), state->ld, rc)));
- TALLOC_FREE(dn);
return NT_STATUS_LDAP(rc);
}
- TALLOC_FREE(msg);
return NT_STATUS_OK;
}
sidstr = sid_binstring(talloc_tos(), group);
NT_STATUS_HAVE_NO_MEMORY(sidstr);
- rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
- attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
- "(objectsid=%s)", sidstr);
+ rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
+ attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
+ &msg, "(objectsid=%s)", sidstr);
TALLOC_FREE(sidstr);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_search failed %s\n",
for (i=0; i<num_members; i++) {
struct dom_sid sid;
- if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
+ if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
|| !sid_peek_rid(&sid, &members[i])) {
TALLOC_FREE(members);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
struct dom_sid *group_sids;
gid_t *gids;
- rc = tldap_search_fmt(
- state->ld, state->domaindn, TLDAP_SCOPE_SUB,
+ rc = pdb_ads_search_fmt(
+ state, state->domaindn, TLDAP_SCOPE_SUB,
attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
"(&(member=%s)(grouptype=%d)(objectclass=group))",
priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
struct pdb_ads_state *state = talloc_get_type_abort(
m->private_data, struct pdb_ads_state);
TALLOC_CTX *frame = talloc_stackframe();
+ struct tldap_context *ld;
struct dom_sid groupsid, membersid;
char *groupdn, *memberdn;
struct tldap_mod *mods;
int rc;
NTSTATUS status;
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
+ }
+
sid_compose(&groupsid, &state->domainsid, grouprid);
sid_compose(&membersid, &state->domainsid, memberrid);
status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(frame);
TALLOC_FREE(frame);
return NT_STATUS_NO_SUCH_GROUP;
}
return NT_STATUS_NO_MEMORY;
}
- rc = tldap_modify(state->ld, groupdn, 1, mods, NULL, NULL);
+ rc = tldap_modify(ld, groupdn, 1, mods, NULL, 0, NULL, 0);
TALLOC_FREE(frame);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_modify failed: %s\n",
TALLOC_CTX *frame = talloc_stackframe();
struct pdb_ads_state *state = talloc_get_type_abort(
m->private_data, struct pdb_ads_state);
+ struct tldap_context *ld;
const char *attrs[1] = { "objectSid" };
int num_mods = 0;
struct tldap_mod *mods = NULL;
int rc;
bool ok = true;
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
+ }
+
dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
state->domaindn);
if (dn == NULL) {
return NT_STATUS_NO_MEMORY;
}
- rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
+ rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_add failed %s\n",
tldap_errstr(debug_ctx(), state->ld, rc)));
return NT_STATUS_LDAP(rc);
}
- rc = tldap_search_fmt(
- state->ld, state->domaindn, TLDAP_SCOPE_SUB,
+ rc = pdb_ads_search_fmt(
+ state, state->domaindn, TLDAP_SCOPE_SUB,
attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
"(&(objectclass=group)(samaccountname=%s))", name);
if (rc != TLDAP_SUCCESS) {
{
struct pdb_ads_state *state = talloc_get_type_abort(
m->private_data, struct pdb_ads_state);
+ struct tldap_context *ld;
struct tldap_message **alias;
char *sidstr, *dn;
int rc;
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
+ }
+
sidstr = sid_binstring(talloc_tos(), sid);
if (sidstr == NULL) {
return NT_STATUS_NO_MEMORY;
}
- rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
- NULL, 0, 0, talloc_tos(), &alias,
- "(&(objectSid=%s)(objectclass=group)"
- "(|(grouptype=%d)(grouptype=%d)))",
- sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
- GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
+ rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
+ NULL, 0, 0, talloc_tos(), &alias,
+ "(&(objectSid=%s)(objectclass=group)"
+ "(|(grouptype=%d)(grouptype=%d)))",
+ sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
+ GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
TALLOC_FREE(sidstr);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_search failed: %s\n",
return NT_STATUS_INTERNAL_ERROR;
}
- rc = tldap_delete(state->ld, dn, NULL, NULL);
+ rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_delete failed: %s\n",
tldap_errstr(debug_ctx(), state->ld, rc)));
return NT_STATUS_OK;
}
-static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
- const DOM_SID *sid,
- struct acct_info *info)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
const DOM_SID *sid,
struct acct_info *info)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ struct pdb_ads_state *state = talloc_get_type_abort(
+ m->private_data, struct pdb_ads_state);
+ struct tldap_context *ld;
+ const char *attrs[3] = { "objectSid", "description",
+ "samAccountName" };
+ struct tldap_message **msg;
+ char *sidstr, *dn;
+ int rc;
+ struct tldap_mod *mods;
+ int num_mods;
+ bool ok;
+
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
+ }
+
+ sidstr = sid_binstring(talloc_tos(), sid);
+ NT_STATUS_HAVE_NO_MEMORY(sidstr);
+
+ rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
+ attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
+ &msg, "(&(objectSid=%s)(objectclass=group)"
+ "(|(grouptype=%d)(grouptype=%d)))",
+ sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
+ GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
+ TALLOC_FREE(sidstr);
+ if (rc != TLDAP_SUCCESS) {
+ DEBUG(10, ("ldap_search failed %s\n",
+ tldap_errstr(debug_ctx(), state->ld, rc)));
+ return NT_STATUS_LDAP(rc);
+ }
+ switch talloc_array_length(msg) {
+ case 0:
+ return NT_STATUS_NO_SUCH_ALIAS;
+ case 1:
+ break;
+ default:
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ if (!tldap_entry_dn(msg[0], &dn)) {
+ TALLOC_FREE(msg);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ mods = NULL;
+ num_mods = 0;
+ ok = true;
+
+ ok &= tldap_make_mod_fmt(
+ msg[0], msg, &num_mods, &mods, "description",
+ "%s", info->acct_desc);
+ ok &= tldap_make_mod_fmt(
+ msg[0], msg, &num_mods, &mods, "samAccountName",
+ "%s", info->acct_name);
+ if (!ok) {
+ TALLOC_FREE(msg);
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (num_mods == 0) {
+ /* no change */
+ TALLOC_FREE(msg);
+ return NT_STATUS_OK;
+ }
+
+ rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
+ TALLOC_FREE(msg);
+ if (rc != TLDAP_SUCCESS) {
+ DEBUG(10, ("ldap_modify failed: %s\n",
+ tldap_errstr(debug_ctx(), state->ld, rc)));
+ return NT_STATUS_LDAP(rc);
+ }
+ return NT_STATUS_OK;
}
static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
sidstr = sid_binstring(talloc_tos(), sid);
NT_STATUS_HAVE_NO_MEMORY(sidstr);
- rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
- NULL, 0, 0, talloc_tos(), &msg,
- "(objectsid=%s)", sidstr);
+ rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
+ NULL, 0, 0, talloc_tos(), &msg,
+ "(objectsid=%s)", sidstr);
TALLOC_FREE(sidstr);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_search failed %s\n",
{
struct pdb_ads_state *state = talloc_get_type_abort(
m->private_data, struct pdb_ads_state);
+ struct tldap_context *ld;
TALLOC_CTX *frame = talloc_stackframe();
struct tldap_mod *mods;
int rc;
char *aliasdn, *memberdn;
NTSTATUS status;
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
+ }
+
status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
return NT_STATUS_NO_MEMORY;
}
- rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
+ rc = tldap_modify(ld, aliasdn, 1, mods, NULL, 0, NULL, 0);
TALLOC_FREE(frame);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_modify failed: %s\n",
return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
}
-static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
+static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
struct dom_sid *psid)
{
const char *attrs[1] = { "objectSid" };
false)) {
return false;
}
- rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
- attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
- &msg, "(objectclass=*)");
+ rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
+ attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
+ &msg, "(objectclass=*)");
TALLOC_FREE(dn);
if (talloc_array_length(msg) != 1) {
DEBUG(10, ("Got %d objects, expected one\n",
sidstr = sid_binstring(talloc_tos(), alias);
NT_STATUS_HAVE_NO_MEMORY(sidstr);
- rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
- attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
- "(objectsid=%s)", sidstr);
+ rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
+ attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
+ &msg, "(objectsid=%s)", sidstr);
TALLOC_FREE(sidstr);
if (rc != TLDAP_SUCCESS) {
DEBUG(10, ("ldap_search failed %s\n",
}
for (i=0; i<num_members; i++) {
- if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
+ if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
TALLOC_FREE(members);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
const DOM_SID *domain_sid,
const DOM_SID *members,
size_t num_members,
- uint32 **pp_alias_rids,
- size_t *p_num_alias_rids)
+ uint32_t **palias_rids,
+ size_t *pnum_alias_rids)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ struct pdb_ads_state *state = talloc_get_type_abort(
+ m->private_data, struct pdb_ads_state);
+ const char *attrs[1] = { "objectSid" };
+ struct tldap_message **msg;
+ uint32_t *alias_rids = NULL;
+ size_t num_alias_rids = 0;
+ int i, rc, count;
+ bool got_members = false;
+ char *filter;
+ NTSTATUS status;
+
+ /*
+ * TODO: Get the filter right so that we only get the aliases from
+ * either the SAM or BUILTIN
+ */
+
+ filter = talloc_asprintf(talloc_tos(),
+ "(&(|(grouptype=%d)(grouptype=%d))"
+ "(objectclass=group)(|",
+ GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
+ GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
+ if (filter == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<num_members; i++) {
+ char *dn;
+
+ status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
+ sid_string_dbg(&members[i]),
+ nt_errstr(status)));
+ continue;
+ }
+ filter = talloc_asprintf_append_buffer(
+ filter, "(member=%s)", dn);
+ TALLOC_FREE(dn);
+ if (filter == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ got_members = true;
+ }
+
+ if (!got_members) {
+ goto done;
+ }
+
+ rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
+ attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
+ &msg, "%s))", filter);
+ TALLOC_FREE(filter);
+ if (rc != TLDAP_SUCCESS) {
+ DEBUG(10, ("tldap_search failed %s\n",
+ tldap_errstr(debug_ctx(), state->ld, rc)));
+ return NT_STATUS_LDAP(rc);
+ }
+
+ count = talloc_array_length(msg);
+ if (count == 0) {
+ goto done;
+ }
+
+ alias_rids = talloc_array(mem_ctx, uint32_t, count);
+ if (alias_rids == NULL) {
+ TALLOC_FREE(msg);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<count; i++) {
+ struct dom_sid sid;
+
+ if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
+ DEBUG(10, ("Could not pull SID for member %d\n", i));
+ continue;
+ }
+ if (sid_peek_check_rid(domain_sid, &sid,
+ &alias_rids[num_alias_rids])) {
+ num_alias_rids += 1;
+ }
+ }
+done:
+ TALLOC_FREE(msg);
+ *palias_rids = alias_rids;
+ *pnum_alias_rids = 0;
+ return NT_STATUS_OK;
}
static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
const DOM_SID *domain_sid,
int num_rids,
uint32 *rids,
- const char **pp_names,
- enum lsa_SidType *attrs)
+ const char **names,
+ enum lsa_SidType *lsa_attrs)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ struct pdb_ads_state *state = talloc_get_type_abort(
+ m->private_data, struct pdb_ads_state);
+ const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
+ int i, num_mapped;
+
+ if (num_rids == 0) {
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ num_mapped = 0;
+
+ for (i=0; i<num_rids; i++) {
+ struct dom_sid sid;
+ struct tldap_message **msg;
+ char *sidstr;
+ uint32_t attr;
+ int rc;
+
+ lsa_attrs[i] = SID_NAME_UNKNOWN;
+
+ sid_compose(&sid, domain_sid, rids[i]);
+
+ sidstr = sid_binstring(talloc_tos(), &sid);
+ NT_STATUS_HAVE_NO_MEMORY(sidstr);
+
+ rc = pdb_ads_search_fmt(state, state->domaindn,
+ TLDAP_SCOPE_SUB, attrs,
+ ARRAY_SIZE(attrs), 0, talloc_tos(),
+ &msg, "(objectsid=%s)", sidstr);
+ TALLOC_FREE(sidstr);
+ if (rc != TLDAP_SUCCESS) {
+ DEBUG(10, ("ldap_search failed %s\n",
+ tldap_errstr(debug_ctx(), state->ld, rc)));
+ continue;
+ }
+
+ switch talloc_array_length(msg) {
+ case 0:
+ DEBUG(10, ("rid %d not found\n", (int)rids[i]));
+ continue;
+ case 1:
+ break;
+ default:
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ names[i] = tldap_talloc_single_attribute(
+ msg[0], "samAccountName", talloc_tos());
+ if (names[i] == NULL) {
+ DEBUG(10, ("no samAccountName\n"));
+ continue;
+ }
+ if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
+ DEBUG(10, ("no samAccountType"));
+ continue;
+ }
+ lsa_attrs[i] = ads_atype_map(attr);
+ num_mapped += 1;
+ }
+
+ if (num_mapped == 0) {
+ return NT_STATUS_NONE_MAPPED;
+ }
+ if (num_mapped < num_rids) {
+ return STATUS_SOME_UNMAPPED;
+ }
+ return NT_STATUS_OK;
}
static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
return false;
}
- rc = tldap_search_fmt(
- state->ld, state->domaindn, TLDAP_SCOPE_SUB,
+ rc = pdb_ads_search_fmt(
+ state, state->domaindn, TLDAP_SCOPE_SUB,
attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
"%s", filter);
if (rc != TLDAP_SUCCESS) {
return false;
}
- rc = tldap_search_fmt(
- state->ld, state->domaindn, TLDAP_SCOPE_SUB,
+ rc = pdb_ads_search_fmt(
+ state, state->domaindn, TLDAP_SCOPE_SUB,
NULL, 0, 0, talloc_tos(), &msg,
"(&(objectsid=%s)(objectclass=user))", sidstr);
if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
return true;
}
- rc = tldap_search_fmt(
- state->ld, state->domaindn, TLDAP_SCOPE_SUB,
+ rc = pdb_ads_search_fmt(
+ state, state->domaindn, TLDAP_SCOPE_SUB,
NULL, 0, 0, talloc_tos(), &msg,
"(&(objectsid=%s)(objectclass=group))", sidstr);
if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
m->del_groupmem = pdb_ads_del_groupmem;
m->create_alias = pdb_ads_create_alias;
m->delete_alias = pdb_ads_delete_alias;
- m->get_aliasinfo = pdb_ads_get_aliasinfo;
+ m->get_aliasinfo = pdb_default_get_aliasinfo;
m->set_aliasinfo = pdb_ads_set_aliasinfo;
m->add_aliasmem = pdb_ads_add_aliasmem;
m->del_aliasmem = pdb_ads_del_aliasmem;
return;
}
+/*
+ this is used to catch debug messages from events
+*/
+static void s3_tldap_debug(void *context, enum tldap_debug_level level,
+ const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
+
+static void s3_tldap_debug(void *context, enum tldap_debug_level level,
+ const char *fmt, va_list ap)
+{
+ int samba_level = -1;
+ char *s = NULL;
+ switch (level) {
+ case TLDAP_DEBUG_FATAL:
+ samba_level = 0;
+ break;
+ case TLDAP_DEBUG_ERROR:
+ samba_level = 1;
+ break;
+ case TLDAP_DEBUG_WARNING:
+ samba_level = 2;
+ break;
+ case TLDAP_DEBUG_TRACE:
+ samba_level = 10;
+ break;
+
+ };
+ if (vasprintf(&s, fmt, ap) == -1) {
+ return;
+ }
+ DEBUG(samba_level, ("tldap: %s", s));
+ free(s);
+}
+
+static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
+{
+ NTSTATUS status;
+ int fd;
+
+ if (tldap_connection_ok(state->ld)) {
+ return state->ld;
+ }
+ TALLOC_FREE(state->ld);
+
+ status = open_socket_out(
+ (struct sockaddr_storage *)(void *)&state->socket_address,
+ 0, 0, &fd);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("Could not connect to %s: %s\n",
+ state->socket_address.sun_path, nt_errstr(status)));
+ return NULL;
+ }
+
+ state->ld = tldap_context_create(state, fd);
+ if (state->ld == NULL) {
+ close(fd);
+ return NULL;
+ }
+ tldap_set_debug(state->ld, s3_tldap_debug, NULL);
+
+ return state->ld;
+}
+
+int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
+ int scope, const char *attrs[], int num_attrs,
+ int attrsonly,
+ TALLOC_CTX *mem_ctx, struct tldap_message ***res,
+ const char *fmt, ...)
+{
+ struct tldap_context *ld;
+ va_list ap;
+ int ret;
+
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ return TLDAP_SERVER_DOWN;
+ }
+
+ va_start(ap, fmt);
+ ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
+ mem_ctx, res, fmt, ap);
+ va_end(ap);
+
+ if (ret != TLDAP_SERVER_DOWN) {
+ return ret;
+ }
+
+ /* retry once */
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ return TLDAP_SERVER_DOWN;
+ }
+
+ va_start(ap, fmt);
+ ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
+ mem_ctx, res, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
const char *location)
{
const char *ncname_attrs[1] = { "netbiosname" };
struct tldap_message **rootdse, **domain, **ncname;
TALLOC_CTX *frame = talloc_stackframe();
- struct sockaddr_un sunaddr;
NTSTATUS status;
int num_domains;
- int fd, rc;
-
- ZERO_STRUCT(sunaddr);
- sunaddr.sun_family = AF_UNIX;
- strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
-
- status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
- 0, 0, &fd);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("Could not connect to %s: %s\n", location,
- nt_errstr(status)));
- goto done;
- }
+ int rc;
- state->ld = tldap_context_create(state, fd);
- if (state->ld == NULL) {
- close(fd);
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
+ ZERO_STRUCT(state->socket_address);
+ state->socket_address.sun_family = AF_UNIX;
+ strncpy(state->socket_address.sun_path, location,
+ sizeof(state->socket_address.sun_path) - 1);
- rc = tldap_search_fmt(
- state->ld, "", TLDAP_SCOPE_BASE,
+ rc = pdb_ads_search_fmt(
+ state, "", TLDAP_SCOPE_BASE,
rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
talloc_tos(), &rootdse, "(objectclass=*)");
if (rc != TLDAP_SUCCESS) {
/*
* Figure out our domain's SID
*/
- rc = tldap_search_fmt(
- state->ld, state->domaindn, TLDAP_SCOPE_BASE,
+ rc = pdb_ads_search_fmt(
+ state, state->domaindn, TLDAP_SCOPE_BASE,
domain_attrs, ARRAY_SIZE(domain_attrs), 0,
talloc_tos(), &domain, "(objectclass=*)");
if (rc != TLDAP_SUCCESS) {
/*
* Figure out our domain's short name
*/
- rc = tldap_search_fmt(
- state->ld, state->configdn, TLDAP_SCOPE_SUB,
+ rc = pdb_ads_search_fmt(
+ state, state->configdn, TLDAP_SCOPE_SUB,
ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
if (rc != TLDAP_SUCCESS) {
if (m == NULL) {
return NT_STATUS_NO_MEMORY;
}
- state = talloc(m, struct pdb_ads_state);
+ state = talloc_zero(m, struct pdb_ads_state);
if (state == NULL) {
goto nomem;
}