void test_sss_idmap_error_string(void **state) { size_t c; for (c = IDMAP_SUCCESS; c < IDMAP_ERR_LAST; c++) { assert_string_not_equal(idmap_error_string(c), idmap_error_string(IDMAP_ERR_LAST)); } }
int cifs_idmap_init_plugin(void **handle, const char **errmsg) { struct sssd_ctx *ctx; enum idmap_error_code err; if (handle == NULL || errmsg == NULL) return EINVAL; ctx = malloc(sizeof *ctx); if (!ctx) { *errmsg = "Failed to allocate context"; return -1; } ctx->errmsg = errmsg; ctx_set_error(ctx, NULL); err = sss_idmap_init(NULL, NULL, NULL, &ctx->idmap); if (err != IDMAP_SUCCESS) { ctx_set_error(ctx, idmap_error_string(err)); free(ctx); return -1; } *handle = ctx; return 0; }
/* Test with `getcifsacl file` on client. */ int cifs_idmap_sid_to_str(void *handle, const struct cifs_sid *csid, char **name) { struct sssd_ctx *ctx = handle; enum idmap_error_code iderr; char *sid; enum sss_id_type id_type; int err; iderr = sss_idmap_bin_sid_to_sid(ctx->idmap, (const uint8_t *) csid, sizeof(*csid), &sid); if (iderr != IDMAP_SUCCESS) { ctx_set_error(ctx, idmap_error_string(iderr)); *name = NULL; return -1; } debug("sid: %s", sid); err = sss_nss_getnamebysid(sid, name, &id_type); if (err != 0) { ctx_set_error(ctx, strerror(err)); *name = NULL; return -err; } /* FIXME: Map Samba Unix SIDs? (sid->id and use getpwuid)? */ debug("name: %s", *name); return 0; }
errno_t ipa_idmap_init(TALLOC_CTX *mem_ctx, struct sdap_id_ctx *id_ctx, struct sdap_idmap_ctx **_idmap_ctx) { errno_t ret; TALLOC_CTX *tmp_ctx; enum idmap_error_code err; struct sdap_idmap_ctx *idmap_ctx = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; idmap_ctx = talloc_zero(tmp_ctx, struct sdap_idmap_ctx); if (!idmap_ctx) { ret = ENOMEM; goto done; } idmap_ctx->id_ctx = id_ctx; idmap_ctx->find_new_domain = ipa_idmap_find_new_domain; /* Initialize the map */ err = sss_idmap_init(sss_idmap_talloc, idmap_ctx, sss_idmap_talloc_free, &idmap_ctx->map); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize the ID map: [%s]\n", idmap_error_string(err)); if (err == IDMAP_OUT_OF_MEMORY) { ret = ENOMEM; } else { ret = EINVAL; } goto done; } ret = ipa_idmap_get_ranges_from_sysdb(idmap_ctx, NULL, NULL, false); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_idmap_get_ranges_from_sysdb failed.\n"); goto done; } *_idmap_ctx = talloc_steal(mem_ctx, idmap_ctx); ret = EOK; done: talloc_free(tmp_ctx); return ret; }
/** * cifs_idmap_sids_to_ids - convert struct cifs_sids to struct cifs_uxids * usecase: mount.cifs -o sec=krb5,multiuser,cifsacl,nounix * test: ls -n on mounted share */ int cifs_idmap_sids_to_ids(void *handle, const struct cifs_sid *csid, const size_t num, struct cifs_uxid *cuxid) { struct sssd_ctx *ctx = handle; enum idmap_error_code err; int success = -1; size_t i; char *sid; debug("num: %zd", num); if (num > UINT_MAX) { ctx_set_error(ctx, "num is too large."); return EINVAL; } for (i = 0; i < num; ++i) { err = sss_idmap_bin_sid_to_sid(ctx->idmap, (const uint8_t *) &csid[i], sizeof(csid[i]), &sid); if (err != IDMAP_SUCCESS) { ctx_set_error(ctx, idmap_error_string(err)); continue; } cuxid[i].type = CIFS_UXID_TYPE_UNKNOWN; if (sss_sid_to_id(ctx, sid, &cuxid[i]) == 0 || samba_unix_sid_to_id(sid, &cuxid[i]) == 0) { debug("setting uid of %s to %d", sid, cuxid[i].id.uid); success = 0; } free(sid); } return success; }
static int sid_to_cifs_sid(struct sssd_ctx *ctx, const char *sid, struct cifs_sid *csid) { uint8_t *bsid = NULL; enum idmap_error_code err; size_t length; err = sss_idmap_sid_to_bin_sid(ctx->idmap, sid, &bsid, &length); if (err != IDMAP_SUCCESS) { ctx_set_error(ctx, idmap_error_string(err)); return -1; } if (length > sizeof(struct cifs_sid)) { ctx_set_error(ctx, "too large sid length"); free(bsid); return -1; } memcpy(csid, bsid, length); sss_idmap_free_bin_sid(ctx->idmap, bsid); return 0; }
errno_t sdap_idmap_init(TALLOC_CTX *mem_ctx, struct sdap_id_ctx *id_ctx, struct sdap_idmap_ctx **_idmap_ctx) { errno_t ret; TALLOC_CTX *tmp_ctx; enum idmap_error_code err; size_t i; struct ldb_result *res; const char *dom_name; const char *sid_str; id_t slice_num; id_t idmap_lower; id_t idmap_upper; id_t rangesize; bool autorid_mode; struct sdap_idmap_ctx *idmap_ctx = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; idmap_ctx = talloc_zero(tmp_ctx, struct sdap_idmap_ctx); if (!idmap_ctx) { ret = ENOMEM; goto done; } idmap_ctx->id_ctx = id_ctx; idmap_ctx->find_new_domain = sdap_idmap_find_new_domain; idmap_lower = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_LOWER); idmap_upper = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_UPPER); rangesize = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_RANGESIZE); autorid_mode = dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_AUTORID_COMPAT); /* Validate that the values make sense */ if (rangesize <= 0 || idmap_upper <= idmap_lower || (idmap_upper-idmap_lower) < rangesize) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid settings for range selection: " "[%"SPRIid"][%"SPRIid"][%"SPRIid"]\n", idmap_lower, idmap_upper, rangesize); ret = EINVAL; goto done; } if (((idmap_upper - idmap_lower) % rangesize) != 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Range size does not divide evenly. Uppermost range will " "not be used\n"); } /* Initialize the map */ err = sss_idmap_init(sss_idmap_talloc, idmap_ctx, sss_idmap_talloc_free, &idmap_ctx->map); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize the ID map: [%s]\n", idmap_error_string(err)); if (err == IDMAP_OUT_OF_MEMORY) { ret = ENOMEM; } else { ret = EINVAL; } goto done; } err = sss_idmap_ctx_set_autorid(idmap_ctx->map, autorid_mode); err |= sss_idmap_ctx_set_lower(idmap_ctx->map, idmap_lower); err |= sss_idmap_ctx_set_upper(idmap_ctx->map, idmap_upper); err |= sss_idmap_ctx_set_rangesize(idmap_ctx->map, rangesize); if (err != IDMAP_SUCCESS) { /* This should never happen */ DEBUG(SSSDBG_CRIT_FAILURE, "sss_idmap_ctx corrupted\n"); return EIO; } /* Setup range for externally managed IDs, i.e. IDs are read from the * ldap_user_uid_number and ldap_group_gid_number attributes. */ if (!dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)) { ret = sdap_idmap_add_configured_external_range(idmap_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_idmap_add_configured_external_range failed.\n"); goto done; } } /* Read in any existing mappings from the cache */ ret = sysdb_idmap_get_mappings(tmp_ctx, id_ctx->be->domain, &res); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not read ID mappings from the cache: [%s]\n", strerror(ret)); goto done; } if (ret == EOK && res->count > 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Initializing [%d] domains for ID-mapping\n", res->count); for (i = 0; i < res->count; i++) { dom_name = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_NAME, NULL); if (!dom_name) { /* This should never happen */ ret = EINVAL; goto done; } sid_str = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_IDMAP_SID_ATTR, NULL); if (!sid_str) { /* This should never happen */ ret = EINVAL; goto done; } slice_num = ldb_msg_find_attr_as_int(res->msgs[i], SYSDB_IDMAP_SLICE_ATTR, -1); if (slice_num == -1) { /* This should never happen */ ret = EINVAL; goto done; } ret = sdap_idmap_add_domain(idmap_ctx, dom_name, sid_str, slice_num); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add domain [%s][%s][%"SPRIid"] " "to ID map: [%s]\n", dom_name, sid_str, slice_num, strerror(ret)); goto done; } } } else { /* This is the first time we're setting up id-mapping * Store the default domain as slice 0 */ dom_name = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN); if (!dom_name) { /* If it's not explicitly specified, use the SSSD domain name */ dom_name = idmap_ctx->id_ctx->be->domain->name; ret = dp_opt_set_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN, dom_name); if (ret != EOK) goto done; } sid_str = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN_SID); if (sid_str) { /* Set the default domain as slice 0 */ ret = sdap_idmap_add_domain(idmap_ctx, dom_name, sid_str, 0); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add domain [%s][%s][%u] to ID map: [%s]\n", dom_name, sid_str, 0, strerror(ret)); goto done; } } else { if (dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_AUTORID_COMPAT)) { /* In autorid compatibility mode, we MUST have a slice 0 */ DEBUG(SSSDBG_CRIT_FAILURE, "WARNING: Autorid compatibility mode selected, " "but %s is not set. UID/GID values may differ " "between clients.\n", idmap_ctx->id_ctx->opts->basic[SDAP_IDMAP_DEFAULT_DOMAIN_SID].opt_name); } /* Otherwise, we'll just fall back to hash values as they are seen */ } } *_idmap_ctx = talloc_steal(mem_ctx, idmap_ctx); ret = EOK; done: talloc_free(tmp_ctx); return ret; }