static NTSTATUS idmap_tdb_sid_to_id(struct idmap_domain *dom, struct id_map *map) { NTSTATUS ret; TDB_DATA data; char *keystr; unsigned long rec_id = 0; struct idmap_tdb_context *ctx; TALLOC_CTX *tmp_ctx = talloc_stackframe(); ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); keystr = sid_string_talloc(tmp_ctx, map->sid); if (keystr == NULL) { DEBUG(0, ("Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; goto done; } DEBUG(10,("Fetching record %s\n", keystr)); /* Check if sid is present in database */ ret = dbwrap_fetch_bystring(ctx->db, tmp_ctx, keystr, &data); if (!NT_STATUS_IS_OK(ret)) { DEBUG(10,("Record %s not found\n", keystr)); ret = NT_STATUS_NONE_MAPPED; goto done; } /* What type of record is this ? */ if (sscanf((const char *)data.dptr, "UID %lu", &rec_id) == 1) { /* Try a UID record. */ map->xid.id = rec_id; map->xid.type = ID_TYPE_UID; DEBUG(10,("Found uid record %s -> %s \n", keystr, (const char *)data.dptr )); ret = NT_STATUS_OK; } else if (sscanf((const char *)data.dptr, "GID %lu", &rec_id) == 1) { /* Try a GID record. */ map->xid.id = rec_id; map->xid.type = ID_TYPE_GID; DEBUG(10,("Found gid record %s -> %s \n", keystr, (const char *)data.dptr )); ret = NT_STATUS_OK; } else { /* Unknown record type ! */ DEBUG(2, ("Found INVALID record %s -> %s\n", keystr, (const char *)data.dptr)); ret = NT_STATUS_INTERNAL_DB_ERROR; goto done; } /* apply filters before returning result */ if (!idmap_unix_id_is_in_range(map->xid.id, dom)) { DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n", map->xid.id, dom->low_id, dom->high_id)); ret = NT_STATUS_NONE_MAPPED; } done: talloc_free(tmp_ctx); return ret; }
static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids) { LDAPMessage *entry = NULL; NTSTATUS ret; TALLOC_CTX *memctx; struct idmap_ldap_context *ctx; LDAPMessage *result = NULL; const char *uidNumber; const char *gidNumber; const char **attr_list; char *filter = NULL; bool multi = False; int idx = 0; int bidx = 0; int count; int rc; int i; /* Only do query if we are online */ if (idmap_is_offline()) { return NT_STATUS_FILE_IS_OFFLINE; } ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context); memctx = talloc_new(ctx); if ( ! memctx) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; } uidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER); gidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER); attr_list = get_attr_list(memctx, sidmap_attr_list); if ( ! ids[1]) { /* if we are requested just one mapping use the simple filter */ filter = talloc_asprintf(memctx, "(&(objectClass=%s)(%s=%s))", LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_string_talloc(memctx, ids[0]->sid)); CHECK_ALLOC_DONE(filter); DEBUG(10, ("Filter: [%s]\n", filter)); } else { /* multiple mappings */ multi = True; } for (i = 0; ids[i]; i++) { ids[i]->status = ID_UNKNOWN; } again: if (multi) { TALLOC_FREE(filter); filter = talloc_asprintf(memctx, "(&(objectClass=%s)(|", LDAP_OBJ_IDMAP_ENTRY); CHECK_ALLOC_DONE(filter); bidx = idx; for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) { filter = talloc_asprintf_append_buffer(filter, "(%s=%s)", LDAP_ATTRIBUTE_SID, sid_string_talloc(memctx, ids[idx]->sid)); CHECK_ALLOC_DONE(filter); } filter = talloc_asprintf_append_buffer(filter, "))"); CHECK_ALLOC_DONE(filter); DEBUG(10, ("Filter: [%s]", filter)); } else { bidx = 0; idx = 1; } rc = smbldap_search(ctx->smbldap_state, ctx->suffix, LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result); if (rc != LDAP_SUCCESS) { DEBUG(3,("Failure looking up sids (%s)\n", ldap_err2string(rc))); ret = NT_STATUS_UNSUCCESSFUL; goto done; } count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result); if (count == 0) { DEBUG(10, ("NO SIDs found\n")); } for (i = 0; i < count; i++) { char *sidstr = NULL; char *tmp = NULL; enum id_type type; struct id_map *map; struct dom_sid sid; uint32_t id; if (i == 0) { /* first entry */ entry = ldap_first_entry(ctx->smbldap_state->ldap_struct, result); } else { /* following ones */ entry = ldap_next_entry(ctx->smbldap_state->ldap_struct, entry); } if ( ! entry) { DEBUG(2, ("ERROR: Unable to fetch ldap entries " "from results\n")); break; } /* first check if the SID is present */ sidstr = smbldap_talloc_single_attribute( ctx->smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID, memctx); if ( ! sidstr) { /* no sid ??, skip entry */ DEBUG(2, ("WARNING SID not found on entry\n")); continue; } if ( ! string_to_sid(&sid, sidstr)) { DEBUG(2, ("ERROR: Invalid SID on entry\n")); TALLOC_FREE(sidstr); continue; } map = idmap_find_map_by_sid(&ids[bidx], &sid); if (!map) { DEBUG(2, ("WARNING: couldn't find entry sid (%s) " "in ids", sidstr)); TALLOC_FREE(sidstr); continue; } /* now try to see if it is a uid, if not try with a gid * (gid is more common, but in case both uidNumber and * gidNumber are returned the SID is mapped to the uid * not the gid) */ type = ID_TYPE_UID; tmp = smbldap_talloc_single_attribute( ctx->smbldap_state->ldap_struct, entry, uidNumber, memctx); if ( ! tmp) { type = ID_TYPE_GID; tmp = smbldap_talloc_single_attribute( ctx->smbldap_state->ldap_struct, entry, gidNumber, memctx); } if ( ! tmp) { /* no ids ?? */ DEBUG(5, ("no uidNumber, " "nor gidNumber attributes found\n")); TALLOC_FREE(sidstr); continue; } id = strtoul(tmp, NULL, 10); if (!idmap_unix_id_is_in_range(id, dom)) { DEBUG(5, ("Requested id (%u) out of range (%u - %u). " "Filtered!\n", id, dom->low_id, dom->high_id)); TALLOC_FREE(sidstr); TALLOC_FREE(tmp); continue; } TALLOC_FREE(tmp); if (map->status == ID_MAPPED) { DEBUG(1, ("WARNING: duplicate %s mapping in LDAP. " "overwriting mapping %s -> %u with %s -> %u\n", (type == ID_TYPE_UID) ? "UID" : "GID", sidstr, map->xid.id, sidstr, id)); } TALLOC_FREE(sidstr); /* mapped */ map->xid.type = type; map->xid.id = id; map->status = ID_MAPPED; DEBUG(10, ("Mapped %s -> %lu (%d)\n", sid_string_dbg(map->sid), (unsigned long)map->xid.id, map->xid.type)); } /* free the ldap results */ if (result) { ldap_msgfree(result); result = NULL; } if (multi && ids[idx]) { /* still some values to map */ goto again; } /* * try to create new mappings for unmapped sids */ for (i = 0; ids[i]; i++) { if (ids[i]->status != ID_MAPPED) { ids[i]->status = ID_UNMAPPED; if (ids[i]->sid != NULL) { ret = idmap_ldap_new_mapping(dom, ids[i]); if (!NT_STATUS_IS_OK(ret)) { goto done; } } } } ret = NT_STATUS_OK; done: talloc_free(memctx); return ret; }
static NTSTATUS idmap_tdb_id_to_sid(struct idmap_domain *dom, struct id_map *map) { NTSTATUS ret; TDB_DATA data; char *keystr; struct idmap_tdb_context *ctx; if (!dom || !map) { return NT_STATUS_INVALID_PARAMETER; } ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); /* apply filters before checking */ if (!idmap_unix_id_is_in_range(map->xid.id, dom)) { DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n", map->xid.id, dom->low_id, dom->high_id)); return NT_STATUS_NONE_MAPPED; } switch (map->xid.type) { case ID_TYPE_UID: keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id); break; case ID_TYPE_GID: keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id); break; default: DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type)); return NT_STATUS_INVALID_PARAMETER; } /* final SAFE_FREE safe */ data.dptr = NULL; if (keystr == NULL) { DEBUG(0, ("Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; goto done; } DEBUG(10,("Fetching record %s\n", keystr)); /* Check if the mapping exists */ ret = dbwrap_fetch_bystring(ctx->db, NULL, keystr, &data); if (!NT_STATUS_IS_OK(ret)) { DEBUG(10,("Record %s not found\n", keystr)); ret = NT_STATUS_NONE_MAPPED; goto done; } if (!string_to_sid(map->sid, (const char *)data.dptr)) { DEBUG(10,("INVALID SID (%s) in record %s\n", (const char *)data.dptr, keystr)); ret = NT_STATUS_INTERNAL_DB_ERROR; goto done; } DEBUG(10,("Found record %s -> %s\n", keystr, (const char *)data.dptr)); ret = NT_STATUS_OK; done: talloc_free(data.dptr); talloc_free(keystr); return ret; }