1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose/*
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose SSSD
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose ID-mapping plugin for winbind
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose Authors:
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose Sumit Bose <sbose@redhat.com>
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose Copyright (C) 2016 Red Hat
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose This program is free software; you can redistribute it and/or modify
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose it under the terms of the GNU General Public License as published by
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose the Free Software Foundation; either version 3 of the License, or
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose (at your option) any later version.
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose This program is distributed in the hope that it will be useful,
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose GNU General Public License for more details.
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose You should have received a copy of the GNU General Public License
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose*/
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose#include <string.h>
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose#include <errno.h>
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose#include "lib/winbind_idmap_sss/winbind_idmap_sss.h"
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose#include "sss_client/idmap/sss_nss_idmap.h"
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose#include "lib/idmap/sss_idmap.h"
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose#include "util/util_sss_idmap.h"
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bosestruct idmap_sss_ctx {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose struct sss_idmap_ctx *idmap_ctx;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose};
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bosestatic NTSTATUS idmap_sss_initialize(struct idmap_domain *dom)
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose{
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose struct idmap_sss_ctx *ctx;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose enum idmap_error_code err;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose if (dom == NULL) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose return ERROR_INVALID_PARAMETER;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose ctx = talloc_zero(dom, struct idmap_sss_ctx);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose if (ctx == NULL) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose return NT_STATUS_NO_MEMORY;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose err = sss_idmap_init(sss_idmap_talloc, ctx, sss_idmap_talloc_free,
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose &ctx->idmap_ctx);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose if (err != IDMAP_SUCCESS) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose talloc_free(ctx);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose return NT_STATUS_NO_MEMORY;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose dom->private_data = ctx;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose return NT_STATUS_OK;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose}
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bosestatic NTSTATUS idmap_sss_unixids_to_sids(struct idmap_domain *dom,
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose struct id_map **map)
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose{
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose size_t c;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose int ret;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose char *sid_str;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose enum sss_id_type id_type;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose struct dom_sid *sid;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose enum idmap_error_code err;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose struct idmap_sss_ctx *ctx;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose if (dom == NULL) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose return ERROR_INVALID_PARAMETER;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose ctx = talloc_get_type(dom->private_data, struct idmap_sss_ctx);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose if (ctx == NULL) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose return ERROR_INVALID_PARAMETER;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose for (c = 0; map[c]; c++) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose map[c]->status = ID_UNKNOWN;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose for (c = 0; map[c]; c++) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose ret = sss_nss_getsidbyid(map[c]->xid.id, &sid_str, &id_type);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose if (ret != 0) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose if (ret == ENOENT) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose map[c]->status = ID_UNMAPPED;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose continue;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose switch (id_type) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose case SSS_ID_TYPE_UID:
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose map[c]->xid.type = ID_TYPE_UID;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose break;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose case SSS_ID_TYPE_GID:
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose map[c]->xid.type = ID_TYPE_GID;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose break;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose case SSS_ID_TYPE_BOTH:
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose map[c]->xid.type = ID_TYPE_BOTH;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose break;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose default:
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose free(sid_str);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose continue;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose err = sss_idmap_sid_to_smb_sid(ctx->idmap_ctx, sid_str, &sid);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose free(sid_str);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose if (err != IDMAP_SUCCESS) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose continue;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose memcpy(map[c]->sid, sid, sizeof(struct dom_sid));
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose sss_idmap_free_smb_sid(ctx->idmap_ctx, sid);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose map[c]->status = ID_MAPPED;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose return NT_STATUS_OK;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose}
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bosestatic NTSTATUS idmap_sss_sids_to_unixids(struct idmap_domain *dom,
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose struct id_map **map)
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose{
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose size_t c;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose int ret;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose char *sid_str;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose enum sss_id_type id_type;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose enum idmap_error_code err;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose struct idmap_sss_ctx *ctx;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose uint32_t id;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose if (dom == NULL) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose return ERROR_INVALID_PARAMETER;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose ctx = talloc_get_type(dom->private_data, struct idmap_sss_ctx);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose if (ctx == NULL) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose return ERROR_INVALID_PARAMETER;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose for (c = 0; map[c]; c++) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose map[c]->status = ID_UNKNOWN;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose for (c = 0; map[c]; c++) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose err = sss_idmap_smb_sid_to_sid(ctx->idmap_ctx, map[c]->sid, &sid_str);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose if (err != IDMAP_SUCCESS) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose continue;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose ret = sss_nss_getidbysid(sid_str, &id, &id_type);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose sss_idmap_free_sid(ctx->idmap_ctx, sid_str);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose if (ret != 0) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose if (ret == ENOENT) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose map[c]->status = ID_UNMAPPED;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose continue;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose switch (id_type) {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose case SSS_ID_TYPE_UID:
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose map[c]->xid.type = ID_TYPE_UID;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose break;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose case SSS_ID_TYPE_GID:
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose map[c]->xid.type = ID_TYPE_GID;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose break;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose case SSS_ID_TYPE_BOTH:
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose map[c]->xid.type = ID_TYPE_BOTH;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose break;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose default:
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose continue;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose map[c]->xid.id = id;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose map[c]->status = ID_MAPPED;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose }
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose return NT_STATUS_OK;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose}
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bosestatic struct idmap_methods sss_methods = {
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose .init = idmap_sss_initialize,
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose .unixids_to_sids = idmap_sss_unixids_to_sids,
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose .sids_to_unixids = idmap_sss_sids_to_unixids,
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose};
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit BoseNTSTATUS idmap_sss_init(void)
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose{
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "sss", &sss_methods);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose}
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit BoseNTSTATUS samba_init_module(void)
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose{
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "sss", &sss_methods);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose}