sss_idmap.c revision 11fd679eb2edabd139c9016e2b7d2085ca3aac5d
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose ID-mapping library
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose Sumit Bose <sbose@redhat.com>
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose Copyright (C) 2012 Red Hat
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose This program is free software; you can redistribute it and/or modify
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose it under the terms of the GNU General Public License as published by
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose the Free Software Foundation; either version 3 of the License, or
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose (at your option) any later version.
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose This program is distributed in the hope that it will be useful,
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose GNU General Public License for more details.
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose You should have received a copy of the GNU General Public License
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bosestatic void *default_alloc(size_t size, void *pvt)
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bosestatic char *idmap_strdup(struct sss_idmap_ctx *ctx, const char *str)
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bosestatic struct sss_idmap_range *idmap_range_dup(struct sss_idmap_ctx *ctx,
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose new = ctx->alloc_func(sizeof(struct sss_idmap_range), ctx->alloc_pvt);
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bosestatic bool id_is_in_range(uint32_t id, struct sss_idmap_range *range,
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return false;
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return true;
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return false;
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Boseconst char *idmap_error_string(enum idmap_error_code err)
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return "IDMAP operation successful";
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return "IDMAP Function is not yet implemented";
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return "IDMAP general error";
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return "IDMAP operation ran out of memory";
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return "IDMAP domain not found";
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return "IDMAP context is invalid";
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return "IDMAP SID is invalid";
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return "IDMAP SID not found";
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return "IDMAP range not found";
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return "IDMAP unknown error code";
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose const char *p;
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose long long a;
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose if (sid == NULL || strncmp(sid, DOM_SID_PREFIX, DOM_SID_PREFIX_LEN) != 0) {
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return false;
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return false;
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return false;
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return false;
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose return true;
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Boseenum idmap_error_code sss_idmap_init(idmap_alloc_func *alloc_func,
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose ctx = alloc_func(sizeof(struct sss_idmap_ctx), alloc_pvt);
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose ctx->free_func = (free_func == NULL) ? default_free : free_func;
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* Set default values. */
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek ctx->idmap_opts.autorid_mode = SSS_IDMAP_DEFAULT_AUTORID;
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek ctx->idmap_opts.idmap_lower = SSS_IDMAP_DEFAULT_LOWER;
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek ctx->idmap_opts.idmap_upper = SSS_IDMAP_DEFAULT_UPPER;
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek ctx->idmap_opts.rangesize = SSS_IDMAP_DEFAULT_RANGESIZE;
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Boseenum idmap_error_code sss_idmap_free(struct sss_idmap_ctx *ctx)
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidekenum idmap_error_code sss_idmap_calculate_range(struct sss_idmap_ctx *ctx,
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek max_slices = (idmap_upper - idmap_lower) / rangesize;
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* The slice is being set explicitly.
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek * This may happen at system startup when we're loading
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek * previously-determined slices. In the future, we may also
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek * permit configuration to select the slice for a domain
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek * explicitly.
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* If slice is -1, we're being asked to pick a new slice */
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* In autorid compatibility mode, always start at 0 and find the
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek * first free value.
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* Hash the domain sid string */
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek hash_val = murmurhash3(dom_sid, strlen(dom_sid), 0xdeadbeef);
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* Now get take the modulus of the hash val and the max_slices
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek * to determine its optimal position in the range.
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* Verify that this slice is not already in use */
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek for (dom = ctx->idmap_domain_info; dom != NULL; dom = dom->next) {
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek if ((dom->range->min <= min && dom->range->max >= max) ||
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek (dom->range->min >= min && dom->range->min <= max) ||
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek (dom->range->max >= min && dom->range->max <= max)) {
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* This range overlaps one already registered
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek * We'll try the next available slot
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* loop around to the beginning if necessary */
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* Keep trying until dom is NULL (meaning we got to the end
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek * without matching) or we have run out of slices and gotten
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek * back to the first one we tried.
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek /* We looped all the way through and found no empty slots */
46222e5191473f9a46aec581273eb2eef22e23beMichal Zidek _range->min = (rangesize * new_slice) + idmap_lower;
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Boseenum idmap_error_code sss_idmap_add_domain(struct sss_idmap_ctx *ctx,
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose dom = ctx->alloc_func(sizeof(struct idmap_domain_info), ctx->alloc_pvt);
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose memset(dom, 0, sizeof(struct idmap_domain_info));
d6f283302268520c1506fb3da4f2a22f5a741be5Michal Zidekstatic bool sss_idmap_sid_is_builtin(const char *sid)
d6f283302268520c1506fb3da4f2a22f5a741be5Michal Zidek return true;
d6f283302268520c1506fb3da4f2a22f5a741be5Michal Zidek return false;
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Boseenum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx,
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose const char *sid,
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose if (strlen(sid) > dom_len && sid[dom_len] == '-' &&
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose strncmp(sid, idmap_domain_info->sid, dom_len) == 0) {
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose if (errno != 0 || rid > UINT32_MAX || *endptr != '\0') {
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Boseenum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx,
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose if (id_is_in_range(id, idmap_domain_info->range, &rid)) {
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose len = snprintf(NULL, 0, SID_FMT, idmap_domain_info->sid, rid);
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose ret = snprintf(sid, len + 1, SID_FMT, idmap_domain_info->sid, rid);
b6dfbf81c61d4431aaa81687ec53e892f8b71edbSumit Boseenum idmap_error_code sss_idmap_dom_sid_to_unix(struct sss_idmap_ctx *ctx,
b6dfbf81c61d4431aaa81687ec53e892f8b71edbSumit Bose err = sss_idmap_dom_sid_to_sid(ctx, dom_sid, &sid);
b6dfbf81c61d4431aaa81687ec53e892f8b71edbSumit Boseenum idmap_error_code sss_idmap_bin_sid_to_unix(struct sss_idmap_ctx *ctx,
b6dfbf81c61d4431aaa81687ec53e892f8b71edbSumit Bose err = sss_idmap_bin_sid_to_sid(ctx, bin_sid, length, &sid);
6f504738cad1ee9daa1bd6eec721caceef65f21dSumit Boseenum idmap_error_code sss_idmap_smb_sid_to_unix(struct sss_idmap_ctx *ctx,
6f504738cad1ee9daa1bd6eec721caceef65f21dSumit Bose err = sss_idmap_smb_sid_to_sid(ctx, smb_sid, &sid);
b6dfbf81c61d4431aaa81687ec53e892f8b71edbSumit Boseenum idmap_error_code sss_idmap_unix_to_dom_sid(struct sss_idmap_ctx *ctx,
b6dfbf81c61d4431aaa81687ec53e892f8b71edbSumit Bose err = sss_idmap_sid_to_dom_sid(ctx, sid, &dom_sid);
b6dfbf81c61d4431aaa81687ec53e892f8b71edbSumit Boseenum idmap_error_code sss_idmap_unix_to_bin_sid(struct sss_idmap_ctx *ctx,
b6dfbf81c61d4431aaa81687ec53e892f8b71edbSumit Bose err = sss_idmap_sid_to_bin_sid(ctx, sid, &bin_sid, &length);
46222e5191473f9a46aec581273eb2eef22e23beMichal Zideksss_idmap_ctx_set_autorid(struct sss_idmap_ctx *ctx, bool use_autorid)
46222e5191473f9a46aec581273eb2eef22e23beMichal Zideksss_idmap_ctx_set_lower(struct sss_idmap_ctx *ctx, id_t lower)
46222e5191473f9a46aec581273eb2eef22e23beMichal Zideksss_idmap_ctx_set_upper(struct sss_idmap_ctx *ctx, id_t upper)
46222e5191473f9a46aec581273eb2eef22e23beMichal Zideksss_idmap_ctx_set_rangesize(struct sss_idmap_ctx *ctx, id_t rangesize)
46222e5191473f9a46aec581273eb2eef22e23beMichal Zideksss_idmap_ctx_get_autorid(struct sss_idmap_ctx *ctx, bool *_autorid)
46222e5191473f9a46aec581273eb2eef22e23beMichal Zideksss_idmap_ctx_get_lower(struct sss_idmap_ctx *ctx, id_t *_lower)
46222e5191473f9a46aec581273eb2eef22e23beMichal Zideksss_idmap_ctx_get_upper(struct sss_idmap_ctx *ctx, id_t *_upper)