Line data Source code
1 : /* 2 : Unix SMB/CIFS implementation. 3 : 4 : Winbind client library. 5 : 6 : Copyright (C) 2008 Kai Blin <kai@samba.org> 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 <tevent.h> 24 : #include "nsswitch/winbind_client.h" 25 : #include "libcli/wbclient/wbclient.h" 26 : #include "libcli/security/dom_sid.h" 27 : #include "nsswitch/libwbclient/wbclient.h" 28 : 29 11385 : NTSTATUS wbc_sids_to_xids(struct id_map *ids, uint32_t count) 30 : { 31 802 : TALLOC_CTX *mem_ctx; 32 802 : uint32_t i; 33 802 : struct wbcDomainSid *sids; 34 802 : struct wbcUnixId *xids; 35 802 : wbcErr result; 36 802 : bool wb_off; 37 : 38 11385 : mem_ctx = talloc_new(NULL); 39 11385 : if (mem_ctx == NULL) { 40 0 : return NT_STATUS_NO_MEMORY; 41 : } 42 : 43 11385 : sids = talloc_array(mem_ctx, struct wbcDomainSid, count); 44 11385 : if (sids == NULL) { 45 0 : TALLOC_FREE(mem_ctx); 46 0 : return NT_STATUS_NO_MEMORY; 47 : } 48 : 49 11385 : xids = talloc_array(mem_ctx, struct wbcUnixId, count); 50 11385 : if (xids == NULL) { 51 0 : TALLOC_FREE(mem_ctx); 52 0 : return NT_STATUS_NO_MEMORY; 53 : } 54 : 55 161958 : for (i=0; i<count; i++) { 56 150573 : memcpy(&sids[i], ids[i].sid, sizeof(struct dom_sid)); 57 : } 58 : 59 11385 : wb_off = winbind_env_set(); 60 11385 : if (wb_off) { 61 1470 : (void)winbind_on(); 62 : } 63 : 64 11385 : result = wbcSidsToUnixIds(sids, count, xids); 65 : 66 11385 : if (wb_off) { 67 1470 : (void)winbind_off(); 68 : } 69 : 70 11385 : if (!WBC_ERROR_IS_OK(result)) { 71 0 : TALLOC_FREE(mem_ctx); 72 0 : return NT_STATUS_INTERNAL_ERROR; 73 : } 74 : 75 161958 : for (i=0; i<count; i++) { 76 150573 : struct wbcUnixId *xid = &xids[i]; 77 150573 : struct unixid *id = &ids[i].xid; 78 : 79 150573 : switch (xid->type) { 80 8801 : case WBC_ID_TYPE_UID: 81 8801 : id->type = ID_TYPE_UID; 82 8801 : id->id = xid->id.uid; 83 8801 : break; 84 8642 : case WBC_ID_TYPE_GID: 85 8642 : id->type = ID_TYPE_GID; 86 8642 : id->id = xid->id.gid; 87 8642 : break; 88 133130 : case WBC_ID_TYPE_BOTH: 89 133130 : id->type = ID_TYPE_BOTH; 90 133130 : id->id = xid->id.uid; 91 133130 : break; 92 0 : case WBC_ID_TYPE_NOT_SPECIFIED: 93 0 : id->type = ID_TYPE_NOT_SPECIFIED; 94 0 : id->id = UINT32_MAX; 95 0 : break; 96 : } 97 150573 : ids[i].status = ID_MAPPED; 98 : } 99 : 100 11385 : TALLOC_FREE(mem_ctx); 101 : 102 11385 : return NT_STATUS_OK; 103 : } 104 : 105 1187 : NTSTATUS wbc_xids_to_sids(struct id_map *ids, uint32_t count) 106 : { 107 0 : TALLOC_CTX *mem_ctx; 108 0 : uint32_t i; 109 0 : struct wbcDomainSid *sids; 110 0 : struct wbcUnixId *xids; 111 0 : wbcErr result; 112 0 : bool wb_off; 113 : 114 1187 : mem_ctx = talloc_new(NULL); 115 1187 : if (mem_ctx == NULL) { 116 0 : return NT_STATUS_NO_MEMORY; 117 : } 118 : 119 1187 : sids = talloc_array(mem_ctx, struct wbcDomainSid, count); 120 1187 : if (sids == NULL) { 121 0 : TALLOC_FREE(mem_ctx); 122 0 : return NT_STATUS_NO_MEMORY; 123 : } 124 : 125 1187 : xids = talloc_array(mem_ctx, struct wbcUnixId, count); 126 1187 : if (xids == NULL) { 127 0 : TALLOC_FREE(mem_ctx); 128 0 : return NT_STATUS_NO_MEMORY; 129 : } 130 : 131 3555 : for (i=0; i<count; i++) { 132 2368 : struct id_map *id = &ids[i]; 133 2368 : struct wbcUnixId *xid = &xids[i]; 134 : 135 2368 : switch (id->xid.type) { 136 1184 : case ID_TYPE_UID: 137 1184 : *xid = (struct wbcUnixId) { 138 : .type = WBC_ID_TYPE_UID, 139 1184 : .id.uid = id->xid.id 140 : }; 141 2368 : break; 142 1184 : case ID_TYPE_GID: 143 1184 : *xid = (struct wbcUnixId) { 144 : .type = WBC_ID_TYPE_GID, 145 1184 : .id.uid = id->xid.id 146 : }; 147 1184 : break; 148 0 : default: 149 0 : TALLOC_FREE(mem_ctx); 150 0 : return NT_STATUS_NOT_FOUND; 151 : } 152 : } 153 : 154 1187 : wb_off = winbind_env_set(); 155 1187 : if (wb_off) { 156 1187 : (void)winbind_on(); 157 : } 158 : 159 1187 : result = wbcUnixIdsToSids(xids, count, sids); 160 : 161 1187 : if (wb_off) { 162 1187 : (void)winbind_off(); 163 : } 164 : 165 1187 : if (!WBC_ERROR_IS_OK(result)) { 166 0 : TALLOC_FREE(mem_ctx); 167 0 : return NT_STATUS_INTERNAL_ERROR; 168 : } 169 : 170 3555 : for (i=0; i<count; i++) { 171 2368 : struct wbcDomainSid *sid = &sids[i]; 172 2368 : struct wbcDomainSid null_sid = { 0 }; 173 2368 : struct id_map *id = &ids[i]; 174 : 175 2368 : if (memcmp(sid, &null_sid, sizeof(*sid)) != 0) { 176 0 : struct dom_sid domsid; 177 2368 : id->status = ID_MAPPED; 178 : 179 2368 : memcpy(&domsid, sid, sizeof(struct dom_sid)); 180 2368 : id->sid = dom_sid_dup(ids, &domsid); 181 2368 : if (id->sid == NULL) { 182 0 : TALLOC_FREE(mem_ctx); 183 0 : return NT_STATUS_NO_MEMORY; 184 : } 185 : } else { 186 0 : id->status = ID_UNMAPPED; 187 0 : id->sid = NULL; 188 : } 189 : } 190 : 191 1187 : TALLOC_FREE(mem_ctx); 192 1187 : return NT_STATUS_OK; 193 : }