Line data Source code
1 : /* 2 : * Unix SMB/CIFS implementation. 3 : * 4 : * ID mapping: abstract r/w new-mapping mechanism 5 : * 6 : * Copyright (C) Michael Adam 2010 7 : * 8 : * This program is free software; you can redistribute it and/or modify 9 : * it under the terms of the GNU General Public License as published by 10 : * the Free Software Foundation; either version 3 of the License, or 11 : * (at your option) any later version. 12 : * 13 : * This program is distributed in the hope that it will be useful, 14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : * GNU General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU General Public License 19 : * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 : */ 21 : 22 : #include "includes.h" 23 : #include "winbindd.h" 24 : #include "idmap.h" 25 : #include "idmap_rw.h" 26 : #include "libcli/security/dom_sid.h" 27 : 28 : #undef DBGC_CLASS 29 : #define DBGC_CLASS DBGC_IDMAP 30 : 31 15 : NTSTATUS idmap_rw_new_mapping(struct idmap_domain *dom, 32 : struct idmap_rw_ops *ops, 33 : struct id_map *map) 34 : { 35 15 : struct dom_sid_buf buf; 36 15 : NTSTATUS status; 37 : 38 15 : if (map == NULL) { 39 0 : return NT_STATUS_INVALID_PARAMETER; 40 : } 41 : 42 15 : if (map->sid == NULL) { 43 0 : return NT_STATUS_INVALID_PARAMETER; 44 : } 45 : 46 15 : switch (map->xid.type) { 47 0 : case ID_TYPE_NOT_SPECIFIED: 48 : /* 49 : * We need to know if we need a user or group mapping. 50 : * Ask the winbindd parent to provide a valid type hint. 51 : */ 52 0 : DBG_INFO("%s ID_TYPE_NOT_SPECIFIED => ID_REQUIRE_TYPE\n", 53 : dom_sid_str_buf(map->sid, &buf)); 54 0 : map->status = ID_REQUIRE_TYPE; 55 0 : return NT_STATUS_SOME_NOT_MAPPED; 56 : 57 0 : case ID_TYPE_BOTH: 58 : /* 59 : * For now we still require 60 : * an explicit type as hint 61 : * and don't support ID_TYPE_BOTH 62 : */ 63 0 : DBG_INFO("%s ID_TYPE_BOTH => ID_REQUIRE_TYPE\n", 64 : dom_sid_str_buf(map->sid, &buf)); 65 0 : map->status = ID_REQUIRE_TYPE; 66 0 : return NT_STATUS_SOME_NOT_MAPPED; 67 : 68 0 : case ID_TYPE_UID: 69 0 : break; 70 : 71 0 : case ID_TYPE_GID: 72 0 : break; 73 : 74 0 : default: 75 0 : return NT_STATUS_INVALID_PARAMETER; 76 : } 77 : 78 15 : status = ops->get_new_id(dom, &map->xid); 79 : 80 15 : if (!NT_STATUS_IS_OK(status)) { 81 0 : DEBUG(3, ("Could not allocate id: %s\n", nt_errstr(status))); 82 0 : return status; 83 : } 84 : 85 15 : DEBUG(10, ("Setting mapping: %s <-> %s %lu\n", 86 : dom_sid_str_buf(map->sid, &buf), 87 : (map->xid.type == ID_TYPE_UID) ? "UID" : "GID", 88 : (unsigned long)map->xid.id)); 89 : 90 15 : map->status = ID_MAPPED; 91 15 : status = ops->set_mapping(dom, map); 92 : 93 15 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { 94 2 : struct id_map *ids[2]; 95 2 : DEBUG(5, ("Mapping for %s exists - retrying to map sid\n", 96 : dom_sid_str_buf(map->sid, &buf))); 97 2 : ids[0] = map; 98 2 : ids[1] = NULL; 99 2 : status = dom->methods->sids_to_unixids(dom, ids); 100 : } 101 : 102 15 : if (!NT_STATUS_IS_OK(status)) { 103 0 : DEBUG(3, ("Could not store the new mapping: %s\n", 104 : nt_errstr(status))); 105 0 : return status; 106 : } 107 : 108 15 : return NT_STATUS_OK; 109 : }