diff options
Diffstat (limited to 'source3/winbindd/idmap_rw.c')
-rw-r--r-- | source3/winbindd/idmap_rw.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/source3/winbindd/idmap_rw.c b/source3/winbindd/idmap_rw.c new file mode 100644 index 0000000..71bfc14 --- /dev/null +++ b/source3/winbindd/idmap_rw.c @@ -0,0 +1,109 @@ +/* + * Unix SMB/CIFS implementation. + * + * ID mapping: abstract r/w new-mapping mechanism + * + * Copyright (C) Michael Adam 2010 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "includes.h" +#include "winbindd.h" +#include "idmap.h" +#include "idmap_rw.h" +#include "libcli/security/dom_sid.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_IDMAP + +NTSTATUS idmap_rw_new_mapping(struct idmap_domain *dom, + struct idmap_rw_ops *ops, + struct id_map *map) +{ + struct dom_sid_buf buf; + NTSTATUS status; + + if (map == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (map->sid == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + switch (map->xid.type) { + case ID_TYPE_NOT_SPECIFIED: + /* + * We need to know if we need a user or group mapping. + * Ask the winbindd parent to provide a valid type hint. + */ + DBG_INFO("%s ID_TYPE_NOT_SPECIFIED => ID_REQUIRE_TYPE\n", + dom_sid_str_buf(map->sid, &buf)); + map->status = ID_REQUIRE_TYPE; + return NT_STATUS_SOME_NOT_MAPPED; + + case ID_TYPE_BOTH: + /* + * For now we still require + * an explicit type as hint + * and don't support ID_TYPE_BOTH + */ + DBG_INFO("%s ID_TYPE_BOTH => ID_REQUIRE_TYPE\n", + dom_sid_str_buf(map->sid, &buf)); + map->status = ID_REQUIRE_TYPE; + return NT_STATUS_SOME_NOT_MAPPED; + + case ID_TYPE_UID: + break; + + case ID_TYPE_GID: + break; + + default: + return NT_STATUS_INVALID_PARAMETER; + } + + status = ops->get_new_id(dom, &map->xid); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("Could not allocate id: %s\n", nt_errstr(status))); + return status; + } + + DEBUG(10, ("Setting mapping: %s <-> %s %lu\n", + dom_sid_str_buf(map->sid, &buf), + (map->xid.type == ID_TYPE_UID) ? "UID" : "GID", + (unsigned long)map->xid.id)); + + map->status = ID_MAPPED; + status = ops->set_mapping(dom, map); + + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { + struct id_map *ids[2]; + DEBUG(5, ("Mapping for %s exists - retrying to map sid\n", + dom_sid_str_buf(map->sid, &buf))); + ids[0] = map; + ids[1] = NULL; + status = dom->methods->sids_to_unixids(dom, ids); + } + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("Could not store the new mapping: %s\n", + nt_errstr(status))); + return status; + } + + return NT_STATUS_OK; +} |