#include "includes.h"
#include "winbindd.h"
+#include "secrets.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_IDMAP
#include "smbldap.h"
+static char *idmap_fetch_secret(const char *backend, bool alloc,
+ const char *domain, const char *identity)
+{
+ char *tmp, *ret;
+ int r;
+
+ if (alloc) {
+ r = asprintf(&tmp, "IDMAP_ALLOC_%s", backend);
+ } else {
+ r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain);
+ }
+
+ if (r < 0)
+ return NULL;
+
+ strupper_m(tmp); /* make sure the key is case insensitive */
+ ret = secrets_fetch_generic(tmp, identity);
+
+ SAFE_FREE(tmp);
+
+ return ret;
+}
+
struct idmap_ldap_context {
struct smbldap_state *smbldap_state;
char *url;
DEBUG(2, ("get_credentials: Failed to lookup ldap "
"bind creds. Using anonymous connection.\n"));
anon = True;
+ *dn = NULL;
} else {
*dn = talloc_strdup(mem_ctx, user_dn);
SAFE_FREE( user_dn );
static NTSTATUS idmap_ldap_alloc_init(const char *params)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- const char *range;
const char *tmp;
uid_t low_uid = 0;
uid_t high_uid = 0;
/* load ranges */
- idmap_alloc_ldap->low_uid = 0;
- idmap_alloc_ldap->high_uid = 0;
- idmap_alloc_ldap->low_gid = 0;
- idmap_alloc_ldap->high_gid = 0;
-
- range = lp_parm_const_string(-1, "idmap alloc config", "range", NULL);
- if (range && range[0]) {
- unsigned low_id, high_id;
-
- if (sscanf(range, "%u - %u", &low_id, &high_id) == 2) {
- if (low_id < high_id) {
- idmap_alloc_ldap->low_gid = low_id;
- idmap_alloc_ldap->low_uid = low_id;
- idmap_alloc_ldap->high_gid = high_id;
- idmap_alloc_ldap->high_uid = high_id;
- } else {
- DEBUG(1, ("ERROR: invalid idmap alloc range "
- "[%s]", range));
- }
- } else {
- DEBUG(1, ("ERROR: invalid syntax for idmap alloc "
- "config:range [%s]", range));
- }
- }
-
- if (lp_idmap_uid(&low_uid, &high_uid)) {
- idmap_alloc_ldap->low_uid = low_uid;
- idmap_alloc_ldap->high_uid = high_uid;
+ if (!lp_idmap_uid(&low_uid, &high_uid)
+ || !lp_idmap_gid(&low_gid, &high_gid)) {
+ DEBUG(1, ("idmap uid or idmap gid missing\n"));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
- if (lp_idmap_gid(&low_gid, &high_gid)) {
- idmap_alloc_ldap->low_gid = low_gid;
- idmap_alloc_ldap->high_gid= high_gid;
- }
+ idmap_alloc_ldap->low_uid = low_uid;
+ idmap_alloc_ldap->high_uid = high_uid;
+ idmap_alloc_ldap->low_gid = low_gid;
+ idmap_alloc_ldap->high_gid= high_gid;
if (idmap_alloc_ldap->high_uid <= idmap_alloc_ldap->low_uid) {
- DEBUG(1, ("idmap uid range missing or invalid\n"));
+ DEBUG(1, ("idmap uid range invalid\n"));
DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (idmap_alloc_ldap->high_gid <= idmap_alloc_ldap->low_gid) {
- DEBUG(1, ("idmap gid range missing or invalid\n"));
+ DEBUG(1, ("idmap gid range invalid\n"));
DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
CHECK_ALLOC_DONE( idmap_alloc_ldap->url );
+ trim_char(idmap_alloc_ldap->url, '\"', '\"');
+
tmp = lp_parm_const_string(-1, "idmap alloc config",
"ldap_base_dn", NULL);
if ( ! tmp || ! *tmp) {
if ( ! (id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
entry, type, ctx))) {
DEBUG(0,("%s attribute not found\n", type));
- goto done;
- }
- if ( ! id_str) {
- DEBUG(0,("Out of memory\n"));
- ret = NT_STATUS_NO_MEMORY;
+ ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
return ret;
}
-/**********************************
- Get current highest id.
-**********************************/
-
-static NTSTATUS idmap_ldap_get_hwm(struct unixid *xid)
-{
- TALLOC_CTX *memctx;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- int rc = LDAP_SERVER_DOWN;
- int count = 0;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- char *id_str;
- char *filter = NULL;
- const char **attr_list;
- const char *type;
-
- /* Only do query if we are online */
- if (idmap_is_offline()) {
- return NT_STATUS_FILE_IS_OFFLINE;
- }
-
- if ( ! idmap_alloc_ldap) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- memctx = talloc_new(idmap_alloc_ldap);
- if ( ! memctx) {
- DEBUG(0, ("Out of memory!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- /* get type */
- switch (xid->type) {
-
- case ID_TYPE_UID:
- type = get_attr_key2string(idpool_attr_list,
- LDAP_ATTR_UIDNUMBER);
- break;
-
- case ID_TYPE_GID:
- type = get_attr_key2string(idpool_attr_list,
- LDAP_ATTR_GIDNUMBER);
- break;
-
- default:
- DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- filter = talloc_asprintf(memctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
- CHECK_ALLOC_DONE(filter);
-
- attr_list = get_attr_list(memctx, idpool_attr_list);
- CHECK_ALLOC_DONE(attr_list);
-
- rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
- idmap_alloc_ldap->suffix,
- LDAP_SCOPE_SUBTREE, filter,
- attr_list, 0, &result);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
- goto done;
- }
-
- talloc_autofree_ldapmsg(memctx, result);
-
- count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
- result);
- if (count != 1) {
- DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
- goto done;
- }
-
- entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
- result);
-
- id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
- entry, type, memctx);
- if ( ! id_str) {
- DEBUG(0,("%s attribute not found\n", type));
- goto done;
- }
- if ( ! id_str) {
- DEBUG(0,("Out of memory\n"));
- ret = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- xid->id = strtoul(id_str, NULL, 10);
-
- ret = NT_STATUS_OK;
-done:
- talloc_free(memctx);
- return ret;
-}
-/**********************************
- Set highest id.
-**********************************/
-
-static NTSTATUS idmap_ldap_set_hwm(struct unixid *xid)
-{
- TALLOC_CTX *ctx;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- int rc = LDAP_SERVER_DOWN;
- int count = 0;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- LDAPMod **mods = NULL;
- char *new_id_str;
- char *filter = NULL;
- const char *dn = NULL;
- const char **attr_list;
- const char *type;
-
- /* Only do query if we are online */
- if (idmap_is_offline()) {
- return NT_STATUS_FILE_IS_OFFLINE;
- }
-
- if ( ! idmap_alloc_ldap) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- ctx = talloc_new(idmap_alloc_ldap);
- if ( ! ctx) {
- DEBUG(0, ("Out of memory!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- /* get type */
- switch (xid->type) {
-
- case ID_TYPE_UID:
- type = get_attr_key2string(idpool_attr_list,
- LDAP_ATTR_UIDNUMBER);
- break;
-
- case ID_TYPE_GID:
- type = get_attr_key2string(idpool_attr_list,
- LDAP_ATTR_GIDNUMBER);
- break;
-
- default:
- DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
- CHECK_ALLOC_DONE(filter);
-
- attr_list = get_attr_list(ctx, idpool_attr_list);
- CHECK_ALLOC_DONE(attr_list);
-
- rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
- idmap_alloc_ldap->suffix,
- LDAP_SCOPE_SUBTREE, filter,
- attr_list, 0, &result);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
- goto done;
- }
-
- talloc_autofree_ldapmsg(ctx, result);
-
- count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
- result);
- if (count != 1) {
- DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
- goto done;
- }
-
- entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
- result);
-
- dn = smbldap_talloc_dn(ctx,
- idmap_alloc_ldap->smbldap_state->ldap_struct,
- entry);
- if ( ! dn) {
- goto done;
- }
-
- new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id);
- if ( ! new_id_str) {
- DEBUG(0,("Out of memory\n"));
- ret = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- smbldap_set_mod(&mods, LDAP_MOD_REPLACE, type, new_id_str);
-
- if (mods == NULL) {
- DEBUG(0,("smbldap_set_mod() failed.\n"));
- goto done;
- }
-
- rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);
-
- ldap_mods_free(mods, True);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(1,("Failed to allocate new %s. "
- "smbldap_modify() failed.\n", type));
- goto done;
- }
-
- ret = NT_STATUS_OK;
-
-done:
- talloc_free(ctx);
- return ret;
-}
-
/**********************************
Close idmap ldap alloc
**********************************/
Initialise idmap database.
********************************/
-static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom)
+static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom,
+ const char *params)
{
NTSTATUS ret;
struct idmap_ldap_context *ctx = NULL;
char *config_option = NULL;
- const char *range = NULL;
const char *tmp = NULL;
/* Only do init if we are online */
return NT_STATUS_NO_MEMORY;
}
- config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
- if ( ! config_option) {
- DEBUG(0, ("Out of memory!\n"));
- ret = NT_STATUS_NO_MEMORY;
- goto done;
- }
+ if (strequal(dom->name, "*")) {
+ uid_t low_uid = 0;
+ uid_t high_uid = 0;
+ gid_t low_gid = 0;
+ gid_t high_gid = 0;
- /* load ranges */
- range = lp_parm_const_string(-1, config_option, "range", NULL);
- if (range && range[0]) {
- if ((sscanf(range, "%u - %u", &ctx->filter_low_id,
- &ctx->filter_high_id) != 2) ||
- (ctx->filter_low_id > ctx->filter_high_id)) {
- DEBUG(1, ("ERROR: invalid filter range [%s]", range));
- ctx->filter_low_id = 0;
- ctx->filter_high_id = 0;
+ ctx->filter_low_id = 0;
+ ctx->filter_high_id = 0;
+
+ if (lp_idmap_uid(&low_uid, &high_uid)) {
+ ctx->filter_low_id = low_uid;
+ ctx->filter_high_id = high_uid;
+ } else {
+ DEBUG(3, ("Warning: 'idmap uid' not set!\n"));
+ }
+
+ if (lp_idmap_gid(&low_gid, &high_gid)) {
+ if ((low_gid != low_uid) || (high_gid != high_uid)) {
+ DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'"
+ " ranges do not agree -- building "
+ "intersection\n"));
+ ctx->filter_low_id = MAX(ctx->filter_low_id,
+ low_gid);
+ ctx->filter_high_id = MIN(ctx->filter_high_id,
+ high_gid);
+ }
+ } else {
+ DEBUG(3, ("Warning: 'idmap gid' not set!\n"));
+ }
+ } else {
+ const char *range = NULL;
+
+ config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
+ if ( ! config_option) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
}
+
+ /* load ranges */
+ range = lp_parm_const_string(-1, config_option, "range", NULL);
+ if (range && range[0]) {
+ if ((sscanf(range, "%u - %u", &ctx->filter_low_id,
+ &ctx->filter_high_id) != 2))
+ {
+ DEBUG(1, ("ERROR: invalid filter range [%s]", range));
+ ctx->filter_low_id = 0;
+ ctx->filter_high_id = 0;
+ }
+ }
+ }
+
+ if (ctx->filter_low_id > ctx->filter_high_id) {
+ DEBUG(1, ("ERROR: invalid filter range [%u-%u]",
+ ctx->filter_low_id, ctx->filter_high_id));
+ ctx->filter_low_id = 0;
+ ctx->filter_high_id = 0;
}
- if (dom->params && *(dom->params)) {
+ if (params != NULL) {
/* assume location is the only parameter */
- ctx->url = talloc_strdup(ctx, dom->params);
+ ctx->url = talloc_strdup(ctx, params);
} else {
tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
}
CHECK_ALLOC_DONE(ctx->url);
- tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL);
- if ( ! tmp || ! *tmp) {
- tmp = lp_ldap_idmap_suffix();
- if ( ! tmp) {
- DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
+ trim_char(ctx->url, '\"', '\"');
+
+ tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL);
+ if ( ! tmp || ! *tmp) {
+ tmp = lp_ldap_idmap_suffix();
+ if ( ! tmp) {
+ DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
- }
+ }
ctx->suffix = talloc_strdup(ctx, tmp);
CHECK_ALLOC_DONE(ctx->suffix);
goto done;
}
- ret = get_credentials( ctx, ctx->smbldap_state, config_option,
+ ret = get_credentials( ctx, ctx->smbldap_state, config_option,
dom, &ctx->user_dn );
if ( !NT_STATUS_IS_OK(ret) ) {
DEBUG(1,("idmap_ldap_db_init: Failed to get connection "
talloc_set_destructor(ctx, idmap_ldap_close_destructor);
dom->private_data = ctx;
- dom->initialized = True;
talloc_free(config_option);
return NT_STATUS_OK;
TALLOC_CTX *memctx;
struct idmap_ldap_context *ctx;
LDAPMessage *result = NULL;
+ LDAPMessage *entry = NULL;
const char *uidNumber;
const char *gidNumber;
const char **attr_list;
return NT_STATUS_FILE_IS_OFFLINE;
}
- /* Initilization my have been deferred because we were offline */
- if ( ! dom->initialized) {
- ret = idmap_ldap_db_init(dom);
- if ( ! NT_STATUS_IS_OK(ret)) {
- return ret;
- }
- }
-
ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
memctx = talloc_new(ctx);
multi = True;
}
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
again:
if (multi) {
}
for (i = 0; i < count; i++) {
- LDAPMessage *entry = NULL;
char *sidstr = NULL;
- char *tmp = NULL;
+ char *tmp = NULL;
enum id_type type;
struct id_map *map;
uint32_t id;
TALLOC_FREE(sidstr);
continue;
}
+
+ if (map->status == ID_MAPPED) {
+ DEBUG(1, ("WARNING: duplicate %s mapping in LDAP. "
+ "overwriting mapping %u -> %s with %u -> %s\n",
+ (type == ID_TYPE_UID) ? "UID" : "GID",
+ id, sid_string_dbg(map->sid), id, sidstr));
+ }
+
TALLOC_FREE(sidstr);
/* mapped */
/* this function searches up to IDMAP_LDAP_MAX_IDS entries
* in maps for a match */
-static struct id_map *find_map_by_sid(struct id_map **maps, DOM_SID *sid)
+static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid)
{
int i;
static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom,
struct id_map **ids)
{
- LDAPMessage *entry = NULL;
+ LDAPMessage *entry = NULL;
NTSTATUS ret;
TALLOC_CTX *memctx;
struct idmap_ldap_context *ctx;
return NT_STATUS_FILE_IS_OFFLINE;
}
- /* Initilization my have been deferred because we were offline */
- if ( ! dom->initialized) {
- ret = idmap_ldap_db_init(dom);
- if ( ! NT_STATUS_IS_OK(ret)) {
- return ret;
- }
- }
-
ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
memctx = talloc_new(ctx);
multi = True;
}
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
again:
if (multi) {
char *tmp = NULL;
enum id_type type;
struct id_map *map;
- DOM_SID sid;
+ struct dom_sid sid;
uint32_t id;
if (i == 0) { /* first entry */
continue;
}
- TALLOC_FREE(sidstr);
-
/* 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
if ( ! tmp) { /* no ids ?? */
DEBUG(5, ("no uidNumber, "
"nor gidNumber attributes found\n"));
+ TALLOC_FREE(sidstr);
continue;
}
DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
"Filtered!\n", id,
ctx->filter_low_id, ctx->filter_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;
return NT_STATUS_FILE_IS_OFFLINE;
}
- /* Initilization my have been deferred because we were offline */
- if ( ! dom->initialized) {
- ret = idmap_ldap_db_init(dom);
- if ( ! NT_STATUS_IS_OK(ret)) {
- return ret;
- }
- }
-
ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
switch(map->xid.type) {
.init = idmap_ldap_db_init,
.unixids_to_sids = idmap_ldap_unixids_to_sids,
.sids_to_unixids = idmap_ldap_sids_to_unixids,
- .set_mapping = idmap_ldap_set_mapping,
+ .allocate_id = idmap_ldap_get_new_id,
.close_fn = idmap_ldap_close
};
-static struct idmap_alloc_methods idmap_ldap_alloc_methods = {
-
- .init = idmap_ldap_alloc_init,
- .allocate_id = idmap_ldap_allocate_id,
- .get_id_hwm = idmap_ldap_get_hwm,
- .set_id_hwm = idmap_ldap_set_hwm,
- .close_fn = idmap_ldap_alloc_close,
- /* .dump_data = TODO */
-};
-
-NTSTATUS idmap_alloc_ldap_init(void)
-{
- return smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "ldap",
- &idmap_ldap_alloc_methods);
-}
-
+NTSTATUS idmap_ldap_init(void);
NTSTATUS idmap_ldap_init(void)
{
- NTSTATUS ret;
-
- /* FIXME: bad hack to actually register also the alloc_ldap module
- * without changining configure.in */
- ret = idmap_alloc_ldap_init();
- if (! NT_STATUS_IS_OK(ret)) {
- return ret;
- }
return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap",
&idmap_ldap_methods);
}