1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 /* 27 * LSA lookups 28 */ 29 30 #include <stdio.h> 31 #include <note.h> 32 #include <assert.h> 33 34 #include "idmapd.h" 35 #include "libsmb.h" 36 37 idmap_retcode 38 idmap_lsa_xlate_sid_type(const lsa_account_t *acct, idmap_id_type *ret_type) 39 { 40 switch (acct->a_sidtype) { 41 case SidTypeUser: 42 case SidTypeComputer: 43 case SidTypeDomain: 44 case SidTypeDeletedAccount: 45 case SidTypeUnknown: 46 case SidTypeLabel: 47 *ret_type = IDMAP_USID; 48 return (IDMAP_SUCCESS); 49 case SidTypeGroup: 50 case SidTypeAlias: 51 case SidTypeWellKnownGroup: 52 *ret_type = IDMAP_GSID; 53 return (IDMAP_SUCCESS); 54 case SidTypeNull: 55 case SidTypeInvalid: 56 default: 57 idmapdlog(LOG_WARNING, 58 "LSA lookup: bad type %d for %s@%s", 59 acct->a_sidtype, acct->a_name, acct->a_domain); 60 return (IDMAP_ERR_OTHER); 61 } 62 NOTE(NOTREACHED) 63 } 64 65 /* Given SID, look up name and type */ 66 idmap_retcode 67 lookup_lsa_by_sid( 68 const char *sidprefix, 69 uint32_t rid, 70 char **ret_name, 71 char **ret_domain, 72 idmap_id_type *ret_type) 73 { 74 lsa_account_t acct; 75 char sid[SMB_SID_STRSZ + 1]; 76 idmap_retcode ret; 77 int rc; 78 79 (void) memset(&acct, 0, sizeof (acct)); 80 *ret_name = NULL; 81 *ret_domain = NULL; 82 83 (void) snprintf(sid, sizeof (sid), "%s-%u", sidprefix, rid); 84 85 rc = smb_lookup_sid(sid, &acct); 86 if (rc != 0) { 87 idmapdlog(LOG_ERR, "Error: smb_lookup_sid failed."); 88 idmapdlog(LOG_ERR, 89 "Check SMB service (svc:/network/smb/server)."); 90 idmapdlog(LOG_ERR, 91 "Check connectivity to Active Directory."); 92 93 ret = IDMAP_ERR_OTHER; 94 goto out; 95 } 96 if (acct.a_status == NT_STATUS_NONE_MAPPED) { 97 ret = IDMAP_ERR_NOTFOUND; 98 goto out; 99 } 100 if (acct.a_status != NT_STATUS_SUCCESS) { 101 idmapdlog(LOG_WARNING, 102 "Warning: smb_lookup_sid(%s) failed (0x%x)", 103 sid, acct.a_status); 104 /* Fail soft */ 105 ret = IDMAP_ERR_NOTFOUND; 106 goto out; 107 } 108 109 ret = idmap_lsa_xlate_sid_type(&acct, ret_type); 110 if (ret != IDMAP_SUCCESS) 111 goto out; 112 113 *ret_name = strdup(acct.a_name); 114 if (*ret_name == NULL) { 115 ret = IDMAP_ERR_MEMORY; 116 goto out; 117 } 118 119 *ret_domain = strdup(acct.a_domain); 120 if (*ret_domain == NULL) { 121 ret = IDMAP_ERR_MEMORY; 122 goto out; 123 } 124 125 ret = IDMAP_SUCCESS; 126 127 out: 128 if (ret != IDMAP_SUCCESS) { 129 free(*ret_name); 130 *ret_name = NULL; 131 free(*ret_domain); 132 *ret_domain = NULL; 133 } 134 return (ret); 135 } 136 137 /* Given name and optional domain, look up SID, type, and canonical name */ 138 idmap_retcode 139 lookup_lsa_by_name( 140 const char *name, 141 const char *domain, 142 char **ret_sidprefix, 143 uint32_t *ret_rid, 144 char **ret_name, 145 char **ret_domain, 146 idmap_id_type *ret_type) 147 { 148 lsa_account_t acct; 149 char *namedom = NULL; 150 idmap_retcode ret; 151 int rc; 152 153 (void) memset(&acct, 0, sizeof (acct)); 154 *ret_sidprefix = NULL; 155 if (ret_name != NULL) 156 *ret_name = NULL; 157 if (ret_domain != NULL) 158 *ret_domain = NULL; 159 160 if (domain != NULL) 161 (void) asprintf(&namedom, "%s@%s", name, domain); 162 else 163 namedom = strdup(name); 164 if (namedom == NULL) { 165 ret = IDMAP_ERR_MEMORY; 166 goto out; 167 } 168 169 rc = smb_lookup_name(namedom, SidTypeUnknown, &acct); 170 if (rc != 0) { 171 idmapdlog(LOG_ERR, "Error: smb_lookup_name failed."); 172 idmapdlog(LOG_ERR, 173 "Check SMB service (svc:/network/smb/server)."); 174 idmapdlog(LOG_ERR, 175 "Check connectivity to Active Directory."); 176 ret = IDMAP_ERR_OTHER; 177 goto out; 178 } 179 if (acct.a_status == NT_STATUS_NONE_MAPPED) { 180 ret = IDMAP_ERR_NOTFOUND; 181 goto out; 182 } 183 if (acct.a_status != NT_STATUS_SUCCESS) { 184 idmapdlog(LOG_WARNING, 185 "Warning: smb_lookup_name(%s) failed (0x%x)", 186 namedom, acct.a_status); 187 /* Fail soft */ 188 ret = IDMAP_ERR_NOTFOUND; 189 goto out; 190 } 191 192 rc = smb_sid_splitstr(acct.a_sid, ret_rid); 193 assert(rc == 0); 194 *ret_sidprefix = strdup(acct.a_sid); 195 if (*ret_sidprefix == NULL) { 196 ret = IDMAP_ERR_MEMORY; 197 goto out; 198 } 199 200 ret = idmap_lsa_xlate_sid_type(&acct, ret_type); 201 if (ret != IDMAP_SUCCESS) 202 goto out; 203 204 if (ret_name != NULL) { 205 *ret_name = strdup(acct.a_name); 206 if (*ret_name == NULL) { 207 ret = IDMAP_ERR_MEMORY; 208 goto out; 209 } 210 } 211 212 if (ret_domain != NULL) { 213 *ret_domain = strdup(acct.a_domain); 214 if (*ret_domain == NULL) { 215 ret = IDMAP_ERR_MEMORY; 216 goto out; 217 } 218 } 219 220 ret = IDMAP_SUCCESS; 221 222 out: 223 free(namedom); 224 if (ret != IDMAP_SUCCESS) { 225 if (ret_name != NULL) { 226 free(*ret_name); 227 *ret_name = NULL; 228 } 229 if (ret_domain != NULL) { 230 free(*ret_domain); 231 *ret_domain = NULL; 232 } 233 free(*ret_sidprefix); 234 *ret_sidprefix = NULL; 235 } 236 return (ret); 237 } 238