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 * Copyright 2019 Nexenta Systems, Inc. All rights reserved. 25 * Copyright 2022 RackTop Systems, Inc. 26 */ 27 28 /* 29 * LSA lookups 30 */ 31 32 #include <stdio.h> 33 #include <note.h> 34 #include <assert.h> 35 36 #include "idmapd.h" 37 #include "libsmb.h" 38 39 idmap_retcode 40 idmap_lsa_xlate_sid_type(const lsa_account_t *acct, idmap_id_type *ret_type) 41 { 42 switch (acct->a_sidtype) { 43 case SidTypeUser: 44 case SidTypeComputer: 45 case SidTypeDomain: 46 case SidTypeDeletedAccount: 47 case SidTypeUnknown: 48 case SidTypeLabel: 49 *ret_type = IDMAP_USID; 50 return (IDMAP_SUCCESS); 51 case SidTypeGroup: 52 case SidTypeAlias: 53 case SidTypeWellKnownGroup: 54 *ret_type = IDMAP_GSID; 55 return (IDMAP_SUCCESS); 56 case SidTypeNull: 57 case SidTypeInvalid: 58 default: 59 idmapdlog(LOG_WARNING, 60 "LSA lookup: bad type %d for %s@%s", 61 acct->a_sidtype, acct->a_name, acct->a_domain); 62 return (IDMAP_ERR_OTHER); 63 } 64 NOTE(NOTREACHED) 65 } 66 67 /* Given SID, look up name and type */ 68 idmap_retcode 69 lookup_lsa_by_sid( 70 const char *sidprefix, 71 uint32_t rid, 72 char **ret_name, 73 char **ret_domain, 74 idmap_id_type *ret_type) 75 { 76 lsa_account_t acct; 77 char sid[SMB_SID_STRSZ + 1]; 78 idmap_retcode ret; 79 int rc; 80 81 (void) memset(&acct, 0, sizeof (acct)); 82 *ret_name = NULL; 83 *ret_domain = NULL; 84 85 (void) snprintf(sid, sizeof (sid), "%s-%u", sidprefix, rid); 86 87 rc = smb_lookup_lsid(sid, &acct); 88 if (rc != 0) { 89 idmapdlog(LOG_ERR, "Error: SMB lookup SID failed."); 90 idmapdlog(LOG_ERR, 91 "Check SMB service (svc:/network/smb/server)."); 92 idmapdlog(LOG_ERR, 93 "Check connectivity to Active Directory."); 94 95 ret = IDMAP_ERR_OTHER; 96 goto out; 97 } 98 if (acct.a_status == NT_STATUS_NONE_MAPPED) { 99 ret = IDMAP_ERR_NOTFOUND; 100 goto out; 101 } 102 if (acct.a_status != NT_STATUS_SUCCESS) { 103 idmapdlog(LOG_WARNING, 104 "Warning: SMB lookup SID(%s) failed (0x%x)", 105 sid, acct.a_status); 106 /* Fail soft */ 107 ret = IDMAP_ERR_NOTFOUND; 108 goto out; 109 } 110 111 ret = idmap_lsa_xlate_sid_type(&acct, ret_type); 112 if (ret != IDMAP_SUCCESS) 113 goto out; 114 115 *ret_name = strdup(acct.a_name); 116 if (*ret_name == NULL) { 117 ret = IDMAP_ERR_MEMORY; 118 goto out; 119 } 120 121 *ret_domain = strdup(acct.a_domain); 122 if (*ret_domain == NULL) { 123 ret = IDMAP_ERR_MEMORY; 124 goto out; 125 } 126 127 ret = IDMAP_SUCCESS; 128 129 out: 130 if (ret != IDMAP_SUCCESS) { 131 free(*ret_name); 132 *ret_name = NULL; 133 free(*ret_domain); 134 *ret_domain = NULL; 135 } 136 return (ret); 137 } 138 139 /* Given name and optional domain, look up SID, type, and canonical name */ 140 idmap_retcode 141 lookup_lsa_by_name( 142 const char *name, 143 const char *domain, 144 char **ret_sidprefix, 145 uint32_t *ret_rid, 146 char **ret_name, 147 char **ret_domain, 148 idmap_id_type *ret_type) 149 { 150 lsa_account_t acct; 151 char *namedom = NULL; 152 idmap_retcode ret; 153 int rc; 154 155 (void) memset(&acct, 0, sizeof (acct)); 156 *ret_sidprefix = NULL; 157 if (ret_name != NULL) 158 *ret_name = NULL; 159 if (ret_domain != NULL) 160 *ret_domain = NULL; 161 162 if (domain != NULL) 163 (void) asprintf(&namedom, "%s@%s", name, domain); 164 else 165 namedom = strdup(name); 166 if (namedom == NULL) { 167 ret = IDMAP_ERR_MEMORY; 168 goto out; 169 } 170 171 rc = smb_lookup_lname(namedom, SidTypeUnknown, &acct); 172 if (rc != 0) { 173 idmapdlog(LOG_ERR, "Error: SMB lookup name failed."); 174 idmapdlog(LOG_ERR, 175 "Check SMB service (svc:/network/smb/server)."); 176 idmapdlog(LOG_ERR, 177 "Check connectivity to Active Directory."); 178 ret = IDMAP_ERR_OTHER; 179 goto out; 180 } 181 if (acct.a_status == NT_STATUS_NONE_MAPPED) { 182 ret = IDMAP_ERR_NOTFOUND; 183 goto out; 184 } 185 if (acct.a_status != NT_STATUS_SUCCESS) { 186 idmapdlog(LOG_WARNING, 187 "Warning: SMB lookup name(%s) failed (0x%x)", 188 namedom, acct.a_status); 189 /* Fail soft */ 190 ret = IDMAP_ERR_NOTFOUND; 191 goto out; 192 } 193 194 rc = smb_sid_splitstr(acct.a_sid, ret_rid); 195 assert(rc == 0); 196 *ret_sidprefix = strdup(acct.a_sid); 197 if (*ret_sidprefix == NULL) { 198 ret = IDMAP_ERR_MEMORY; 199 goto out; 200 } 201 202 ret = idmap_lsa_xlate_sid_type(&acct, ret_type); 203 if (ret != IDMAP_SUCCESS) 204 goto out; 205 206 if (ret_name != NULL) { 207 *ret_name = strdup(acct.a_name); 208 if (*ret_name == NULL) { 209 ret = IDMAP_ERR_MEMORY; 210 goto out; 211 } 212 } 213 214 if (ret_domain != NULL) { 215 *ret_domain = strdup(acct.a_domain); 216 if (*ret_domain == NULL) { 217 ret = IDMAP_ERR_MEMORY; 218 goto out; 219 } 220 } 221 222 ret = IDMAP_SUCCESS; 223 224 out: 225 free(namedom); 226 if (ret != IDMAP_SUCCESS) { 227 if (ret_name != NULL) { 228 free(*ret_name); 229 *ret_name = NULL; 230 } 231 if (ret_domain != NULL) { 232 free(*ret_domain); 233 *ret_domain = NULL; 234 } 235 free(*ret_sidprefix); 236 *ret_sidprefix = NULL; 237 } 238 return (ret); 239 } 240 241 /* 242 * This exists just so we can avoid exposing all of idmapd to libsmb.h. 243 * Like the above functions, it's a door call over to smbd. 244 */ 245 void 246 notify_dc_changed(void) 247 { 248 int rc; 249 rc = smb_notify_dc_changed(); 250 if (rc != 0) { 251 idmapdlog(LOG_WARNING, 252 "Warning: smb_notify_dc_changed, rc=%d", rc); 253 } 254 } 255