1/* 2 Unix SMB/CIFS implementation. 3 4 Winbind ADS backend functions 5 6 Copyright (C) Andrew Tridgell 2001 7 Copyright (C) Andrew Bartlett 2002 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22*/ 23 24#include "includes.h" 25#ifdef HAVE_LDAP 26 27/* convert a single name to a sid in a domain */ 28NTSTATUS ads_name_to_sid(ADS_STRUCT *ads, 29 const char *name, 30 DOM_SID *sid, 31 enum SID_NAME_USE *type) 32{ 33 const char *attrs[] = {"objectSid", "sAMAccountType", NULL}; 34 int count; 35 ADS_STATUS rc; 36 void *res = NULL; 37 char *ldap_exp; 38 uint32 t; 39 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 40 char *escaped_name = escape_ldap_string_alloc(name); 41 char *escaped_realm = escape_ldap_string_alloc(ads->config.realm); 42 43 if (!escaped_name || !escaped_realm) { 44 status = NT_STATUS_NO_MEMORY; 45 goto done; 46 } 47 48 if (asprintf(&ldap_exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))", 49 escaped_name, escaped_name, escaped_realm) == -1) { 50 DEBUG(1,("ads_name_to_sid: asprintf failed!\n")); 51 status = NT_STATUS_NO_MEMORY; 52 goto done; 53 } 54 55 rc = ads_search_retry(ads, &res, ldap_exp, attrs); 56 free(ldap_exp); 57 if (!ADS_ERR_OK(rc)) { 58 DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc))); 59 goto done; 60 } 61 62 count = ads_count_replies(ads, res); 63 if (count != 1) { 64 DEBUG(1,("name_to_sid: %s not found\n", name)); 65 goto done; 66 } 67 68 if (!ads_pull_sid(ads, res, "objectSid", sid)) { 69 DEBUG(1,("No sid for %s !?\n", name)); 70 goto done; 71 } 72 73 if (!ads_pull_uint32(ads, res, "sAMAccountType", &t)) { 74 DEBUG(1,("No sAMAccountType for %s !?\n", name)); 75 goto done; 76 } 77 78 *type = ads_atype_map(t); 79 80 status = NT_STATUS_OK; 81 82 DEBUG(3,("ads name_to_sid mapped %s\n", name)); 83 84done: 85 if (res) ads_msgfree(ads, res); 86 87 SAFE_FREE(escaped_name); 88 SAFE_FREE(escaped_realm); 89 90 return status; 91} 92 93/* convert a sid to a user or group name */ 94NTSTATUS ads_sid_to_name(ADS_STRUCT *ads, 95 TALLOC_CTX *mem_ctx, 96 const DOM_SID *sid, 97 char **name, 98 enum SID_NAME_USE *type) 99{ 100 const char *attrs[] = {"userPrincipalName", 101 "sAMAccountName", 102 "sAMAccountType", NULL}; 103 ADS_STATUS rc; 104 void *msg = NULL; 105 char *ldap_exp = NULL; 106 char *sidstr = NULL; 107 uint32 atype; 108 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 109 110 if (!(sidstr = sid_binstring(sid))) { 111 DEBUG(1,("ads_sid_to_name: sid_binstring failed!\n")); 112 status = NT_STATUS_NO_MEMORY; 113 goto done; 114 } 115 116 if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) { 117 DEBUG(1,("ads_sid_to_name: asprintf failed!\n")); 118 status = NT_STATUS_NO_MEMORY; 119 goto done; 120 } 121 122 rc = ads_search_retry(ads, &msg, ldap_exp, attrs); 123 if (!ADS_ERR_OK(rc)) { 124 status = ads_ntstatus(rc); 125 DEBUG(1,("ads_sid_to_name ads_search: %s\n", ads_errstr(rc))); 126 goto done; 127 } 128 129 if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) { 130 goto done; 131 } 132 133 *name = ads_pull_username(ads, mem_ctx, msg); 134 if (!*name) { 135 DEBUG(1,("ads_sid_to_name: ads_pull_username retuned NULL!\n")); 136 status = NT_STATUS_NO_MEMORY; 137 goto done; 138 } 139 140 *type = ads_atype_map(atype); 141 142 status = NT_STATUS_OK; 143 144 DEBUG(3,("ads sid_to_name mapped %s\n", *name)); 145 146done: 147 if (msg) ads_msgfree(ads, msg); 148 149 SAFE_FREE(ldap_exp); 150 SAFE_FREE(sidstr); 151 152 return status; 153} 154 155 156/* convert a sid to a DN */ 157 158ADS_STATUS ads_sid_to_dn(ADS_STRUCT *ads, 159 TALLOC_CTX *mem_ctx, 160 const DOM_SID *sid, 161 char **dn) 162{ 163 ADS_STATUS rc; 164 LDAPMessage *msg = NULL; 165 LDAPMessage *entry = NULL; 166 char *ldap_exp; 167 char *sidstr = NULL; 168 int count; 169 char *dn2 = NULL; 170 171 const char *attr[] = { 172 "dn", 173 NULL 174 }; 175 176 if (!(sidstr = sid_binstring(sid))) { 177 DEBUG(1,("ads_sid_to_dn: sid_binstring failed!\n")); 178 rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 179 goto done; 180 } 181 182 if(!(ldap_exp = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr))) { 183 DEBUG(1,("ads_sid_to_dn: talloc_asprintf failed!\n")); 184 rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 185 goto done; 186 } 187 188 rc = ads_search_retry(ads, (void **)&msg, ldap_exp, attr); 189 190 if (!ADS_ERR_OK(rc)) { 191 DEBUG(1,("ads_sid_to_dn ads_search: %s\n", ads_errstr(rc))); 192 goto done; 193 } 194 195 if ((count = ads_count_replies(ads, msg)) != 1) { 196 fstring sid_string; 197 DEBUG(1,("ads_sid_to_dn (sid=%s): Not found (count=%d)\n", 198 sid_to_string(sid_string, sid), count)); 199 rc = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); 200 goto done; 201 } 202 203 entry = ads_first_entry(ads, msg); 204 205 dn2 = ads_get_dn(ads, entry); 206 207 if (!dn2) { 208 rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 209 goto done; 210 } 211 212 *dn = talloc_strdup(mem_ctx, dn2); 213 214 if (!*dn) { 215 ads_memfree(ads, dn2); 216 rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 217 goto done; 218 } 219 220 rc = ADS_ERROR_NT(NT_STATUS_OK); 221 222 DEBUG(3,("ads sid_to_dn mapped %s\n", dn2)); 223 224 SAFE_FREE(dn2); 225done: 226 if (msg) ads_msgfree(ads, msg); 227 if (dn2) ads_memfree(ads, dn2); 228 229 SAFE_FREE(sidstr); 230 231 return rc; 232} 233 234#endif 235