1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21148c5f43SAlan Wright 22da6c28aaSamw /* 23148c5f43SAlan Wright * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 24*b3700b07SGordon Ross * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 25da6c28aaSamw */ 26da6c28aaSamw 27da6c28aaSamw /* 28da6c28aaSamw * This module provides the high level interface to the LSA RPC functions. 29da6c28aaSamw */ 30da6c28aaSamw 31da6c28aaSamw #include <strings.h> 32da6c28aaSamw #include <unistd.h> 33da6c28aaSamw 34da6c28aaSamw #include <smbsrv/libsmb.h> 35da6c28aaSamw #include <smbsrv/libmlsvc.h> 36da6c28aaSamw #include <smbsrv/smbinfo.h> 37da6c28aaSamw #include <smbsrv/smb_token.h> 38da6c28aaSamw 3989dc44ceSjose borrego #include <lsalib.h> 40dc20a302Sas200622 417f667e74Sjose borrego static uint32_t lsa_lookup_name_builtin(char *, char *, smb_account_t *); 427f667e74Sjose borrego static uint32_t lsa_lookup_name_domain(char *, smb_account_t *); 43dc20a302Sas200622 447f667e74Sjose borrego static uint32_t lsa_lookup_sid_builtin(smb_sid_t *, smb_account_t *); 457f667e74Sjose borrego static uint32_t lsa_lookup_sid_domain(smb_sid_t *, smb_account_t *); 46dc20a302Sas200622 47*b3700b07SGordon Ross static uint32_t lsa_list_accounts(mlsvc_handle_t *); 48*b3700b07SGordon Ross static uint32_t lsa_map_status(uint32_t); 49da6c28aaSamw 50da6c28aaSamw /* 51dc20a302Sas200622 * Lookup the given account and returns the account information 527f667e74Sjose borrego * in the passed smb_account_t structure. 5389dc44ceSjose borrego * 5489dc44ceSjose borrego * The lookup is performed in the following order: 5589dc44ceSjose borrego * well known accounts 5689dc44ceSjose borrego * local accounts 5789dc44ceSjose borrego * domain accounts 5889dc44ceSjose borrego * 5989dc44ceSjose borrego * If it's established the given account is well know or local 6089dc44ceSjose borrego * but the lookup fails for some reason, the next step(s) won't be 6189dc44ceSjose borrego * performed. 62dc20a302Sas200622 * 63dc20a302Sas200622 * If the name is a domain account, it may refer to a user, group or 64dc20a302Sas200622 * alias. If it is a local account, its type should be specified 65dc20a302Sas200622 * in the sid_type parameter. In case the account type is unknown 66dc20a302Sas200622 * sid_type should be set to SidTypeUnknown. 67dc20a302Sas200622 * 6889dc44ceSjose borrego * account argument could be either [domain\]name or [domain/]name. 6989dc44ceSjose borrego * 7089dc44ceSjose borrego * Return status: 7189dc44ceSjose borrego * 7289dc44ceSjose borrego * NT_STATUS_SUCCESS Account is successfully translated 7389dc44ceSjose borrego * NT_STATUS_NONE_MAPPED Couldn't translate the account 74dc20a302Sas200622 */ 75dc20a302Sas200622 uint32_t 767f667e74Sjose borrego lsa_lookup_name(char *account, uint16_t type, smb_account_t *info) 77dc20a302Sas200622 { 7889dc44ceSjose borrego char nambuf[SMB_USERNAME_MAXLEN]; 7989dc44ceSjose borrego char dombuf[SMB_PI_MAX_DOMAIN]; 8089dc44ceSjose borrego char *name, *domain; 8189dc44ceSjose borrego uint32_t status; 8289dc44ceSjose borrego char *slash; 83dc20a302Sas200622 8489dc44ceSjose borrego (void) strsubst(account, '/', '\\'); 8589dc44ceSjose borrego (void) strcanon(account, "\\"); 8689dc44ceSjose borrego /* \john -> john */ 8789dc44ceSjose borrego account += strspn(account, "\\"); 8889dc44ceSjose borrego 8989dc44ceSjose borrego if ((slash = strchr(account, '\\')) != NULL) { 9089dc44ceSjose borrego *slash = '\0'; 9189dc44ceSjose borrego (void) strlcpy(dombuf, account, sizeof (dombuf)); 9289dc44ceSjose borrego (void) strlcpy(nambuf, slash + 1, sizeof (nambuf)); 9389dc44ceSjose borrego *slash = '\\'; 9489dc44ceSjose borrego name = nambuf; 9589dc44ceSjose borrego domain = dombuf; 96dc20a302Sas200622 } else { 97dc20a302Sas200622 name = account; 98dc20a302Sas200622 domain = NULL; 99dc20a302Sas200622 } 100dc20a302Sas200622 10189dc44ceSjose borrego status = lsa_lookup_name_builtin(domain, name, info); 10289dc44ceSjose borrego if (status == NT_STATUS_NOT_FOUND) { 1037f667e74Sjose borrego status = smb_sam_lookup_name(domain, name, type, info); 10489dc44ceSjose borrego if (status == NT_STATUS_SUCCESS) 105dc20a302Sas200622 return (status); 106dc20a302Sas200622 10789dc44ceSjose borrego if ((domain == NULL) || (status == NT_STATUS_NOT_FOUND)) 10889dc44ceSjose borrego status = lsa_lookup_name_domain(account, info); 109dc20a302Sas200622 } 110dc20a302Sas200622 11189dc44ceSjose borrego return ((status == NT_STATUS_SUCCESS) ? status : NT_STATUS_NONE_MAPPED); 112dc20a302Sas200622 } 113dc20a302Sas200622 114dc20a302Sas200622 uint32_t 1157f667e74Sjose borrego lsa_lookup_sid(smb_sid_t *sid, smb_account_t *info) 116dc20a302Sas200622 { 1177f667e74Sjose borrego uint32_t status; 1187f667e74Sjose borrego 1196537f381Sas200622 if (!smb_sid_isvalid(sid)) 120dc20a302Sas200622 return (NT_STATUS_INVALID_SID); 121dc20a302Sas200622 1227f667e74Sjose borrego status = lsa_lookup_sid_builtin(sid, info); 1237f667e74Sjose borrego if (status == NT_STATUS_NOT_FOUND) { 1247f667e74Sjose borrego status = smb_sam_lookup_sid(sid, info); 1257f667e74Sjose borrego if (status == NT_STATUS_NOT_FOUND) 1267f667e74Sjose borrego status = lsa_lookup_sid_domain(sid, info); 1277f667e74Sjose borrego } 128dc20a302Sas200622 1297f667e74Sjose borrego return ((status == NT_STATUS_SUCCESS) ? status : NT_STATUS_NONE_MAPPED); 130dc20a302Sas200622 } 131dc20a302Sas200622 132dc20a302Sas200622 /* 133da6c28aaSamw * Obtains the primary domain SID and name from the specified server 13429bd2886SAlan Wright * (domain controller). 135da6c28aaSamw * 1368d7e4166Sjose borrego * The requested information will be returned via 'info' argument. 1378d7e4166Sjose borrego * 138*b3700b07SGordon Ross * Returns NT status codes. (Raw, not LSA-ized) 139da6c28aaSamw */ 140da6c28aaSamw DWORD 14129bd2886SAlan Wright lsa_query_primary_domain_info(char *server, char *domain, 142a0aa776eSAlan Wright smb_domain_t *info) 143da6c28aaSamw { 144da6c28aaSamw mlsvc_handle_t domain_handle; 145a0aa776eSAlan Wright char user[SMB_USERNAME_MAXLEN]; 146*b3700b07SGordon Ross DWORD status; 147a0aa776eSAlan Wright 148a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 149da6c28aaSamw 150*b3700b07SGordon Ross status = lsar_open(server, domain, user, &domain_handle); 151*b3700b07SGordon Ross if (status != 0) 152*b3700b07SGordon Ross return (status); 153da6c28aaSamw 154da6c28aaSamw status = lsar_query_info_policy(&domain_handle, 1558d7e4166Sjose borrego MSLSA_POLICY_PRIMARY_DOMAIN_INFO, info); 156da6c28aaSamw 157da6c28aaSamw (void) lsar_close(&domain_handle); 158da6c28aaSamw return (status); 159da6c28aaSamw } 160da6c28aaSamw 161da6c28aaSamw /* 162da6c28aaSamw * Obtains the account domain SID and name from the current server 16329bd2886SAlan Wright * (domain controller). 164da6c28aaSamw * 1658d7e4166Sjose borrego * The requested information will be returned via 'info' argument. 1668d7e4166Sjose borrego * 167*b3700b07SGordon Ross * Returns NT status codes. (Raw, not LSA-ized) 168da6c28aaSamw */ 169da6c28aaSamw DWORD 17029bd2886SAlan Wright lsa_query_account_domain_info(char *server, char *domain, 171a0aa776eSAlan Wright smb_domain_t *info) 172da6c28aaSamw { 173da6c28aaSamw mlsvc_handle_t domain_handle; 174a0aa776eSAlan Wright char user[SMB_USERNAME_MAXLEN]; 175*b3700b07SGordon Ross DWORD status; 176a0aa776eSAlan Wright 177a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 178da6c28aaSamw 179*b3700b07SGordon Ross status = lsar_open(server, domain, user, &domain_handle); 180*b3700b07SGordon Ross if (status != 0) 181*b3700b07SGordon Ross return (status); 182da6c28aaSamw 183da6c28aaSamw status = lsar_query_info_policy(&domain_handle, 1848d7e4166Sjose borrego MSLSA_POLICY_ACCOUNT_DOMAIN_INFO, info); 1858d7e4166Sjose borrego 1868d7e4166Sjose borrego (void) lsar_close(&domain_handle); 1878d7e4166Sjose borrego return (status); 1888d7e4166Sjose borrego } 1898d7e4166Sjose borrego 1908d7e4166Sjose borrego /* 1918d7e4166Sjose borrego * lsa_query_dns_domain_info 1928d7e4166Sjose borrego * 1938d7e4166Sjose borrego * Obtains the DNS domain info from the specified server 1948d7e4166Sjose borrego * (domain controller). 1958d7e4166Sjose borrego * 1968d7e4166Sjose borrego * The requested information will be returned via 'info' argument. 1978d7e4166Sjose borrego * 198*b3700b07SGordon Ross * Returns NT status codes. (Raw, not LSA-ized) 1998d7e4166Sjose borrego */ 2008d7e4166Sjose borrego DWORD 201a0aa776eSAlan Wright lsa_query_dns_domain_info(char *server, char *domain, smb_domain_t *info) 2028d7e4166Sjose borrego { 2038d7e4166Sjose borrego mlsvc_handle_t domain_handle; 204a0aa776eSAlan Wright char user[SMB_USERNAME_MAXLEN]; 205*b3700b07SGordon Ross DWORD status; 206a0aa776eSAlan Wright 207a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 2088d7e4166Sjose borrego 209*b3700b07SGordon Ross status = lsar_open(server, domain, user, &domain_handle); 210*b3700b07SGordon Ross if (status != 0) 211*b3700b07SGordon Ross return (status); 2128d7e4166Sjose borrego 2138d7e4166Sjose borrego status = lsar_query_info_policy(&domain_handle, 2148d7e4166Sjose borrego MSLSA_POLICY_DNS_DOMAIN_INFO, info); 215da6c28aaSamw 216da6c28aaSamw (void) lsar_close(&domain_handle); 217da6c28aaSamw return (status); 218da6c28aaSamw } 219da6c28aaSamw 220da6c28aaSamw /* 22129bd2886SAlan Wright * Enumerate the trusted domains of primary domain. 22229bd2886SAlan Wright * This is the basic enumaration call which only returns the 22329bd2886SAlan Wright * NetBIOS name of the domain and its SID. 224da6c28aaSamw * 2258d7e4166Sjose borrego * The requested information will be returned via 'info' argument. 2268d7e4166Sjose borrego * 227*b3700b07SGordon Ross * Returns NT status codes. (Raw, not LSA-ized) 228da6c28aaSamw */ 229da6c28aaSamw DWORD 23029bd2886SAlan Wright lsa_enum_trusted_domains(char *server, char *domain, 23129bd2886SAlan Wright smb_trusted_domains_t *info) 232da6c28aaSamw { 233da6c28aaSamw mlsvc_handle_t domain_handle; 234*b3700b07SGordon Ross char user[SMB_USERNAME_MAXLEN]; 235da6c28aaSamw DWORD enum_context; 236da6c28aaSamw DWORD status; 237a0aa776eSAlan Wright 238a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 239da6c28aaSamw 240*b3700b07SGordon Ross status = lsar_open(server, domain, user, &domain_handle); 241*b3700b07SGordon Ross if (status != 0) 242*b3700b07SGordon Ross return (status); 243da6c28aaSamw 244da6c28aaSamw enum_context = 0; 245da6c28aaSamw 2468d7e4166Sjose borrego status = lsar_enum_trusted_domains(&domain_handle, &enum_context, info); 247148c5f43SAlan Wright if (status == NT_STATUS_NO_MORE_ENTRIES) { 248da6c28aaSamw /* 249148c5f43SAlan Wright * STATUS_NO_MORE_ENTRIES indicates that we 250da6c28aaSamw * have all of the available information. 251da6c28aaSamw */ 252da6c28aaSamw status = NT_STATUS_SUCCESS; 253da6c28aaSamw } 254da6c28aaSamw 255da6c28aaSamw (void) lsar_close(&domain_handle); 256da6c28aaSamw return (status); 257da6c28aaSamw } 258da6c28aaSamw 259da6c28aaSamw /* 26029bd2886SAlan Wright * Enumerate the trusted domains of the primary domain. 26129bd2886SAlan Wright * This is the extended enumaration call which besides 26229bd2886SAlan Wright * NetBIOS name of the domain and its SID, it will return 26329bd2886SAlan Wright * the FQDN plus some trust information which is not used. 26429bd2886SAlan Wright * 26529bd2886SAlan Wright * The requested information will be returned via 'info' argument. 26629bd2886SAlan Wright * 267*b3700b07SGordon Ross * Returns NT status codes. (Raw, not LSA-ized) 2688d7e4166Sjose borrego */ 26929bd2886SAlan Wright DWORD 27029bd2886SAlan Wright lsa_enum_trusted_domains_ex(char *server, char *domain, 27129bd2886SAlan Wright smb_trusted_domains_t *info) 2728d7e4166Sjose borrego { 27329bd2886SAlan Wright mlsvc_handle_t domain_handle; 274*b3700b07SGordon Ross char user[SMB_USERNAME_MAXLEN]; 27529bd2886SAlan Wright DWORD enum_context; 27629bd2886SAlan Wright DWORD status; 277a0aa776eSAlan Wright 278a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 2798d7e4166Sjose borrego 280*b3700b07SGordon Ross status = lsar_open(server, domain, user, &domain_handle); 281*b3700b07SGordon Ross if (status != 0) 282*b3700b07SGordon Ross return (status); 2838d7e4166Sjose borrego 28429bd2886SAlan Wright enum_context = 0; 2858d7e4166Sjose borrego 28629bd2886SAlan Wright status = lsar_enum_trusted_domains_ex(&domain_handle, &enum_context, 28729bd2886SAlan Wright info); 288148c5f43SAlan Wright if (status == NT_STATUS_NO_MORE_ENTRIES) { 28929bd2886SAlan Wright /* 290148c5f43SAlan Wright * STATUS_NO_MORE_ENTRIES indicates that we 29129bd2886SAlan Wright * have all of the available information. 29229bd2886SAlan Wright */ 29329bd2886SAlan Wright status = NT_STATUS_SUCCESS; 2948d7e4166Sjose borrego } 29529bd2886SAlan Wright 29629bd2886SAlan Wright (void) lsar_close(&domain_handle); 29729bd2886SAlan Wright return (status); 2988d7e4166Sjose borrego } 2998d7e4166Sjose borrego 3008d7e4166Sjose borrego /* 30189dc44ceSjose borrego * Lookup well known accounts table 302dc20a302Sas200622 * 30389dc44ceSjose borrego * Return status: 30489dc44ceSjose borrego * 30589dc44ceSjose borrego * NT_STATUS_SUCCESS Account is translated successfully 30689dc44ceSjose borrego * NT_STATUS_NOT_FOUND This is not a well known account 30789dc44ceSjose borrego * NT_STATUS_NONE_MAPPED Account is found but domains don't match 30889dc44ceSjose borrego * NT_STATUS_NO_MEMORY Memory shortage 30989dc44ceSjose borrego * NT_STATUS_INTERNAL_ERROR Internal error/unexpected failure 310dc20a302Sas200622 */ 311dc20a302Sas200622 static uint32_t 3127f667e74Sjose borrego lsa_lookup_name_builtin(char *domain, char *name, smb_account_t *info) 313dc20a302Sas200622 { 31489dc44ceSjose borrego smb_wka_t *wka; 31589dc44ceSjose borrego char *wkadom; 316dc20a302Sas200622 3177f667e74Sjose borrego bzero(info, sizeof (smb_account_t)); 3187f667e74Sjose borrego 3197f667e74Sjose borrego if ((wka = smb_wka_lookup_name(name)) == NULL) 32089dc44ceSjose borrego return (NT_STATUS_NOT_FOUND); 321dc20a302Sas200622 32289dc44ceSjose borrego if ((wkadom = smb_wka_get_domain(wka->wka_domidx)) == NULL) 323dc20a302Sas200622 return (NT_STATUS_INTERNAL_ERROR); 324dc20a302Sas200622 325bbf6f00cSJordan Brown if ((domain != NULL) && (smb_strcasecmp(domain, wkadom, 0) != 0)) 32689dc44ceSjose borrego return (NT_STATUS_NONE_MAPPED); 32789dc44ceSjose borrego 3287f667e74Sjose borrego info->a_name = strdup(name); 3297f667e74Sjose borrego info->a_sid = smb_sid_dup(wka->wka_binsid); 3307f667e74Sjose borrego info->a_domain = strdup(wkadom); 3317f667e74Sjose borrego info->a_domsid = smb_sid_split(wka->wka_binsid, &info->a_rid); 3327f667e74Sjose borrego info->a_type = wka->wka_type; 33389dc44ceSjose borrego 3347f667e74Sjose borrego if (!smb_account_validate(info)) { 3357f667e74Sjose borrego smb_account_free(info); 33689dc44ceSjose borrego return (NT_STATUS_NO_MEMORY); 337dc20a302Sas200622 } 338dc20a302Sas200622 339dc20a302Sas200622 return (NT_STATUS_SUCCESS); 340dc20a302Sas200622 } 341dc20a302Sas200622 342dc20a302Sas200622 /* 343*b3700b07SGordon Ross * Lookup a domain account by its name. 344dc20a302Sas200622 * 34589dc44ceSjose borrego * The information is returned in the user_info structure. 34689dc44ceSjose borrego * The caller is responsible for allocating and releasing 34789dc44ceSjose borrego * this structure. 348*b3700b07SGordon Ross * 349*b3700b07SGordon Ross * Returns NT status codes. (LSA-ized) 350dc20a302Sas200622 */ 351dc20a302Sas200622 static uint32_t 3527f667e74Sjose borrego lsa_lookup_name_domain(char *account_name, smb_account_t *info) 353dc20a302Sas200622 { 354dc20a302Sas200622 mlsvc_handle_t domain_handle; 355a0aa776eSAlan Wright smb_domainex_t dinfo; 356a0aa776eSAlan Wright char user[SMB_USERNAME_MAXLEN]; 357*b3700b07SGordon Ross uint32_t status; 358a0aa776eSAlan Wright 359a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 360dc20a302Sas200622 36189dc44ceSjose borrego if (!smb_domain_getinfo(&dinfo)) 36289dc44ceSjose borrego return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 36389dc44ceSjose borrego 364*b3700b07SGordon Ross status = lsar_open(dinfo.d_dci.dc_name, dinfo.d_primary.di_nbname, 365*b3700b07SGordon Ross user, &domain_handle); 366*b3700b07SGordon Ross if (status != 0) 367*b3700b07SGordon Ross return (lsa_map_status(status)); 368dc20a302Sas200622 3697f667e74Sjose borrego status = lsar_lookup_names(&domain_handle, account_name, info); 370dc20a302Sas200622 371dc20a302Sas200622 (void) lsar_close(&domain_handle); 372dc20a302Sas200622 return (status); 373dc20a302Sas200622 } 374dc20a302Sas200622 375dc20a302Sas200622 /* 376da6c28aaSamw * lsa_lookup_privs 377da6c28aaSamw * 378da6c28aaSamw * Request the privileges associated with the specified account. In 379da6c28aaSamw * order to get the privileges, we first have to lookup the name on 380da6c28aaSamw * the specified domain controller and obtain the appropriate SID. 381da6c28aaSamw * The SID can then be used to open the account and obtain the 382da6c28aaSamw * account privileges. The results from both the name lookup and the 383da6c28aaSamw * privileges are returned in the user_info structure. The caller is 384da6c28aaSamw * responsible for allocating and releasing this structure. 385da6c28aaSamw * 386*b3700b07SGordon Ross * Returns NT status codes. (LSA-ized) 387da6c28aaSamw */ 388da6c28aaSamw /*ARGSUSED*/ 389*b3700b07SGordon Ross DWORD 3907f667e74Sjose borrego lsa_lookup_privs(char *account_name, char *target_name, smb_account_t *ainfo) 391da6c28aaSamw { 392da6c28aaSamw mlsvc_handle_t domain_handle; 393a0aa776eSAlan Wright smb_domainex_t dinfo; 394a0aa776eSAlan Wright char user[SMB_USERNAME_MAXLEN]; 395*b3700b07SGordon Ross DWORD status; 396a0aa776eSAlan Wright 397a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 398da6c28aaSamw 3998d7e4166Sjose borrego if (!smb_domain_getinfo(&dinfo)) 400*b3700b07SGordon Ross return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 4018d7e4166Sjose borrego 402*b3700b07SGordon Ross status = lsar_open(dinfo.d_dci.dc_name, dinfo.d_primary.di_nbname, 403*b3700b07SGordon Ross user, &domain_handle); 404*b3700b07SGordon Ross if (status != 0) 405*b3700b07SGordon Ross return (lsa_map_status(status)); 406da6c28aaSamw 407*b3700b07SGordon Ross status = lsa_list_accounts(&domain_handle); 408da6c28aaSamw (void) lsar_close(&domain_handle); 409*b3700b07SGordon Ross return (status); 410da6c28aaSamw } 411da6c28aaSamw 412da6c28aaSamw /* 413da6c28aaSamw * lsa_list_privs 414da6c28aaSamw * 415da6c28aaSamw * List the privileges supported by the specified server. 416da6c28aaSamw * This function is only intended for diagnostics. 417da6c28aaSamw * 418*b3700b07SGordon Ross * Returns NT status codes. (LSA-ized) 419da6c28aaSamw */ 420da6c28aaSamw DWORD 421da6c28aaSamw lsa_list_privs(char *server, char *domain) 422da6c28aaSamw { 423da6c28aaSamw static char name[128]; 424da6c28aaSamw static struct ms_luid luid; 425da6c28aaSamw mlsvc_handle_t domain_handle; 426*b3700b07SGordon Ross char user[SMB_USERNAME_MAXLEN]; 427*b3700b07SGordon Ross DWORD status; 428da6c28aaSamw int rc; 429da6c28aaSamw int i; 430a0aa776eSAlan Wright 431a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 432da6c28aaSamw 433*b3700b07SGordon Ross status = lsar_open(server, domain, user, &domain_handle); 434*b3700b07SGordon Ross if (status != 0) 435*b3700b07SGordon Ross return (lsa_map_status(status)); 436da6c28aaSamw 437da6c28aaSamw for (i = 0; i < 30; ++i) { 438da6c28aaSamw luid.low_part = i; 439da6c28aaSamw rc = lsar_lookup_priv_name(&domain_handle, &luid, name, 128); 440da6c28aaSamw if (rc != 0) 441da6c28aaSamw continue; 442da6c28aaSamw 443da6c28aaSamw (void) lsar_lookup_priv_value(&domain_handle, name, &luid); 444da6c28aaSamw (void) lsar_lookup_priv_display_name(&domain_handle, name, 445da6c28aaSamw name, 128); 446da6c28aaSamw } 447da6c28aaSamw 448da6c28aaSamw (void) lsar_close(&domain_handle); 449da6c28aaSamw return (NT_STATUS_SUCCESS); 450da6c28aaSamw } 451da6c28aaSamw 452da6c28aaSamw /* 453da6c28aaSamw * lsa_list_accounts 454da6c28aaSamw * 455da6c28aaSamw * This function can be used to list the accounts in the specified 456da6c28aaSamw * domain. For now the SIDs are just listed in the system log. 457da6c28aaSamw * 458*b3700b07SGordon Ross * Returns NT status 459da6c28aaSamw */ 460*b3700b07SGordon Ross static DWORD 461da6c28aaSamw lsa_list_accounts(mlsvc_handle_t *domain_handle) 462da6c28aaSamw { 463da6c28aaSamw mlsvc_handle_t account_handle; 464da6c28aaSamw struct mslsa_EnumAccountBuf accounts; 465da6c28aaSamw struct mslsa_sid *sid; 4667f667e74Sjose borrego smb_account_t ainfo; 467da6c28aaSamw DWORD enum_context = 0; 468*b3700b07SGordon Ross DWORD status; 469da6c28aaSamw int i; 470da6c28aaSamw 471da6c28aaSamw bzero(&accounts, sizeof (struct mslsa_EnumAccountBuf)); 472da6c28aaSamw 473da6c28aaSamw do { 474*b3700b07SGordon Ross status = lsar_enum_accounts(domain_handle, &enum_context, 475da6c28aaSamw &accounts); 476*b3700b07SGordon Ross if (status != 0) 477*b3700b07SGordon Ross return (status); 478da6c28aaSamw 479da6c28aaSamw for (i = 0; i < accounts.entries_read; ++i) { 480da6c28aaSamw sid = accounts.info[i].sid; 481da6c28aaSamw 482da6c28aaSamw if (lsar_open_account(domain_handle, sid, 483da6c28aaSamw &account_handle) == 0) { 484da6c28aaSamw (void) lsar_enum_privs_account(&account_handle, 4857f667e74Sjose borrego &ainfo); 486da6c28aaSamw (void) lsar_close(&account_handle); 487da6c28aaSamw } 488da6c28aaSamw 489da6c28aaSamw free(accounts.info[i].sid); 490da6c28aaSamw } 491da6c28aaSamw 492da6c28aaSamw if (accounts.info) 493da6c28aaSamw free(accounts.info); 494*b3700b07SGordon Ross } while (status == 0 && accounts.entries_read != 0); 495da6c28aaSamw 496da6c28aaSamw return (0); 497da6c28aaSamw } 498dc20a302Sas200622 499dc20a302Sas200622 /* 5007f667e74Sjose borrego * Lookup well known accounts table for the given SID 501dc20a302Sas200622 * 5027f667e74Sjose borrego * Return status: 5037f667e74Sjose borrego * 5047f667e74Sjose borrego * NT_STATUS_SUCCESS Account is translated successfully 5057f667e74Sjose borrego * NT_STATUS_NOT_FOUND This is not a well known account 5067f667e74Sjose borrego * NT_STATUS_NO_MEMORY Memory shortage 5077f667e74Sjose borrego * NT_STATUS_INTERNAL_ERROR Internal error/unexpected failure 508dc20a302Sas200622 */ 509dc20a302Sas200622 static uint32_t 5107f667e74Sjose borrego lsa_lookup_sid_builtin(smb_sid_t *sid, smb_account_t *ainfo) 511dc20a302Sas200622 { 5127f667e74Sjose borrego smb_wka_t *wka; 5137f667e74Sjose borrego char *wkadom; 514dc20a302Sas200622 5157f667e74Sjose borrego bzero(ainfo, sizeof (smb_account_t)); 516dc20a302Sas200622 5177f667e74Sjose borrego if ((wka = smb_wka_lookup_sid(sid)) == NULL) 5187f667e74Sjose borrego return (NT_STATUS_NOT_FOUND); 519dc20a302Sas200622 5207f667e74Sjose borrego if ((wkadom = smb_wka_get_domain(wka->wka_domidx)) == NULL) 521dc20a302Sas200622 return (NT_STATUS_INTERNAL_ERROR); 5227f667e74Sjose borrego 5237f667e74Sjose borrego ainfo->a_name = strdup(wka->wka_name); 5247f667e74Sjose borrego ainfo->a_sid = smb_sid_dup(wka->wka_binsid); 5257f667e74Sjose borrego ainfo->a_domain = strdup(wkadom); 5267f667e74Sjose borrego ainfo->a_domsid = smb_sid_split(ainfo->a_sid, &ainfo->a_rid); 5277f667e74Sjose borrego ainfo->a_type = wka->wka_type; 5287f667e74Sjose borrego 5297f667e74Sjose borrego if (!smb_account_validate(ainfo)) { 5307f667e74Sjose borrego smb_account_free(ainfo); 531dc20a302Sas200622 return (NT_STATUS_NO_MEMORY); 5327f667e74Sjose borrego } 533dc20a302Sas200622 534dc20a302Sas200622 return (NT_STATUS_SUCCESS); 535dc20a302Sas200622 } 536dc20a302Sas200622 537*b3700b07SGordon Ross /* 538*b3700b07SGordon Ross * Lookup a domain account by its SID. 539*b3700b07SGordon Ross * 540*b3700b07SGordon Ross * The information is returned in the user_info structure. 541*b3700b07SGordon Ross * The caller is responsible for allocating and releasing 542*b3700b07SGordon Ross * this structure. 543*b3700b07SGordon Ross * 544*b3700b07SGordon Ross * Returns NT status codes. (LSA-ized) 545*b3700b07SGordon Ross */ 546dc20a302Sas200622 static uint32_t 5477f667e74Sjose borrego lsa_lookup_sid_domain(smb_sid_t *sid, smb_account_t *ainfo) 548dc20a302Sas200622 { 549dc20a302Sas200622 mlsvc_handle_t domain_handle; 550a0aa776eSAlan Wright smb_domainex_t dinfo; 551a0aa776eSAlan Wright char user[SMB_USERNAME_MAXLEN]; 552*b3700b07SGordon Ross uint32_t status; 553a0aa776eSAlan Wright 554a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 555dc20a302Sas200622 5568d7e4166Sjose borrego if (!smb_domain_getinfo(&dinfo)) 5578d7e4166Sjose borrego return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 5588d7e4166Sjose borrego 559*b3700b07SGordon Ross status = lsar_open(dinfo.d_dci.dc_name, dinfo.d_primary.di_nbname, 560*b3700b07SGordon Ross user, &domain_handle); 561*b3700b07SGordon Ross if (status != 0) 562*b3700b07SGordon Ross return (lsa_map_status(status)); 563dc20a302Sas200622 564fe1c642dSBill Krier status = lsar_lookup_sids(&domain_handle, sid, ainfo); 565dc20a302Sas200622 566dc20a302Sas200622 (void) lsar_close(&domain_handle); 567dc20a302Sas200622 return (status); 568dc20a302Sas200622 } 569*b3700b07SGordon Ross 570*b3700b07SGordon Ross /* 571*b3700b07SGordon Ross * Most functions that call the local security authority expect 572*b3700b07SGordon Ross * only a limited set of status returns. This function maps the 573*b3700b07SGordon Ross * status we get from talking to our domain controller into one 574*b3700b07SGordon Ross * that LSA functions can return. Most common errors become: 575*b3700b07SGordon Ross * NT_STATUS_CANT_ACCESS_DOMAIN_INFO (when no DC etc.) 576*b3700b07SGordon Ross */ 577*b3700b07SGordon Ross static uint32_t 578*b3700b07SGordon Ross lsa_map_status(uint32_t status) 579*b3700b07SGordon Ross { 580*b3700b07SGordon Ross switch (status) { 581*b3700b07SGordon Ross case NT_STATUS_SUCCESS: 582*b3700b07SGordon Ross break; 583*b3700b07SGordon Ross case NT_STATUS_INVALID_PARAMETER: /* rpc bind */ 584*b3700b07SGordon Ross break; 585*b3700b07SGordon Ross case NT_STATUS_NO_MEMORY: 586*b3700b07SGordon Ross break; 587*b3700b07SGordon Ross case NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND: 588*b3700b07SGordon Ross case NT_STATUS_BAD_NETWORK_PATH: /* get server addr */ 589*b3700b07SGordon Ross case NT_STATUS_NETWORK_ACCESS_DENIED: /* authentication */ 590*b3700b07SGordon Ross case NT_STATUS_BAD_NETWORK_NAME: /* tree connect */ 591*b3700b07SGordon Ross case NT_STATUS_ACCESS_DENIED: /* open pipe */ 592*b3700b07SGordon Ross status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 593*b3700b07SGordon Ross break; 594*b3700b07SGordon Ross default: 595*b3700b07SGordon Ross status = NT_STATUS_UNSUCCESSFUL; 596*b3700b07SGordon Ross break; 597*b3700b07SGordon Ross } 598*b3700b07SGordon Ross return (status); 599*b3700b07SGordon Ross } 600