1*11337SWilliam.Krier@Sun.COM /* 2*11337SWilliam.Krier@Sun.COM * CDDL HEADER START 3*11337SWilliam.Krier@Sun.COM * 4*11337SWilliam.Krier@Sun.COM * The contents of this file are subject to the terms of the 5*11337SWilliam.Krier@Sun.COM * Common Development and Distribution License (the "License"). 6*11337SWilliam.Krier@Sun.COM * You may not use this file except in compliance with the License. 7*11337SWilliam.Krier@Sun.COM * 8*11337SWilliam.Krier@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*11337SWilliam.Krier@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*11337SWilliam.Krier@Sun.COM * See the License for the specific language governing permissions 11*11337SWilliam.Krier@Sun.COM * and limitations under the License. 12*11337SWilliam.Krier@Sun.COM * 13*11337SWilliam.Krier@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*11337SWilliam.Krier@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*11337SWilliam.Krier@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*11337SWilliam.Krier@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*11337SWilliam.Krier@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*11337SWilliam.Krier@Sun.COM * 19*11337SWilliam.Krier@Sun.COM * CDDL HEADER END 20*11337SWilliam.Krier@Sun.COM */ 21*11337SWilliam.Krier@Sun.COM /* 22*11337SWilliam.Krier@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*11337SWilliam.Krier@Sun.COM * Use is subject to license terms. 24*11337SWilliam.Krier@Sun.COM */ 25*11337SWilliam.Krier@Sun.COM 26*11337SWilliam.Krier@Sun.COM /* 27*11337SWilliam.Krier@Sun.COM * Local Security Authority RPC (LSAR) client-side interface. 28*11337SWilliam.Krier@Sun.COM */ 29*11337SWilliam.Krier@Sun.COM 30*11337SWilliam.Krier@Sun.COM #include <sys/errno.h> 31*11337SWilliam.Krier@Sun.COM #include <stdio.h> 32*11337SWilliam.Krier@Sun.COM #include <stdlib.h> 33*11337SWilliam.Krier@Sun.COM #include <strings.h> 34*11337SWilliam.Krier@Sun.COM 35*11337SWilliam.Krier@Sun.COM #include <smbsrv/libsmb.h> 36*11337SWilliam.Krier@Sun.COM #include <smbsrv/libmlsvc.h> 37*11337SWilliam.Krier@Sun.COM #include <smbsrv/smbinfo.h> 38*11337SWilliam.Krier@Sun.COM #include <smbsrv/ntaccess.h> 39*11337SWilliam.Krier@Sun.COM #include <smbsrv/ntstatus.h> 40*11337SWilliam.Krier@Sun.COM #include <smbsrv/ntlocale.h> 41*11337SWilliam.Krier@Sun.COM #include <smbsrv/string.h> 42*11337SWilliam.Krier@Sun.COM #include <lsalib.h> 43*11337SWilliam.Krier@Sun.COM 44*11337SWilliam.Krier@Sun.COM /* 45*11337SWilliam.Krier@Sun.COM * The maximum number of bytes we are prepared to deal with in a 46*11337SWilliam.Krier@Sun.COM * response. 47*11337SWilliam.Krier@Sun.COM */ 48*11337SWilliam.Krier@Sun.COM #define MLSVC_MAX_RESPONSE_LEN 1024 49*11337SWilliam.Krier@Sun.COM 50*11337SWilliam.Krier@Sun.COM /* 51*11337SWilliam.Krier@Sun.COM * This structure is used when looking up names. We only lookup one 52*11337SWilliam.Krier@Sun.COM * name at a time but the structure will allow for more. 53*11337SWilliam.Krier@Sun.COM */ 54*11337SWilliam.Krier@Sun.COM typedef struct lsa_names { 55*11337SWilliam.Krier@Sun.COM uint32_t n_entry; 56*11337SWilliam.Krier@Sun.COM mslsa_string_t name[8]; 57*11337SWilliam.Krier@Sun.COM } lsa_names_t; 58*11337SWilliam.Krier@Sun.COM 59*11337SWilliam.Krier@Sun.COM typedef DWORD (*lsar_nameop_t)(mlsvc_handle_t *, lsa_names_t *, 60*11337SWilliam.Krier@Sun.COM smb_account_t *); 61*11337SWilliam.Krier@Sun.COM 62*11337SWilliam.Krier@Sun.COM static uint32_t lsar_lookup_names1(mlsvc_handle_t *, lsa_names_t *, 63*11337SWilliam.Krier@Sun.COM smb_account_t *); 64*11337SWilliam.Krier@Sun.COM static uint32_t lsar_lookup_names2(mlsvc_handle_t *, lsa_names_t *, 65*11337SWilliam.Krier@Sun.COM smb_account_t *); 66*11337SWilliam.Krier@Sun.COM static uint32_t lsar_lookup_names3(mlsvc_handle_t *, lsa_names_t *, 67*11337SWilliam.Krier@Sun.COM smb_account_t *); 68*11337SWilliam.Krier@Sun.COM static uint32_t lsar_lookup_sids1(mlsvc_handle_t *, lsa_sid_t *, 69*11337SWilliam.Krier@Sun.COM smb_account_t *); 70*11337SWilliam.Krier@Sun.COM static uint32_t lsar_lookup_sids2(mlsvc_handle_t *, lsa_sid_t *, 71*11337SWilliam.Krier@Sun.COM smb_account_t *account); 72*11337SWilliam.Krier@Sun.COM 73*11337SWilliam.Krier@Sun.COM static char *lsar_get_username(const char *); 74*11337SWilliam.Krier@Sun.COM static void smb_account_trace(const smb_account_t *); 75*11337SWilliam.Krier@Sun.COM 76*11337SWilliam.Krier@Sun.COM static void lsar_set_trusted_domains_ex(struct mslsa_EnumTrustedDomainBufEx *, 77*11337SWilliam.Krier@Sun.COM smb_trusted_domains_t *); 78*11337SWilliam.Krier@Sun.COM static void lsar_set_trusted_domains(struct mslsa_EnumTrustedDomainBuf *, 79*11337SWilliam.Krier@Sun.COM smb_trusted_domains_t *); 80*11337SWilliam.Krier@Sun.COM 81*11337SWilliam.Krier@Sun.COM /* 82*11337SWilliam.Krier@Sun.COM * lsar_open 83*11337SWilliam.Krier@Sun.COM * 84*11337SWilliam.Krier@Sun.COM * This is a wrapper round lsar_open_policy2 to ensure that we connect 85*11337SWilliam.Krier@Sun.COM * using the appropriate domain information. 86*11337SWilliam.Krier@Sun.COM * 87*11337SWilliam.Krier@Sun.COM * If username argument is NULL, an anonymous connection will be established. 88*11337SWilliam.Krier@Sun.COM * Otherwise, an authenticated connection will be established. 89*11337SWilliam.Krier@Sun.COM * 90*11337SWilliam.Krier@Sun.COM * On success 0 is returned. Otherwise a -ve error code. 91*11337SWilliam.Krier@Sun.COM */ 92*11337SWilliam.Krier@Sun.COM int lsar_open(char *server, char *domain, char *username, 93*11337SWilliam.Krier@Sun.COM mlsvc_handle_t *domain_handle) 94*11337SWilliam.Krier@Sun.COM { 95*11337SWilliam.Krier@Sun.COM if (server == NULL || domain == NULL) 96*11337SWilliam.Krier@Sun.COM return (-1); 97*11337SWilliam.Krier@Sun.COM 98*11337SWilliam.Krier@Sun.COM if (username == NULL) 99*11337SWilliam.Krier@Sun.COM username = MLSVC_ANON_USER; 100*11337SWilliam.Krier@Sun.COM 101*11337SWilliam.Krier@Sun.COM return (lsar_open_policy2(server, domain, username, domain_handle)); 102*11337SWilliam.Krier@Sun.COM } 103*11337SWilliam.Krier@Sun.COM 104*11337SWilliam.Krier@Sun.COM /* 105*11337SWilliam.Krier@Sun.COM * lsar_open_policy2 106*11337SWilliam.Krier@Sun.COM * 107*11337SWilliam.Krier@Sun.COM * Obtain an LSA policy handle. A policy handle is required to access 108*11337SWilliam.Krier@Sun.COM * LSA resources on a remote server. The server name supplied here does 109*11337SWilliam.Krier@Sun.COM * not need the double backslash prefix; it is added here. Call this 110*11337SWilliam.Krier@Sun.COM * function via lsar_open to ensure that the appropriate connection is 111*11337SWilliam.Krier@Sun.COM * in place. 112*11337SWilliam.Krier@Sun.COM * 113*11337SWilliam.Krier@Sun.COM * I'm not sure if it makes a difference whether we use GENERIC_EXECUTE 114*11337SWilliam.Krier@Sun.COM * or STANDARD_RIGHTS_EXECUTE. For a long time I used the standard bit 115*11337SWilliam.Krier@Sun.COM * and then I added the generic bit while working on privileges because 116*11337SWilliam.Krier@Sun.COM * NT sets that bit. I don't think it matters. 117*11337SWilliam.Krier@Sun.COM * 118*11337SWilliam.Krier@Sun.COM * Returns 0 on success. Otherwise non-zero to indicate a failure. 119*11337SWilliam.Krier@Sun.COM */ 120*11337SWilliam.Krier@Sun.COM int 121*11337SWilliam.Krier@Sun.COM lsar_open_policy2(char *server, char *domain, char *username, 122*11337SWilliam.Krier@Sun.COM mlsvc_handle_t *lsa_handle) 123*11337SWilliam.Krier@Sun.COM { 124*11337SWilliam.Krier@Sun.COM struct mslsa_OpenPolicy2 arg; 125*11337SWilliam.Krier@Sun.COM int opnum; 126*11337SWilliam.Krier@Sun.COM int len; 127*11337SWilliam.Krier@Sun.COM int rc; 128*11337SWilliam.Krier@Sun.COM 129*11337SWilliam.Krier@Sun.COM rc = ndr_rpc_bind(lsa_handle, server, domain, username, "LSARPC"); 130*11337SWilliam.Krier@Sun.COM if (rc != 0) 131*11337SWilliam.Krier@Sun.COM return (-1); 132*11337SWilliam.Krier@Sun.COM 133*11337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_OpenPolicy2; 134*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_OpenPolicy2)); 135*11337SWilliam.Krier@Sun.COM 136*11337SWilliam.Krier@Sun.COM len = strlen(server) + 4; 137*11337SWilliam.Krier@Sun.COM arg.servername = ndr_rpc_malloc(lsa_handle, len); 138*11337SWilliam.Krier@Sun.COM if (arg.servername == NULL) { 139*11337SWilliam.Krier@Sun.COM ndr_rpc_unbind(lsa_handle); 140*11337SWilliam.Krier@Sun.COM return (-1); 141*11337SWilliam.Krier@Sun.COM } 142*11337SWilliam.Krier@Sun.COM 143*11337SWilliam.Krier@Sun.COM (void) snprintf((char *)arg.servername, len, "\\\\%s", server); 144*11337SWilliam.Krier@Sun.COM arg.attributes.length = sizeof (struct mslsa_object_attributes); 145*11337SWilliam.Krier@Sun.COM 146*11337SWilliam.Krier@Sun.COM if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) { 147*11337SWilliam.Krier@Sun.COM arg.desiredAccess = MAXIMUM_ALLOWED; 148*11337SWilliam.Krier@Sun.COM } else { 149*11337SWilliam.Krier@Sun.COM arg.desiredAccess = GENERIC_EXECUTE 150*11337SWilliam.Krier@Sun.COM | STANDARD_RIGHTS_EXECUTE 151*11337SWilliam.Krier@Sun.COM | POLICY_VIEW_LOCAL_INFORMATION 152*11337SWilliam.Krier@Sun.COM | POLICY_LOOKUP_NAMES; 153*11337SWilliam.Krier@Sun.COM } 154*11337SWilliam.Krier@Sun.COM 155*11337SWilliam.Krier@Sun.COM if ((rc = ndr_rpc_call(lsa_handle, opnum, &arg)) != 0) { 156*11337SWilliam.Krier@Sun.COM ndr_rpc_unbind(lsa_handle); 157*11337SWilliam.Krier@Sun.COM return (-1); 158*11337SWilliam.Krier@Sun.COM } 159*11337SWilliam.Krier@Sun.COM 160*11337SWilliam.Krier@Sun.COM if (arg.status != 0) { 161*11337SWilliam.Krier@Sun.COM rc = -1; 162*11337SWilliam.Krier@Sun.COM } else { 163*11337SWilliam.Krier@Sun.COM (void) memcpy(&lsa_handle->handle, &arg.domain_handle, 164*11337SWilliam.Krier@Sun.COM sizeof (ndr_hdid_t)); 165*11337SWilliam.Krier@Sun.COM 166*11337SWilliam.Krier@Sun.COM if (ndr_is_null_handle(lsa_handle)) 167*11337SWilliam.Krier@Sun.COM rc = -1; 168*11337SWilliam.Krier@Sun.COM } 169*11337SWilliam.Krier@Sun.COM 170*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 171*11337SWilliam.Krier@Sun.COM 172*11337SWilliam.Krier@Sun.COM if (rc != 0) 173*11337SWilliam.Krier@Sun.COM ndr_rpc_unbind(lsa_handle); 174*11337SWilliam.Krier@Sun.COM return (rc); 175*11337SWilliam.Krier@Sun.COM } 176*11337SWilliam.Krier@Sun.COM 177*11337SWilliam.Krier@Sun.COM /* 178*11337SWilliam.Krier@Sun.COM * lsar_open_account 179*11337SWilliam.Krier@Sun.COM * 180*11337SWilliam.Krier@Sun.COM * Obtain an LSA account handle. The lsa_handle must be a valid handle 181*11337SWilliam.Krier@Sun.COM * obtained via lsar_open_policy2. The main thing to remember here is 182*11337SWilliam.Krier@Sun.COM * to set up the context in the lsa_account_handle. I'm not sure what 183*11337SWilliam.Krier@Sun.COM * the requirements are for desired access. Some values require admin 184*11337SWilliam.Krier@Sun.COM * access. 185*11337SWilliam.Krier@Sun.COM * 186*11337SWilliam.Krier@Sun.COM * Returns 0 on success. Otherwise non-zero to indicate a failure. 187*11337SWilliam.Krier@Sun.COM */ 188*11337SWilliam.Krier@Sun.COM int 189*11337SWilliam.Krier@Sun.COM lsar_open_account(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, 190*11337SWilliam.Krier@Sun.COM mlsvc_handle_t *lsa_account_handle) 191*11337SWilliam.Krier@Sun.COM { 192*11337SWilliam.Krier@Sun.COM struct mslsa_OpenAccount arg; 193*11337SWilliam.Krier@Sun.COM int opnum; 194*11337SWilliam.Krier@Sun.COM int rc; 195*11337SWilliam.Krier@Sun.COM 196*11337SWilliam.Krier@Sun.COM if (ndr_is_null_handle(lsa_handle) || sid == NULL) 197*11337SWilliam.Krier@Sun.COM return (-1); 198*11337SWilliam.Krier@Sun.COM 199*11337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_OpenAccount; 200*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_OpenAccount)); 201*11337SWilliam.Krier@Sun.COM 202*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 203*11337SWilliam.Krier@Sun.COM arg.sid = sid; 204*11337SWilliam.Krier@Sun.COM arg.access_mask = STANDARD_RIGHTS_REQUIRED 205*11337SWilliam.Krier@Sun.COM #if 0 206*11337SWilliam.Krier@Sun.COM | POLICY_VIEW_AUDIT_INFORMATION 207*11337SWilliam.Krier@Sun.COM | POLICY_GET_PRIVATE_INFORMATION 208*11337SWilliam.Krier@Sun.COM | POLICY_TRUST_ADMIN 209*11337SWilliam.Krier@Sun.COM #endif 210*11337SWilliam.Krier@Sun.COM | POLICY_VIEW_LOCAL_INFORMATION; 211*11337SWilliam.Krier@Sun.COM 212*11337SWilliam.Krier@Sun.COM if ((rc = ndr_rpc_call(lsa_handle, opnum, &arg)) != 0) 213*11337SWilliam.Krier@Sun.COM return (-1); 214*11337SWilliam.Krier@Sun.COM 215*11337SWilliam.Krier@Sun.COM if (arg.status != 0) { 216*11337SWilliam.Krier@Sun.COM rc = -1; 217*11337SWilliam.Krier@Sun.COM } else { 218*11337SWilliam.Krier@Sun.COM ndr_inherit_handle(lsa_account_handle, lsa_handle); 219*11337SWilliam.Krier@Sun.COM 220*11337SWilliam.Krier@Sun.COM (void) memcpy(&lsa_account_handle->handle, 221*11337SWilliam.Krier@Sun.COM &arg.account_handle, sizeof (ndr_hdid_t)); 222*11337SWilliam.Krier@Sun.COM 223*11337SWilliam.Krier@Sun.COM if (ndr_is_null_handle(lsa_account_handle)) 224*11337SWilliam.Krier@Sun.COM rc = -1; 225*11337SWilliam.Krier@Sun.COM } 226*11337SWilliam.Krier@Sun.COM 227*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 228*11337SWilliam.Krier@Sun.COM return (rc); 229*11337SWilliam.Krier@Sun.COM } 230*11337SWilliam.Krier@Sun.COM 231*11337SWilliam.Krier@Sun.COM /* 232*11337SWilliam.Krier@Sun.COM * lsar_close 233*11337SWilliam.Krier@Sun.COM * 234*11337SWilliam.Krier@Sun.COM * Close the LSA connection associated with the handle. The lsa_handle 235*11337SWilliam.Krier@Sun.COM * must be a valid handle obtained via a call to lsar_open_policy2 or 236*11337SWilliam.Krier@Sun.COM * lsar_open_account. On success the handle will be zeroed out to 237*11337SWilliam.Krier@Sun.COM * ensure that it is not used again. If this is the top level handle 238*11337SWilliam.Krier@Sun.COM * (i.e. the one obtained via lsar_open_policy2) the pipe is closed. 239*11337SWilliam.Krier@Sun.COM * 240*11337SWilliam.Krier@Sun.COM * Returns 0 on success. Otherwise non-zero to indicate a failure. 241*11337SWilliam.Krier@Sun.COM */ 242*11337SWilliam.Krier@Sun.COM int 243*11337SWilliam.Krier@Sun.COM lsar_close(mlsvc_handle_t *lsa_handle) 244*11337SWilliam.Krier@Sun.COM { 245*11337SWilliam.Krier@Sun.COM struct mslsa_CloseHandle arg; 246*11337SWilliam.Krier@Sun.COM int opnum; 247*11337SWilliam.Krier@Sun.COM 248*11337SWilliam.Krier@Sun.COM if (ndr_is_null_handle(lsa_handle)) 249*11337SWilliam.Krier@Sun.COM return (-1); 250*11337SWilliam.Krier@Sun.COM 251*11337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_CloseHandle; 252*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_CloseHandle)); 253*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 254*11337SWilliam.Krier@Sun.COM 255*11337SWilliam.Krier@Sun.COM (void) ndr_rpc_call(lsa_handle, opnum, &arg); 256*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 257*11337SWilliam.Krier@Sun.COM 258*11337SWilliam.Krier@Sun.COM if (ndr_is_bind_handle(lsa_handle)) 259*11337SWilliam.Krier@Sun.COM ndr_rpc_unbind(lsa_handle); 260*11337SWilliam.Krier@Sun.COM 261*11337SWilliam.Krier@Sun.COM bzero(lsa_handle, sizeof (mlsvc_handle_t)); 262*11337SWilliam.Krier@Sun.COM return (0); 263*11337SWilliam.Krier@Sun.COM } 264*11337SWilliam.Krier@Sun.COM 265*11337SWilliam.Krier@Sun.COM /* 266*11337SWilliam.Krier@Sun.COM * lsar_query_security_desc 267*11337SWilliam.Krier@Sun.COM * 268*11337SWilliam.Krier@Sun.COM * Don't use this call yet. It is just a place holder for now. 269*11337SWilliam.Krier@Sun.COM */ 270*11337SWilliam.Krier@Sun.COM int 271*11337SWilliam.Krier@Sun.COM lsar_query_security_desc(mlsvc_handle_t *lsa_handle) 272*11337SWilliam.Krier@Sun.COM { 273*11337SWilliam.Krier@Sun.COM struct mslsa_QuerySecurityObject arg; 274*11337SWilliam.Krier@Sun.COM int rc; 275*11337SWilliam.Krier@Sun.COM int opnum; 276*11337SWilliam.Krier@Sun.COM 277*11337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_QuerySecurityObject; 278*11337SWilliam.Krier@Sun.COM 279*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_QuerySecurityObject)); 280*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 281*11337SWilliam.Krier@Sun.COM 282*11337SWilliam.Krier@Sun.COM rc = ndr_rpc_call(lsa_handle, opnum, &arg); 283*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 284*11337SWilliam.Krier@Sun.COM return (rc); 285*11337SWilliam.Krier@Sun.COM } 286*11337SWilliam.Krier@Sun.COM 287*11337SWilliam.Krier@Sun.COM /* 288*11337SWilliam.Krier@Sun.COM * lsar_query_info_policy 289*11337SWilliam.Krier@Sun.COM * 290*11337SWilliam.Krier@Sun.COM * The general purpose of this function is to allow various pieces of 291*11337SWilliam.Krier@Sun.COM * information to be queried on the domain controller. The only 292*11337SWilliam.Krier@Sun.COM * information queries supported are MSLSA_POLICY_PRIMARY_DOMAIN_INFO 293*11337SWilliam.Krier@Sun.COM * and MSLSA_POLICY_ACCOUNT_DOMAIN_INFO. 294*11337SWilliam.Krier@Sun.COM * 295*11337SWilliam.Krier@Sun.COM * On success, the return code will be 0 and the user_info structure 296*11337SWilliam.Krier@Sun.COM * will be set up. The sid_name_use field will be set to SidTypeDomain 297*11337SWilliam.Krier@Sun.COM * indicating that the domain name and domain sid fields are vaild. If 298*11337SWilliam.Krier@Sun.COM * the infoClass returned from the server is not one of the supported 299*11337SWilliam.Krier@Sun.COM * values, the sid_name_use willbe set to SidTypeUnknown. If the RPC 300*11337SWilliam.Krier@Sun.COM * fails, a negative error code will be returned, in which case the 301*11337SWilliam.Krier@Sun.COM * user_info will not have been updated. 302*11337SWilliam.Krier@Sun.COM */ 303*11337SWilliam.Krier@Sun.COM DWORD 304*11337SWilliam.Krier@Sun.COM lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass, 305*11337SWilliam.Krier@Sun.COM smb_domain_t *info) 306*11337SWilliam.Krier@Sun.COM { 307*11337SWilliam.Krier@Sun.COM struct mslsa_QueryInfoPolicy arg; 308*11337SWilliam.Krier@Sun.COM struct mslsa_PrimaryDomainInfo *pd_info; 309*11337SWilliam.Krier@Sun.COM struct mslsa_AccountDomainInfo *ad_info; 310*11337SWilliam.Krier@Sun.COM struct mslsa_DnsDomainInfo *dns_info; 311*11337SWilliam.Krier@Sun.COM char guid_str[UUID_PRINTABLE_STRING_LENGTH]; 312*11337SWilliam.Krier@Sun.COM char sidstr[SMB_SID_STRSZ]; 313*11337SWilliam.Krier@Sun.COM int opnum; 314*11337SWilliam.Krier@Sun.COM DWORD status; 315*11337SWilliam.Krier@Sun.COM 316*11337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || info == NULL) 317*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 318*11337SWilliam.Krier@Sun.COM 319*11337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_QueryInfoPolicy; 320*11337SWilliam.Krier@Sun.COM 321*11337SWilliam.Krier@Sun.COM bzero(info, sizeof (smb_domain_t)); 322*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_QueryInfoPolicy)); 323*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 324*11337SWilliam.Krier@Sun.COM 325*11337SWilliam.Krier@Sun.COM arg.info_class = infoClass; 326*11337SWilliam.Krier@Sun.COM 327*11337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 328*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_PARAMETER; 329*11337SWilliam.Krier@Sun.COM } else if (arg.status != 0) { 330*11337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status); 331*11337SWilliam.Krier@Sun.COM status = NT_SC_VALUE(arg.status); 332*11337SWilliam.Krier@Sun.COM } else { 333*11337SWilliam.Krier@Sun.COM 334*11337SWilliam.Krier@Sun.COM switch (infoClass) { 335*11337SWilliam.Krier@Sun.COM case MSLSA_POLICY_PRIMARY_DOMAIN_INFO: 336*11337SWilliam.Krier@Sun.COM pd_info = &arg.ru.pd_info; 337*11337SWilliam.Krier@Sun.COM 338*11337SWilliam.Krier@Sun.COM smb_sid_tostr((smb_sid_t *)pd_info->sid, sidstr); 339*11337SWilliam.Krier@Sun.COM info->di_type = SMB_DOMAIN_PRIMARY; 340*11337SWilliam.Krier@Sun.COM smb_domain_set_basic_info(sidstr, 341*11337SWilliam.Krier@Sun.COM (char *)pd_info->name.str, "", info); 342*11337SWilliam.Krier@Sun.COM 343*11337SWilliam.Krier@Sun.COM status = NT_STATUS_SUCCESS; 344*11337SWilliam.Krier@Sun.COM break; 345*11337SWilliam.Krier@Sun.COM 346*11337SWilliam.Krier@Sun.COM case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO: 347*11337SWilliam.Krier@Sun.COM ad_info = &arg.ru.ad_info; 348*11337SWilliam.Krier@Sun.COM 349*11337SWilliam.Krier@Sun.COM smb_sid_tostr((smb_sid_t *)ad_info->sid, sidstr); 350*11337SWilliam.Krier@Sun.COM info->di_type = SMB_DOMAIN_ACCOUNT; 351*11337SWilliam.Krier@Sun.COM smb_domain_set_basic_info(sidstr, 352*11337SWilliam.Krier@Sun.COM (char *)ad_info->name.str, "", info); 353*11337SWilliam.Krier@Sun.COM 354*11337SWilliam.Krier@Sun.COM status = NT_STATUS_SUCCESS; 355*11337SWilliam.Krier@Sun.COM break; 356*11337SWilliam.Krier@Sun.COM 357*11337SWilliam.Krier@Sun.COM case MSLSA_POLICY_DNS_DOMAIN_INFO: 358*11337SWilliam.Krier@Sun.COM dns_info = &arg.ru.dns_info; 359*11337SWilliam.Krier@Sun.COM ndr_uuid_unparse((ndr_uuid_t *)&dns_info->guid, 360*11337SWilliam.Krier@Sun.COM guid_str); 361*11337SWilliam.Krier@Sun.COM smb_sid_tostr((smb_sid_t *)dns_info->sid, sidstr); 362*11337SWilliam.Krier@Sun.COM 363*11337SWilliam.Krier@Sun.COM info->di_type = SMB_DOMAIN_PRIMARY; 364*11337SWilliam.Krier@Sun.COM smb_domain_set_dns_info(sidstr, 365*11337SWilliam.Krier@Sun.COM (char *)dns_info->nb_domain.str, 366*11337SWilliam.Krier@Sun.COM (char *)dns_info->dns_domain.str, 367*11337SWilliam.Krier@Sun.COM (char *)dns_info->forest.str, 368*11337SWilliam.Krier@Sun.COM guid_str, info); 369*11337SWilliam.Krier@Sun.COM status = NT_STATUS_SUCCESS; 370*11337SWilliam.Krier@Sun.COM break; 371*11337SWilliam.Krier@Sun.COM 372*11337SWilliam.Krier@Sun.COM default: 373*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_INFO_CLASS; 374*11337SWilliam.Krier@Sun.COM break; 375*11337SWilliam.Krier@Sun.COM } 376*11337SWilliam.Krier@Sun.COM } 377*11337SWilliam.Krier@Sun.COM 378*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 379*11337SWilliam.Krier@Sun.COM return (status); 380*11337SWilliam.Krier@Sun.COM } 381*11337SWilliam.Krier@Sun.COM 382*11337SWilliam.Krier@Sun.COM /* 383*11337SWilliam.Krier@Sun.COM * Lookup a name and obtain the sid/rid. 384*11337SWilliam.Krier@Sun.COM * This is a wrapper for the various lookup sid RPCs. 385*11337SWilliam.Krier@Sun.COM */ 386*11337SWilliam.Krier@Sun.COM uint32_t 387*11337SWilliam.Krier@Sun.COM lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, smb_account_t *info) 388*11337SWilliam.Krier@Sun.COM { 389*11337SWilliam.Krier@Sun.COM static lsar_nameop_t ops[] = { 390*11337SWilliam.Krier@Sun.COM lsar_lookup_names3, 391*11337SWilliam.Krier@Sun.COM lsar_lookup_names2, 392*11337SWilliam.Krier@Sun.COM lsar_lookup_names1 393*11337SWilliam.Krier@Sun.COM }; 394*11337SWilliam.Krier@Sun.COM 395*11337SWilliam.Krier@Sun.COM const srvsvc_server_info_t *svinfo; 396*11337SWilliam.Krier@Sun.COM lsa_names_t names; 397*11337SWilliam.Krier@Sun.COM char *p; 398*11337SWilliam.Krier@Sun.COM uint32_t length; 399*11337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_INVALID_PARAMETER; 400*11337SWilliam.Krier@Sun.COM int n_op = (sizeof (ops) / sizeof (ops[0])); 401*11337SWilliam.Krier@Sun.COM int i; 402*11337SWilliam.Krier@Sun.COM 403*11337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || name == NULL || info == NULL) 404*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 405*11337SWilliam.Krier@Sun.COM 406*11337SWilliam.Krier@Sun.COM bzero(info, sizeof (smb_account_t)); 407*11337SWilliam.Krier@Sun.COM 408*11337SWilliam.Krier@Sun.COM svinfo = ndr_rpc_server_info(lsa_handle); 409*11337SWilliam.Krier@Sun.COM if (svinfo->sv_os == NATIVE_OS_WIN2000 && 410*11337SWilliam.Krier@Sun.COM svinfo->sv_version_major == 5 && svinfo->sv_version_minor == 0) { 411*11337SWilliam.Krier@Sun.COM /* 412*11337SWilliam.Krier@Sun.COM * Windows 2000 doesn't like an LSA lookup for 413*11337SWilliam.Krier@Sun.COM * DOMAIN\Administrator. 414*11337SWilliam.Krier@Sun.COM */ 415*11337SWilliam.Krier@Sun.COM if ((p = strchr(name, '\\')) != 0) { 416*11337SWilliam.Krier@Sun.COM ++p; 417*11337SWilliam.Krier@Sun.COM 418*11337SWilliam.Krier@Sun.COM if (strcasecmp(p, "administrator") == 0) 419*11337SWilliam.Krier@Sun.COM name = p; 420*11337SWilliam.Krier@Sun.COM } 421*11337SWilliam.Krier@Sun.COM 422*11337SWilliam.Krier@Sun.COM } 423*11337SWilliam.Krier@Sun.COM 424*11337SWilliam.Krier@Sun.COM length = smb_wcequiv_strlen(name); 425*11337SWilliam.Krier@Sun.COM names.name[0].length = length; 426*11337SWilliam.Krier@Sun.COM names.name[0].allosize = length; 427*11337SWilliam.Krier@Sun.COM names.name[0].str = (unsigned char *)name; 428*11337SWilliam.Krier@Sun.COM names.n_entry = 1; 429*11337SWilliam.Krier@Sun.COM 430*11337SWilliam.Krier@Sun.COM if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) { 431*11337SWilliam.Krier@Sun.COM for (i = 0; i < n_op; ++i) { 432*11337SWilliam.Krier@Sun.COM ndr_rpc_set_nonull(lsa_handle); 433*11337SWilliam.Krier@Sun.COM status = (*ops[i])(lsa_handle, &names, info); 434*11337SWilliam.Krier@Sun.COM 435*11337SWilliam.Krier@Sun.COM if (status != NT_STATUS_INVALID_PARAMETER) 436*11337SWilliam.Krier@Sun.COM break; 437*11337SWilliam.Krier@Sun.COM } 438*11337SWilliam.Krier@Sun.COM } else { 439*11337SWilliam.Krier@Sun.COM ndr_rpc_set_nonull(lsa_handle); 440*11337SWilliam.Krier@Sun.COM status = lsar_lookup_names1(lsa_handle, &names, info); 441*11337SWilliam.Krier@Sun.COM } 442*11337SWilliam.Krier@Sun.COM 443*11337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) { 444*11337SWilliam.Krier@Sun.COM info->a_name = lsar_get_username(name); 445*11337SWilliam.Krier@Sun.COM 446*11337SWilliam.Krier@Sun.COM if (!smb_account_validate(info)) { 447*11337SWilliam.Krier@Sun.COM smb_account_free(info); 448*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 449*11337SWilliam.Krier@Sun.COM } else { 450*11337SWilliam.Krier@Sun.COM smb_account_trace(info); 451*11337SWilliam.Krier@Sun.COM } 452*11337SWilliam.Krier@Sun.COM } 453*11337SWilliam.Krier@Sun.COM 454*11337SWilliam.Krier@Sun.COM return (status); 455*11337SWilliam.Krier@Sun.COM } 456*11337SWilliam.Krier@Sun.COM 457*11337SWilliam.Krier@Sun.COM /* 458*11337SWilliam.Krier@Sun.COM * The name may be in one of the following forms: 459*11337SWilliam.Krier@Sun.COM * 460*11337SWilliam.Krier@Sun.COM * domain\username 461*11337SWilliam.Krier@Sun.COM * domain/username 462*11337SWilliam.Krier@Sun.COM * username 463*11337SWilliam.Krier@Sun.COM * username@domain 464*11337SWilliam.Krier@Sun.COM * 465*11337SWilliam.Krier@Sun.COM * Return a strdup'd copy of the username. The caller is responsible 466*11337SWilliam.Krier@Sun.COM * for freeing the allocated memory. 467*11337SWilliam.Krier@Sun.COM */ 468*11337SWilliam.Krier@Sun.COM static char * 469*11337SWilliam.Krier@Sun.COM lsar_get_username(const char *name) 470*11337SWilliam.Krier@Sun.COM { 471*11337SWilliam.Krier@Sun.COM char tmp[MAXNAMELEN]; 472*11337SWilliam.Krier@Sun.COM char *dp = NULL; 473*11337SWilliam.Krier@Sun.COM char *np = NULL; 474*11337SWilliam.Krier@Sun.COM 475*11337SWilliam.Krier@Sun.COM (void) strlcpy(tmp, name, MAXNAMELEN); 476*11337SWilliam.Krier@Sun.COM smb_name_parse(tmp, &np, &dp); 477*11337SWilliam.Krier@Sun.COM 478*11337SWilliam.Krier@Sun.COM if (dp != NULL && np != NULL) 479*11337SWilliam.Krier@Sun.COM return (strdup(np)); 480*11337SWilliam.Krier@Sun.COM else 481*11337SWilliam.Krier@Sun.COM return (strdup(name)); 482*11337SWilliam.Krier@Sun.COM } 483*11337SWilliam.Krier@Sun.COM 484*11337SWilliam.Krier@Sun.COM /* 485*11337SWilliam.Krier@Sun.COM * lsar_lookup_names1 486*11337SWilliam.Krier@Sun.COM * 487*11337SWilliam.Krier@Sun.COM * Lookup a name and obtain the domain and user rid. 488*11337SWilliam.Krier@Sun.COM * 489*11337SWilliam.Krier@Sun.COM * Note: NT returns an error if the mapped_count is non-zero when the RPC 490*11337SWilliam.Krier@Sun.COM * is called. 491*11337SWilliam.Krier@Sun.COM * 492*11337SWilliam.Krier@Sun.COM * If the lookup fails, the status will typically be NT_STATUS_NONE_MAPPED. 493*11337SWilliam.Krier@Sun.COM */ 494*11337SWilliam.Krier@Sun.COM static uint32_t 495*11337SWilliam.Krier@Sun.COM lsar_lookup_names1(mlsvc_handle_t *lsa_handle, lsa_names_t *names, 496*11337SWilliam.Krier@Sun.COM smb_account_t *info) 497*11337SWilliam.Krier@Sun.COM { 498*11337SWilliam.Krier@Sun.COM struct mslsa_LookupNames arg; 499*11337SWilliam.Krier@Sun.COM struct mslsa_rid_entry *rid_entry; 500*11337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry; 501*11337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 502*11337SWilliam.Krier@Sun.COM char *domname; 503*11337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupNames; 504*11337SWilliam.Krier@Sun.COM 505*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_LookupNames)); 506*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 507*11337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA; 508*11337SWilliam.Krier@Sun.COM arg.name_table = (struct mslsa_lup_name_table *)names; 509*11337SWilliam.Krier@Sun.COM 510*11337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 511*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 512*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 513*11337SWilliam.Krier@Sun.COM } 514*11337SWilliam.Krier@Sun.COM 515*11337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) { 516*11337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status); 517*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 518*11337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status)); 519*11337SWilliam.Krier@Sun.COM } 520*11337SWilliam.Krier@Sun.COM 521*11337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) { 522*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 523*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 524*11337SWilliam.Krier@Sun.COM } 525*11337SWilliam.Krier@Sun.COM 526*11337SWilliam.Krier@Sun.COM rid_entry = &arg.translated_sids.rids[0]; 527*11337SWilliam.Krier@Sun.COM if (rid_entry->domain_index != 0) { 528*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 529*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 530*11337SWilliam.Krier@Sun.COM } 531*11337SWilliam.Krier@Sun.COM 532*11337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0]; 533*11337SWilliam.Krier@Sun.COM 534*11337SWilliam.Krier@Sun.COM info->a_type = rid_entry->sid_name_use; 535*11337SWilliam.Krier@Sun.COM info->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 536*11337SWilliam.Krier@Sun.COM if ((domname = (char *)domain_entry->domain_name.str) != NULL) 537*11337SWilliam.Krier@Sun.COM info->a_domain = strdup(domname); 538*11337SWilliam.Krier@Sun.COM info->a_rid = rid_entry->rid; 539*11337SWilliam.Krier@Sun.COM info->a_sid = smb_sid_splice(info->a_domsid, info->a_rid); 540*11337SWilliam.Krier@Sun.COM 541*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 542*11337SWilliam.Krier@Sun.COM return (status); 543*11337SWilliam.Krier@Sun.COM } 544*11337SWilliam.Krier@Sun.COM 545*11337SWilliam.Krier@Sun.COM /* 546*11337SWilliam.Krier@Sun.COM * lsar_lookup_names2 547*11337SWilliam.Krier@Sun.COM */ 548*11337SWilliam.Krier@Sun.COM static uint32_t 549*11337SWilliam.Krier@Sun.COM lsar_lookup_names2(mlsvc_handle_t *lsa_handle, lsa_names_t *names, 550*11337SWilliam.Krier@Sun.COM smb_account_t *info) 551*11337SWilliam.Krier@Sun.COM { 552*11337SWilliam.Krier@Sun.COM struct lsar_LookupNames2 arg; 553*11337SWilliam.Krier@Sun.COM struct lsar_rid_entry2 *rid_entry; 554*11337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry; 555*11337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 556*11337SWilliam.Krier@Sun.COM char *domname; 557*11337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupNames2; 558*11337SWilliam.Krier@Sun.COM 559*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct lsar_LookupNames2)); 560*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.policy_handle, lsa_handle, sizeof (mslsa_handle_t)); 561*11337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA; 562*11337SWilliam.Krier@Sun.COM arg.client_revision = LSA_CLIENT_REVISION_AD; 563*11337SWilliam.Krier@Sun.COM arg.name_table = (struct mslsa_lup_name_table *)names; 564*11337SWilliam.Krier@Sun.COM 565*11337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 566*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 567*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 568*11337SWilliam.Krier@Sun.COM } 569*11337SWilliam.Krier@Sun.COM 570*11337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) { 571*11337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status); 572*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 573*11337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status)); 574*11337SWilliam.Krier@Sun.COM } 575*11337SWilliam.Krier@Sun.COM 576*11337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) { 577*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 578*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 579*11337SWilliam.Krier@Sun.COM } 580*11337SWilliam.Krier@Sun.COM 581*11337SWilliam.Krier@Sun.COM rid_entry = &arg.translated_sids.rids[0]; 582*11337SWilliam.Krier@Sun.COM if (rid_entry->domain_index != 0) { 583*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 584*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 585*11337SWilliam.Krier@Sun.COM } 586*11337SWilliam.Krier@Sun.COM 587*11337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0]; 588*11337SWilliam.Krier@Sun.COM 589*11337SWilliam.Krier@Sun.COM info->a_type = rid_entry->sid_name_use; 590*11337SWilliam.Krier@Sun.COM info->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 591*11337SWilliam.Krier@Sun.COM if ((domname = (char *)domain_entry->domain_name.str) != NULL) 592*11337SWilliam.Krier@Sun.COM info->a_domain = strdup(domname); 593*11337SWilliam.Krier@Sun.COM info->a_rid = rid_entry->rid; 594*11337SWilliam.Krier@Sun.COM info->a_sid = smb_sid_splice(info->a_domsid, info->a_rid); 595*11337SWilliam.Krier@Sun.COM 596*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 597*11337SWilliam.Krier@Sun.COM return (status); 598*11337SWilliam.Krier@Sun.COM } 599*11337SWilliam.Krier@Sun.COM 600*11337SWilliam.Krier@Sun.COM /* 601*11337SWilliam.Krier@Sun.COM * lsar_lookup_names3 602*11337SWilliam.Krier@Sun.COM */ 603*11337SWilliam.Krier@Sun.COM static uint32_t 604*11337SWilliam.Krier@Sun.COM lsar_lookup_names3(mlsvc_handle_t *lsa_handle, lsa_names_t *names, 605*11337SWilliam.Krier@Sun.COM smb_account_t *info) 606*11337SWilliam.Krier@Sun.COM { 607*11337SWilliam.Krier@Sun.COM struct lsar_LookupNames3 arg; 608*11337SWilliam.Krier@Sun.COM lsar_translated_sid_ex2_t *sid_entry; 609*11337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry; 610*11337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 611*11337SWilliam.Krier@Sun.COM char *domname; 612*11337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupNames3; 613*11337SWilliam.Krier@Sun.COM 614*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct lsar_LookupNames3)); 615*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.policy_handle, lsa_handle, sizeof (mslsa_handle_t)); 616*11337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA; 617*11337SWilliam.Krier@Sun.COM arg.client_revision = LSA_CLIENT_REVISION_AD; 618*11337SWilliam.Krier@Sun.COM arg.name_table = (struct mslsa_lup_name_table *)names; 619*11337SWilliam.Krier@Sun.COM 620*11337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 621*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 622*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 623*11337SWilliam.Krier@Sun.COM } 624*11337SWilliam.Krier@Sun.COM 625*11337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) { 626*11337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status); 627*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 628*11337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status)); 629*11337SWilliam.Krier@Sun.COM } 630*11337SWilliam.Krier@Sun.COM 631*11337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) { 632*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 633*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 634*11337SWilliam.Krier@Sun.COM } 635*11337SWilliam.Krier@Sun.COM 636*11337SWilliam.Krier@Sun.COM sid_entry = &arg.translated_sids.sids[0]; 637*11337SWilliam.Krier@Sun.COM if (sid_entry->domain_index != 0) { 638*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 639*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 640*11337SWilliam.Krier@Sun.COM } 641*11337SWilliam.Krier@Sun.COM 642*11337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0]; 643*11337SWilliam.Krier@Sun.COM 644*11337SWilliam.Krier@Sun.COM info->a_type = sid_entry->sid_name_use; 645*11337SWilliam.Krier@Sun.COM info->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 646*11337SWilliam.Krier@Sun.COM if ((domname = (char *)domain_entry->domain_name.str) != NULL) 647*11337SWilliam.Krier@Sun.COM info->a_domain = strdup(domname); 648*11337SWilliam.Krier@Sun.COM info->a_sid = smb_sid_dup((smb_sid_t *)sid_entry->sid); 649*11337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(info->a_sid, &info->a_rid); 650*11337SWilliam.Krier@Sun.COM 651*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 652*11337SWilliam.Krier@Sun.COM return (status); 653*11337SWilliam.Krier@Sun.COM } 654*11337SWilliam.Krier@Sun.COM 655*11337SWilliam.Krier@Sun.COM /* 656*11337SWilliam.Krier@Sun.COM * lsar_lookup_names4 657*11337SWilliam.Krier@Sun.COM * 658*11337SWilliam.Krier@Sun.COM * This function is only valid if the remote RPC server is a domain 659*11337SWilliam.Krier@Sun.COM * controller and requires the security extensions defined in MS-RPCE. 660*11337SWilliam.Krier@Sun.COM * 661*11337SWilliam.Krier@Sun.COM * Domain controllers will return RPC_NT_PROTSEQ_NOT_SUPPORTED here 662*11337SWilliam.Krier@Sun.COM * because we don't support the RPC_C_AUTHN_NETLOGON security provider. 663*11337SWilliam.Krier@Sun.COM * Non-domain controllers will return NT_STATUS_INVALID_SERVER_STATE. 664*11337SWilliam.Krier@Sun.COM */ 665*11337SWilliam.Krier@Sun.COM static uint32_t /*LINTED E_STATIC_UNUSED*/ 666*11337SWilliam.Krier@Sun.COM lsar_lookup_names4(mlsvc_handle_t *lsa_handle, lsa_names_t *names, 667*11337SWilliam.Krier@Sun.COM smb_account_t *info) 668*11337SWilliam.Krier@Sun.COM { 669*11337SWilliam.Krier@Sun.COM struct lsar_LookupNames4 arg; 670*11337SWilliam.Krier@Sun.COM lsar_translated_sid_ex2_t *sid_entry; 671*11337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry; 672*11337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 673*11337SWilliam.Krier@Sun.COM char *domname; 674*11337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupNames4; 675*11337SWilliam.Krier@Sun.COM 676*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct lsar_LookupNames4)); 677*11337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA; 678*11337SWilliam.Krier@Sun.COM arg.client_revision = LSA_CLIENT_REVISION_AD; 679*11337SWilliam.Krier@Sun.COM arg.name_table = (struct mslsa_lup_name_table *)names; 680*11337SWilliam.Krier@Sun.COM 681*11337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 682*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 683*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 684*11337SWilliam.Krier@Sun.COM } 685*11337SWilliam.Krier@Sun.COM 686*11337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) { 687*11337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status); 688*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 689*11337SWilliam.Krier@Sun.COM if (arg.status == RPC_NT_PROTSEQ_NOT_SUPPORTED || 690*11337SWilliam.Krier@Sun.COM arg.status == NT_STATUS_INVALID_SERVER_STATE) 691*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 692*11337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status)); 693*11337SWilliam.Krier@Sun.COM } 694*11337SWilliam.Krier@Sun.COM 695*11337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) { 696*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 697*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 698*11337SWilliam.Krier@Sun.COM } 699*11337SWilliam.Krier@Sun.COM 700*11337SWilliam.Krier@Sun.COM sid_entry = &arg.translated_sids.sids[0]; 701*11337SWilliam.Krier@Sun.COM if (sid_entry->domain_index != 0) { 702*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 703*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 704*11337SWilliam.Krier@Sun.COM } 705*11337SWilliam.Krier@Sun.COM 706*11337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0]; 707*11337SWilliam.Krier@Sun.COM 708*11337SWilliam.Krier@Sun.COM info->a_type = sid_entry->sid_name_use; 709*11337SWilliam.Krier@Sun.COM info->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 710*11337SWilliam.Krier@Sun.COM if ((domname = (char *)domain_entry->domain_name.str) != NULL) 711*11337SWilliam.Krier@Sun.COM info->a_domain = strdup(domname); 712*11337SWilliam.Krier@Sun.COM info->a_sid = smb_sid_dup((smb_sid_t *)sid_entry->sid); 713*11337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(info->a_sid, &info->a_rid); 714*11337SWilliam.Krier@Sun.COM 715*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 716*11337SWilliam.Krier@Sun.COM return (status); 717*11337SWilliam.Krier@Sun.COM } 718*11337SWilliam.Krier@Sun.COM 719*11337SWilliam.Krier@Sun.COM /* 720*11337SWilliam.Krier@Sun.COM * Lookup a sid and obtain the domain sid and account name. 721*11337SWilliam.Krier@Sun.COM * This is a wrapper for the various lookup sid RPCs. 722*11337SWilliam.Krier@Sun.COM */ 723*11337SWilliam.Krier@Sun.COM uint32_t 724*11337SWilliam.Krier@Sun.COM lsar_lookup_sids(mlsvc_handle_t *lsa_handle, smb_sid_t *sid, 725*11337SWilliam.Krier@Sun.COM smb_account_t *account) 726*11337SWilliam.Krier@Sun.COM { 727*11337SWilliam.Krier@Sun.COM char sidbuf[SMB_SID_STRSZ]; 728*11337SWilliam.Krier@Sun.COM uint32_t status; 729*11337SWilliam.Krier@Sun.COM 730*11337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || sid == NULL || account == NULL) 731*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 732*11337SWilliam.Krier@Sun.COM 733*11337SWilliam.Krier@Sun.COM bzero(account, sizeof (smb_account_t)); 734*11337SWilliam.Krier@Sun.COM bzero(sidbuf, SMB_SID_STRSZ); 735*11337SWilliam.Krier@Sun.COM smb_sid_tostr(sid, sidbuf); 736*11337SWilliam.Krier@Sun.COM smb_tracef("%s", sidbuf); 737*11337SWilliam.Krier@Sun.COM 738*11337SWilliam.Krier@Sun.COM if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) 739*11337SWilliam.Krier@Sun.COM status = lsar_lookup_sids2(lsa_handle, (lsa_sid_t *)sid, 740*11337SWilliam.Krier@Sun.COM account); 741*11337SWilliam.Krier@Sun.COM else 742*11337SWilliam.Krier@Sun.COM status = lsar_lookup_sids1(lsa_handle, (lsa_sid_t *)sid, 743*11337SWilliam.Krier@Sun.COM account); 744*11337SWilliam.Krier@Sun.COM 745*11337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) { 746*11337SWilliam.Krier@Sun.COM if (!smb_account_validate(account)) { 747*11337SWilliam.Krier@Sun.COM smb_account_free(account); 748*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 749*11337SWilliam.Krier@Sun.COM } else { 750*11337SWilliam.Krier@Sun.COM smb_account_trace(account); 751*11337SWilliam.Krier@Sun.COM } 752*11337SWilliam.Krier@Sun.COM } 753*11337SWilliam.Krier@Sun.COM 754*11337SWilliam.Krier@Sun.COM return (status); 755*11337SWilliam.Krier@Sun.COM } 756*11337SWilliam.Krier@Sun.COM 757*11337SWilliam.Krier@Sun.COM /* 758*11337SWilliam.Krier@Sun.COM * lsar_lookup_sids1 759*11337SWilliam.Krier@Sun.COM */ 760*11337SWilliam.Krier@Sun.COM static uint32_t 761*11337SWilliam.Krier@Sun.COM lsar_lookup_sids1(mlsvc_handle_t *lsa_handle, lsa_sid_t *sid, 762*11337SWilliam.Krier@Sun.COM smb_account_t *account) 763*11337SWilliam.Krier@Sun.COM { 764*11337SWilliam.Krier@Sun.COM struct mslsa_LookupSids arg; 765*11337SWilliam.Krier@Sun.COM struct mslsa_lup_sid_entry sid_entry; 766*11337SWilliam.Krier@Sun.COM struct mslsa_name_entry *name_entry; 767*11337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry; 768*11337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 769*11337SWilliam.Krier@Sun.COM char *name; 770*11337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupSids; 771*11337SWilliam.Krier@Sun.COM 772*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_LookupSids)); 773*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 774*11337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA; 775*11337SWilliam.Krier@Sun.COM 776*11337SWilliam.Krier@Sun.COM sid_entry.psid = sid; 777*11337SWilliam.Krier@Sun.COM arg.lup_sid_table.n_entry = 1; 778*11337SWilliam.Krier@Sun.COM arg.lup_sid_table.entries = &sid_entry; 779*11337SWilliam.Krier@Sun.COM 780*11337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 781*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 782*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 783*11337SWilliam.Krier@Sun.COM } 784*11337SWilliam.Krier@Sun.COM 785*11337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) { 786*11337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status); 787*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 788*11337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status)); 789*11337SWilliam.Krier@Sun.COM } 790*11337SWilliam.Krier@Sun.COM 791*11337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) { 792*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 793*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 794*11337SWilliam.Krier@Sun.COM } 795*11337SWilliam.Krier@Sun.COM 796*11337SWilliam.Krier@Sun.COM name_entry = &arg.name_table.entries[0]; 797*11337SWilliam.Krier@Sun.COM if (name_entry->domain_ix != 0) { 798*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 799*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 800*11337SWilliam.Krier@Sun.COM } 801*11337SWilliam.Krier@Sun.COM 802*11337SWilliam.Krier@Sun.COM name = (char *)name_entry->name.str; 803*11337SWilliam.Krier@Sun.COM account->a_name = (name) ? strdup(name) : strdup(""); 804*11337SWilliam.Krier@Sun.COM account->a_type = name_entry->sid_name_use; 805*11337SWilliam.Krier@Sun.COM account->a_sid = smb_sid_dup((smb_sid_t *)sid); 806*11337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(account->a_sid, &account->a_rid); 807*11337SWilliam.Krier@Sun.COM 808*11337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0]; 809*11337SWilliam.Krier@Sun.COM if ((name = (char *)domain_entry->domain_name.str) != NULL) 810*11337SWilliam.Krier@Sun.COM account->a_domain = strdup(name); 811*11337SWilliam.Krier@Sun.COM account->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 812*11337SWilliam.Krier@Sun.COM 813*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 814*11337SWilliam.Krier@Sun.COM return (status); 815*11337SWilliam.Krier@Sun.COM } 816*11337SWilliam.Krier@Sun.COM 817*11337SWilliam.Krier@Sun.COM /* 818*11337SWilliam.Krier@Sun.COM * lsar_lookup_sids2 819*11337SWilliam.Krier@Sun.COM */ 820*11337SWilliam.Krier@Sun.COM static uint32_t 821*11337SWilliam.Krier@Sun.COM lsar_lookup_sids2(mlsvc_handle_t *lsa_handle, lsa_sid_t *sid, 822*11337SWilliam.Krier@Sun.COM smb_account_t *account) 823*11337SWilliam.Krier@Sun.COM { 824*11337SWilliam.Krier@Sun.COM struct lsar_lookup_sids2 arg; 825*11337SWilliam.Krier@Sun.COM struct lsar_name_entry2 *name_entry; 826*11337SWilliam.Krier@Sun.COM struct mslsa_lup_sid_entry sid_entry; 827*11337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry; 828*11337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 829*11337SWilliam.Krier@Sun.COM char *name; 830*11337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupSids2; 831*11337SWilliam.Krier@Sun.COM 832*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct lsar_lookup_sids2)); 833*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.policy_handle, lsa_handle, sizeof (mslsa_handle_t)); 834*11337SWilliam.Krier@Sun.COM 835*11337SWilliam.Krier@Sun.COM sid_entry.psid = sid; 836*11337SWilliam.Krier@Sun.COM arg.lup_sid_table.n_entry = 1; 837*11337SWilliam.Krier@Sun.COM arg.lup_sid_table.entries = &sid_entry; 838*11337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA; 839*11337SWilliam.Krier@Sun.COM arg.client_revision = LSA_CLIENT_REVISION_AD; 840*11337SWilliam.Krier@Sun.COM 841*11337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 842*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 843*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 844*11337SWilliam.Krier@Sun.COM } 845*11337SWilliam.Krier@Sun.COM 846*11337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) { 847*11337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status); 848*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 849*11337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status)); 850*11337SWilliam.Krier@Sun.COM } 851*11337SWilliam.Krier@Sun.COM 852*11337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) { 853*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 854*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 855*11337SWilliam.Krier@Sun.COM } 856*11337SWilliam.Krier@Sun.COM 857*11337SWilliam.Krier@Sun.COM name_entry = &arg.name_table.entries[0]; 858*11337SWilliam.Krier@Sun.COM if (name_entry->domain_ix != 0) { 859*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 860*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 861*11337SWilliam.Krier@Sun.COM } 862*11337SWilliam.Krier@Sun.COM 863*11337SWilliam.Krier@Sun.COM name = (char *)name_entry->name.str; 864*11337SWilliam.Krier@Sun.COM account->a_name = (name) ? strdup(name) : strdup(""); 865*11337SWilliam.Krier@Sun.COM account->a_type = name_entry->sid_name_use; 866*11337SWilliam.Krier@Sun.COM account->a_sid = smb_sid_dup((smb_sid_t *)sid); 867*11337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(account->a_sid, &account->a_rid); 868*11337SWilliam.Krier@Sun.COM 869*11337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0]; 870*11337SWilliam.Krier@Sun.COM if ((name = (char *)domain_entry->domain_name.str) != NULL) 871*11337SWilliam.Krier@Sun.COM account->a_domain = strdup(name); 872*11337SWilliam.Krier@Sun.COM account->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 873*11337SWilliam.Krier@Sun.COM 874*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 875*11337SWilliam.Krier@Sun.COM return (status); 876*11337SWilliam.Krier@Sun.COM } 877*11337SWilliam.Krier@Sun.COM 878*11337SWilliam.Krier@Sun.COM /* 879*11337SWilliam.Krier@Sun.COM * lsar_lookup_sids3 880*11337SWilliam.Krier@Sun.COM * 881*11337SWilliam.Krier@Sun.COM * This function is only valid if the remote RPC server is a domain 882*11337SWilliam.Krier@Sun.COM * controller and requires the security extensions defined in MS-RPCE. 883*11337SWilliam.Krier@Sun.COM * 884*11337SWilliam.Krier@Sun.COM * Domain controllers will return RPC_NT_PROTSEQ_NOT_SUPPORTED here 885*11337SWilliam.Krier@Sun.COM * because we don't support the RPC_C_AUTHN_NETLOGON security provider. 886*11337SWilliam.Krier@Sun.COM * Non-domain controllers will return NT_STATUS_INVALID_SERVER_STATE. 887*11337SWilliam.Krier@Sun.COM */ 888*11337SWilliam.Krier@Sun.COM static uint32_t /*LINTED E_STATIC_UNUSED*/ 889*11337SWilliam.Krier@Sun.COM lsar_lookup_sids3(mlsvc_handle_t *lsa_handle, lsa_sid_t *sid, 890*11337SWilliam.Krier@Sun.COM smb_account_t *account) 891*11337SWilliam.Krier@Sun.COM { 892*11337SWilliam.Krier@Sun.COM struct lsar_lookup_sids3 arg; 893*11337SWilliam.Krier@Sun.COM lsar_translated_name_ex_t *name_entry; 894*11337SWilliam.Krier@Sun.COM struct mslsa_lup_sid_entry sid_entry; 895*11337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry; 896*11337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 897*11337SWilliam.Krier@Sun.COM char *name; 898*11337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupSids3; 899*11337SWilliam.Krier@Sun.COM 900*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct lsar_lookup_sids3)); 901*11337SWilliam.Krier@Sun.COM 902*11337SWilliam.Krier@Sun.COM sid_entry.psid = sid; 903*11337SWilliam.Krier@Sun.COM arg.lup_sid_table.n_entry = 1; 904*11337SWilliam.Krier@Sun.COM arg.lup_sid_table.entries = &sid_entry; 905*11337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA; 906*11337SWilliam.Krier@Sun.COM arg.client_revision = LSA_CLIENT_REVISION_AD; 907*11337SWilliam.Krier@Sun.COM 908*11337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 909*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 910*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 911*11337SWilliam.Krier@Sun.COM } 912*11337SWilliam.Krier@Sun.COM 913*11337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) { 914*11337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status); 915*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 916*11337SWilliam.Krier@Sun.COM if (arg.status == RPC_NT_PROTSEQ_NOT_SUPPORTED || 917*11337SWilliam.Krier@Sun.COM arg.status == NT_STATUS_INVALID_SERVER_STATE) 918*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 919*11337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status)); 920*11337SWilliam.Krier@Sun.COM } 921*11337SWilliam.Krier@Sun.COM 922*11337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) { 923*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 924*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 925*11337SWilliam.Krier@Sun.COM } 926*11337SWilliam.Krier@Sun.COM 927*11337SWilliam.Krier@Sun.COM name_entry = &arg.name_table.entries[0]; 928*11337SWilliam.Krier@Sun.COM if (name_entry->domain_ix != 0) { 929*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 930*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED); 931*11337SWilliam.Krier@Sun.COM } 932*11337SWilliam.Krier@Sun.COM 933*11337SWilliam.Krier@Sun.COM name = (char *)name_entry->name.str; 934*11337SWilliam.Krier@Sun.COM account->a_name = (name) ? strdup(name) : strdup(""); 935*11337SWilliam.Krier@Sun.COM account->a_type = name_entry->sid_name_use; 936*11337SWilliam.Krier@Sun.COM account->a_sid = smb_sid_dup((smb_sid_t *)sid); 937*11337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(account->a_sid, &account->a_rid); 938*11337SWilliam.Krier@Sun.COM 939*11337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0]; 940*11337SWilliam.Krier@Sun.COM if ((name = (char *)domain_entry->domain_name.str) != NULL) 941*11337SWilliam.Krier@Sun.COM account->a_domain = strdup(name); 942*11337SWilliam.Krier@Sun.COM account->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 943*11337SWilliam.Krier@Sun.COM 944*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 945*11337SWilliam.Krier@Sun.COM return (status); 946*11337SWilliam.Krier@Sun.COM } 947*11337SWilliam.Krier@Sun.COM 948*11337SWilliam.Krier@Sun.COM /* 949*11337SWilliam.Krier@Sun.COM * lsar_enum_accounts 950*11337SWilliam.Krier@Sun.COM * 951*11337SWilliam.Krier@Sun.COM * Enumerate the list of accounts (i.e. SIDs). Use the handle returned 952*11337SWilliam.Krier@Sun.COM * from lsa_open_policy2. The enum_context is used to support multiple 953*11337SWilliam.Krier@Sun.COM * calls to this enumeration function. It should be set to 0 on the 954*11337SWilliam.Krier@Sun.COM * first call. It will be updated by the domain controller and should 955*11337SWilliam.Krier@Sun.COM * simply be passed unchanged to subsequent calls until there are no 956*11337SWilliam.Krier@Sun.COM * more accounts. A warning status of 0x1A indicates that no more data 957*11337SWilliam.Krier@Sun.COM * is available. The list of accounts will be returned in accounts. 958*11337SWilliam.Krier@Sun.COM * This list is dynamically allocated using malloc, it should be freed 959*11337SWilliam.Krier@Sun.COM * by the caller when it is no longer required. 960*11337SWilliam.Krier@Sun.COM */ 961*11337SWilliam.Krier@Sun.COM int 962*11337SWilliam.Krier@Sun.COM lsar_enum_accounts(mlsvc_handle_t *lsa_handle, DWORD *enum_context, 963*11337SWilliam.Krier@Sun.COM struct mslsa_EnumAccountBuf *accounts) 964*11337SWilliam.Krier@Sun.COM { 965*11337SWilliam.Krier@Sun.COM struct mslsa_EnumerateAccounts arg; 966*11337SWilliam.Krier@Sun.COM struct mslsa_AccountInfo *info; 967*11337SWilliam.Krier@Sun.COM int opnum; 968*11337SWilliam.Krier@Sun.COM int rc; 969*11337SWilliam.Krier@Sun.COM DWORD n_entries; 970*11337SWilliam.Krier@Sun.COM DWORD i; 971*11337SWilliam.Krier@Sun.COM int nbytes; 972*11337SWilliam.Krier@Sun.COM 973*11337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || enum_context == NULL || accounts == NULL) 974*11337SWilliam.Krier@Sun.COM return (-1); 975*11337SWilliam.Krier@Sun.COM 976*11337SWilliam.Krier@Sun.COM accounts->entries_read = 0; 977*11337SWilliam.Krier@Sun.COM accounts->info = 0; 978*11337SWilliam.Krier@Sun.COM 979*11337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_EnumerateAccounts; 980*11337SWilliam.Krier@Sun.COM 981*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_EnumerateAccounts)); 982*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 983*11337SWilliam.Krier@Sun.COM arg.enum_context = *enum_context; 984*11337SWilliam.Krier@Sun.COM arg.max_length = MLSVC_MAX_RESPONSE_LEN; 985*11337SWilliam.Krier@Sun.COM 986*11337SWilliam.Krier@Sun.COM rc = ndr_rpc_call(lsa_handle, opnum, &arg); 987*11337SWilliam.Krier@Sun.COM if (rc == 0) { 988*11337SWilliam.Krier@Sun.COM if (arg.status != 0) { 989*11337SWilliam.Krier@Sun.COM if ((arg.status & 0x00FFFFFF) == 990*11337SWilliam.Krier@Sun.COM NT_STATUS_NO_MORE_DATA) { 991*11337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context; 992*11337SWilliam.Krier@Sun.COM } else { 993*11337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status); 994*11337SWilliam.Krier@Sun.COM rc = -1; 995*11337SWilliam.Krier@Sun.COM } 996*11337SWilliam.Krier@Sun.COM } else if (arg.enum_buf->entries_read != 0) { 997*11337SWilliam.Krier@Sun.COM n_entries = arg.enum_buf->entries_read; 998*11337SWilliam.Krier@Sun.COM nbytes = n_entries * sizeof (struct mslsa_AccountInfo); 999*11337SWilliam.Krier@Sun.COM 1000*11337SWilliam.Krier@Sun.COM if ((info = malloc(nbytes)) == NULL) { 1001*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 1002*11337SWilliam.Krier@Sun.COM return (-1); 1003*11337SWilliam.Krier@Sun.COM } 1004*11337SWilliam.Krier@Sun.COM 1005*11337SWilliam.Krier@Sun.COM for (i = 0; i < n_entries; ++i) 1006*11337SWilliam.Krier@Sun.COM info[i].sid = (lsa_sid_t *)smb_sid_dup( 1007*11337SWilliam.Krier@Sun.COM (smb_sid_t *)arg.enum_buf->info[i].sid); 1008*11337SWilliam.Krier@Sun.COM 1009*11337SWilliam.Krier@Sun.COM accounts->entries_read = n_entries; 1010*11337SWilliam.Krier@Sun.COM accounts->info = info; 1011*11337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context; 1012*11337SWilliam.Krier@Sun.COM } 1013*11337SWilliam.Krier@Sun.COM } 1014*11337SWilliam.Krier@Sun.COM 1015*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 1016*11337SWilliam.Krier@Sun.COM return (rc); 1017*11337SWilliam.Krier@Sun.COM } 1018*11337SWilliam.Krier@Sun.COM 1019*11337SWilliam.Krier@Sun.COM /* 1020*11337SWilliam.Krier@Sun.COM * lsar_enum_trusted_domains 1021*11337SWilliam.Krier@Sun.COM * 1022*11337SWilliam.Krier@Sun.COM * Enumerate the list of trusted domains. Use the handle returned from 1023*11337SWilliam.Krier@Sun.COM * lsa_open_policy2. The enum_context is used to support multiple calls 1024*11337SWilliam.Krier@Sun.COM * to this enumeration function. It should be set to 0 on the first 1025*11337SWilliam.Krier@Sun.COM * call. It will be updated by the domain controller and should simply 1026*11337SWilliam.Krier@Sun.COM * be passed unchanged to subsequent calls until there are no more 1027*11337SWilliam.Krier@Sun.COM * domains. 1028*11337SWilliam.Krier@Sun.COM * 1029*11337SWilliam.Krier@Sun.COM * The trusted domains aren't actually returned here. They are added 1030*11337SWilliam.Krier@Sun.COM * to the NT domain database. After all of the trusted domains have 1031*11337SWilliam.Krier@Sun.COM * been discovered, the database can be interrogated to find all of 1032*11337SWilliam.Krier@Sun.COM * the trusted domains. 1033*11337SWilliam.Krier@Sun.COM */ 1034*11337SWilliam.Krier@Sun.COM DWORD 1035*11337SWilliam.Krier@Sun.COM lsar_enum_trusted_domains(mlsvc_handle_t *lsa_handle, DWORD *enum_context, 1036*11337SWilliam.Krier@Sun.COM smb_trusted_domains_t *list) 1037*11337SWilliam.Krier@Sun.COM { 1038*11337SWilliam.Krier@Sun.COM struct mslsa_EnumTrustedDomain arg; 1039*11337SWilliam.Krier@Sun.COM int opnum; 1040*11337SWilliam.Krier@Sun.COM DWORD status; 1041*11337SWilliam.Krier@Sun.COM 1042*11337SWilliam.Krier@Sun.COM if (list == NULL) 1043*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 1044*11337SWilliam.Krier@Sun.COM 1045*11337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_EnumTrustedDomain; 1046*11337SWilliam.Krier@Sun.COM 1047*11337SWilliam.Krier@Sun.COM bzero(list, sizeof (smb_trusted_domains_t)); 1048*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_EnumTrustedDomain)); 1049*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 1050*11337SWilliam.Krier@Sun.COM arg.enum_context = *enum_context; 1051*11337SWilliam.Krier@Sun.COM arg.max_length = MLSVC_MAX_RESPONSE_LEN; 1052*11337SWilliam.Krier@Sun.COM 1053*11337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 1054*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_PARAMETER; 1055*11337SWilliam.Krier@Sun.COM } else if (arg.status != 0) { 1056*11337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context; 1057*11337SWilliam.Krier@Sun.COM status = NT_SC_VALUE(arg.status); 1058*11337SWilliam.Krier@Sun.COM 1059*11337SWilliam.Krier@Sun.COM /* 1060*11337SWilliam.Krier@Sun.COM * status 0x8000001A means NO_MORE_DATA, 1061*11337SWilliam.Krier@Sun.COM * which is not an error. 1062*11337SWilliam.Krier@Sun.COM */ 1063*11337SWilliam.Krier@Sun.COM if (status != NT_STATUS_NO_MORE_DATA) 1064*11337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status); 1065*11337SWilliam.Krier@Sun.COM } else if (arg.enum_buf->entries_read == 0) { 1066*11337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context; 1067*11337SWilliam.Krier@Sun.COM status = 0; 1068*11337SWilliam.Krier@Sun.COM } else { 1069*11337SWilliam.Krier@Sun.COM lsar_set_trusted_domains(arg.enum_buf, list); 1070*11337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context; 1071*11337SWilliam.Krier@Sun.COM status = 0; 1072*11337SWilliam.Krier@Sun.COM } 1073*11337SWilliam.Krier@Sun.COM 1074*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 1075*11337SWilliam.Krier@Sun.COM return (status); 1076*11337SWilliam.Krier@Sun.COM } 1077*11337SWilliam.Krier@Sun.COM 1078*11337SWilliam.Krier@Sun.COM DWORD 1079*11337SWilliam.Krier@Sun.COM lsar_enum_trusted_domains_ex(mlsvc_handle_t *lsa_handle, DWORD *enum_context, 1080*11337SWilliam.Krier@Sun.COM smb_trusted_domains_t *list) 1081*11337SWilliam.Krier@Sun.COM { 1082*11337SWilliam.Krier@Sun.COM struct mslsa_EnumTrustedDomainEx arg; 1083*11337SWilliam.Krier@Sun.COM int opnum; 1084*11337SWilliam.Krier@Sun.COM DWORD status; 1085*11337SWilliam.Krier@Sun.COM 1086*11337SWilliam.Krier@Sun.COM if (list == NULL) 1087*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 1088*11337SWilliam.Krier@Sun.COM 1089*11337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_EnumTrustedDomainsEx; 1090*11337SWilliam.Krier@Sun.COM 1091*11337SWilliam.Krier@Sun.COM bzero(list, sizeof (smb_trusted_domains_t)); 1092*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_EnumTrustedDomainEx)); 1093*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 1094*11337SWilliam.Krier@Sun.COM arg.enum_context = *enum_context; 1095*11337SWilliam.Krier@Sun.COM arg.max_length = MLSVC_MAX_RESPONSE_LEN; 1096*11337SWilliam.Krier@Sun.COM 1097*11337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 1098*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_PARAMETER; 1099*11337SWilliam.Krier@Sun.COM } else if (arg.status != 0) { 1100*11337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context; 1101*11337SWilliam.Krier@Sun.COM status = NT_SC_VALUE(arg.status); 1102*11337SWilliam.Krier@Sun.COM 1103*11337SWilliam.Krier@Sun.COM /* 1104*11337SWilliam.Krier@Sun.COM * status 0x8000001A means NO_MORE_DATA, 1105*11337SWilliam.Krier@Sun.COM * which is not an error. 1106*11337SWilliam.Krier@Sun.COM */ 1107*11337SWilliam.Krier@Sun.COM if (status != NT_STATUS_NO_MORE_DATA) 1108*11337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status); 1109*11337SWilliam.Krier@Sun.COM } else if (arg.enum_buf->entries_read == 0) { 1110*11337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context; 1111*11337SWilliam.Krier@Sun.COM status = 0; 1112*11337SWilliam.Krier@Sun.COM } else { 1113*11337SWilliam.Krier@Sun.COM lsar_set_trusted_domains_ex(arg.enum_buf, list); 1114*11337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context; 1115*11337SWilliam.Krier@Sun.COM status = 0; 1116*11337SWilliam.Krier@Sun.COM } 1117*11337SWilliam.Krier@Sun.COM 1118*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 1119*11337SWilliam.Krier@Sun.COM return (status); 1120*11337SWilliam.Krier@Sun.COM } 1121*11337SWilliam.Krier@Sun.COM 1122*11337SWilliam.Krier@Sun.COM /* 1123*11337SWilliam.Krier@Sun.COM * lsar_enum_privs_account 1124*11337SWilliam.Krier@Sun.COM * 1125*11337SWilliam.Krier@Sun.COM * Privileges enum? Need an account handle. 1126*11337SWilliam.Krier@Sun.COM */ 1127*11337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 1128*11337SWilliam.Krier@Sun.COM int 1129*11337SWilliam.Krier@Sun.COM lsar_enum_privs_account(mlsvc_handle_t *account_handle, smb_account_t *account) 1130*11337SWilliam.Krier@Sun.COM { 1131*11337SWilliam.Krier@Sun.COM struct mslsa_EnumPrivsAccount arg; 1132*11337SWilliam.Krier@Sun.COM int opnum; 1133*11337SWilliam.Krier@Sun.COM int rc; 1134*11337SWilliam.Krier@Sun.COM 1135*11337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_EnumPrivsAccount; 1136*11337SWilliam.Krier@Sun.COM 1137*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_EnumPrivsAccount)); 1138*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.account_handle, &account_handle->handle, 1139*11337SWilliam.Krier@Sun.COM sizeof (mslsa_handle_t)); 1140*11337SWilliam.Krier@Sun.COM 1141*11337SWilliam.Krier@Sun.COM rc = ndr_rpc_call(account_handle, opnum, &arg); 1142*11337SWilliam.Krier@Sun.COM if ((rc == 0) && (arg.status != 0)) { 1143*11337SWilliam.Krier@Sun.COM ndr_rpc_status(account_handle, opnum, arg.status); 1144*11337SWilliam.Krier@Sun.COM rc = -1; 1145*11337SWilliam.Krier@Sun.COM } 1146*11337SWilliam.Krier@Sun.COM ndr_rpc_release(account_handle); 1147*11337SWilliam.Krier@Sun.COM return (rc); 1148*11337SWilliam.Krier@Sun.COM } 1149*11337SWilliam.Krier@Sun.COM 1150*11337SWilliam.Krier@Sun.COM /* 1151*11337SWilliam.Krier@Sun.COM * lsar_lookup_priv_value 1152*11337SWilliam.Krier@Sun.COM * 1153*11337SWilliam.Krier@Sun.COM * Map a privilege name to a local unique id (LUID). Privilege names 1154*11337SWilliam.Krier@Sun.COM * are consistent across the network. LUIDs are machine specific. 1155*11337SWilliam.Krier@Sun.COM * This function provides the means to map a privilege name to the 1156*11337SWilliam.Krier@Sun.COM * LUID used by a remote server to represent it. The handle here is 1157*11337SWilliam.Krier@Sun.COM * a policy handle. 1158*11337SWilliam.Krier@Sun.COM */ 1159*11337SWilliam.Krier@Sun.COM int 1160*11337SWilliam.Krier@Sun.COM lsar_lookup_priv_value(mlsvc_handle_t *lsa_handle, char *name, 1161*11337SWilliam.Krier@Sun.COM struct ms_luid *luid) 1162*11337SWilliam.Krier@Sun.COM { 1163*11337SWilliam.Krier@Sun.COM struct mslsa_LookupPrivValue arg; 1164*11337SWilliam.Krier@Sun.COM int opnum; 1165*11337SWilliam.Krier@Sun.COM int rc; 1166*11337SWilliam.Krier@Sun.COM size_t length; 1167*11337SWilliam.Krier@Sun.COM 1168*11337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || name == NULL || luid == NULL) 1169*11337SWilliam.Krier@Sun.COM return (-1); 1170*11337SWilliam.Krier@Sun.COM 1171*11337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_LookupPrivValue; 1172*11337SWilliam.Krier@Sun.COM 1173*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_LookupPrivValue)); 1174*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 1175*11337SWilliam.Krier@Sun.COM 1176*11337SWilliam.Krier@Sun.COM length = smb_wcequiv_strlen(name); 1177*11337SWilliam.Krier@Sun.COM if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) 1178*11337SWilliam.Krier@Sun.COM length += sizeof (smb_wchar_t); 1179*11337SWilliam.Krier@Sun.COM 1180*11337SWilliam.Krier@Sun.COM arg.name.length = length; 1181*11337SWilliam.Krier@Sun.COM arg.name.allosize = length; 1182*11337SWilliam.Krier@Sun.COM arg.name.str = (unsigned char *)name; 1183*11337SWilliam.Krier@Sun.COM 1184*11337SWilliam.Krier@Sun.COM rc = ndr_rpc_call(lsa_handle, opnum, &arg); 1185*11337SWilliam.Krier@Sun.COM if (rc == 0) { 1186*11337SWilliam.Krier@Sun.COM if (arg.status != 0) 1187*11337SWilliam.Krier@Sun.COM rc = -1; 1188*11337SWilliam.Krier@Sun.COM else 1189*11337SWilliam.Krier@Sun.COM (void) memcpy(luid, &arg.luid, sizeof (struct ms_luid)); 1190*11337SWilliam.Krier@Sun.COM } 1191*11337SWilliam.Krier@Sun.COM 1192*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 1193*11337SWilliam.Krier@Sun.COM return (rc); 1194*11337SWilliam.Krier@Sun.COM } 1195*11337SWilliam.Krier@Sun.COM 1196*11337SWilliam.Krier@Sun.COM /* 1197*11337SWilliam.Krier@Sun.COM * lsar_lookup_priv_name 1198*11337SWilliam.Krier@Sun.COM * 1199*11337SWilliam.Krier@Sun.COM * Map a local unique id (LUID) to a privilege name. Privilege names 1200*11337SWilliam.Krier@Sun.COM * are consistent across the network. LUIDs are machine specific. 1201*11337SWilliam.Krier@Sun.COM * This function the means to map the LUID used by a remote server to 1202*11337SWilliam.Krier@Sun.COM * the appropriate privilege name. The handle here is a policy handle. 1203*11337SWilliam.Krier@Sun.COM */ 1204*11337SWilliam.Krier@Sun.COM int 1205*11337SWilliam.Krier@Sun.COM lsar_lookup_priv_name(mlsvc_handle_t *lsa_handle, struct ms_luid *luid, 1206*11337SWilliam.Krier@Sun.COM char *name, int namelen) 1207*11337SWilliam.Krier@Sun.COM { 1208*11337SWilliam.Krier@Sun.COM struct mslsa_LookupPrivName arg; 1209*11337SWilliam.Krier@Sun.COM int opnum; 1210*11337SWilliam.Krier@Sun.COM int rc; 1211*11337SWilliam.Krier@Sun.COM 1212*11337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || luid == NULL || name == NULL) 1213*11337SWilliam.Krier@Sun.COM return (-1); 1214*11337SWilliam.Krier@Sun.COM 1215*11337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_LookupPrivName; 1216*11337SWilliam.Krier@Sun.COM 1217*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_LookupPrivName)); 1218*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 1219*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.luid, luid, sizeof (struct ms_luid)); 1220*11337SWilliam.Krier@Sun.COM 1221*11337SWilliam.Krier@Sun.COM rc = ndr_rpc_call(lsa_handle, opnum, &arg); 1222*11337SWilliam.Krier@Sun.COM if (rc == 0) { 1223*11337SWilliam.Krier@Sun.COM if (arg.status != 0) 1224*11337SWilliam.Krier@Sun.COM rc = -1; 1225*11337SWilliam.Krier@Sun.COM else 1226*11337SWilliam.Krier@Sun.COM (void) strlcpy(name, (char const *)arg.name->str, 1227*11337SWilliam.Krier@Sun.COM namelen); 1228*11337SWilliam.Krier@Sun.COM } 1229*11337SWilliam.Krier@Sun.COM 1230*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 1231*11337SWilliam.Krier@Sun.COM return (rc); 1232*11337SWilliam.Krier@Sun.COM } 1233*11337SWilliam.Krier@Sun.COM 1234*11337SWilliam.Krier@Sun.COM /* 1235*11337SWilliam.Krier@Sun.COM * lsar_lookup_priv_display_name 1236*11337SWilliam.Krier@Sun.COM * 1237*11337SWilliam.Krier@Sun.COM * Map a privilege name to a privilege display name. The input handle 1238*11337SWilliam.Krier@Sun.COM * should be an LSA policy handle and the name would normally be one 1239*11337SWilliam.Krier@Sun.COM * of the privileges defined in smb_privilege.h 1240*11337SWilliam.Krier@Sun.COM * 1241*11337SWilliam.Krier@Sun.COM * There's something peculiar about the return status from NT servers, 1242*11337SWilliam.Krier@Sun.COM * it's not always present. So for now, I'm ignoring the status in the 1243*11337SWilliam.Krier@Sun.COM * RPC response. 1244*11337SWilliam.Krier@Sun.COM * 1245*11337SWilliam.Krier@Sun.COM * Returns NT status codes. 1246*11337SWilliam.Krier@Sun.COM */ 1247*11337SWilliam.Krier@Sun.COM DWORD 1248*11337SWilliam.Krier@Sun.COM lsar_lookup_priv_display_name(mlsvc_handle_t *lsa_handle, char *name, 1249*11337SWilliam.Krier@Sun.COM char *display_name, int display_len) 1250*11337SWilliam.Krier@Sun.COM { 1251*11337SWilliam.Krier@Sun.COM struct mslsa_LookupPrivDisplayName arg; 1252*11337SWilliam.Krier@Sun.COM int opnum; 1253*11337SWilliam.Krier@Sun.COM size_t length; 1254*11337SWilliam.Krier@Sun.COM DWORD status; 1255*11337SWilliam.Krier@Sun.COM 1256*11337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || name == NULL || display_name == NULL) 1257*11337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER); 1258*11337SWilliam.Krier@Sun.COM 1259*11337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_LookupPrivDisplayName; 1260*11337SWilliam.Krier@Sun.COM 1261*11337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_LookupPrivDisplayName)); 1262*11337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 1263*11337SWilliam.Krier@Sun.COM 1264*11337SWilliam.Krier@Sun.COM length = smb_wcequiv_strlen(name); 1265*11337SWilliam.Krier@Sun.COM arg.name.length = length; 1266*11337SWilliam.Krier@Sun.COM arg.name.allosize = length; 1267*11337SWilliam.Krier@Sun.COM arg.name.str = (unsigned char *)name; 1268*11337SWilliam.Krier@Sun.COM 1269*11337SWilliam.Krier@Sun.COM arg.client_language = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); 1270*11337SWilliam.Krier@Sun.COM arg.default_language = MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL); 1271*11337SWilliam.Krier@Sun.COM 1272*11337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) 1273*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_PARAMETER; 1274*11337SWilliam.Krier@Sun.COM #if 0 1275*11337SWilliam.Krier@Sun.COM else if (arg.status != 0) 1276*11337SWilliam.Krier@Sun.COM status = NT_SC_VALUE(arg.status); 1277*11337SWilliam.Krier@Sun.COM #endif 1278*11337SWilliam.Krier@Sun.COM else { 1279*11337SWilliam.Krier@Sun.COM (void) strlcpy(display_name, 1280*11337SWilliam.Krier@Sun.COM (char const *)arg.display_name->str, display_len); 1281*11337SWilliam.Krier@Sun.COM status = NT_STATUS_SUCCESS; 1282*11337SWilliam.Krier@Sun.COM } 1283*11337SWilliam.Krier@Sun.COM 1284*11337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle); 1285*11337SWilliam.Krier@Sun.COM return (status); 1286*11337SWilliam.Krier@Sun.COM } 1287*11337SWilliam.Krier@Sun.COM 1288*11337SWilliam.Krier@Sun.COM static void 1289*11337SWilliam.Krier@Sun.COM lsar_set_trusted_domains_ex(struct mslsa_EnumTrustedDomainBufEx *enum_buf, 1290*11337SWilliam.Krier@Sun.COM smb_trusted_domains_t *list) 1291*11337SWilliam.Krier@Sun.COM { 1292*11337SWilliam.Krier@Sun.COM char sidstr[SMB_SID_STRSZ]; 1293*11337SWilliam.Krier@Sun.COM int i; 1294*11337SWilliam.Krier@Sun.COM 1295*11337SWilliam.Krier@Sun.COM if (list == NULL || enum_buf == NULL || enum_buf->entries_read == 0) 1296*11337SWilliam.Krier@Sun.COM return; 1297*11337SWilliam.Krier@Sun.COM 1298*11337SWilliam.Krier@Sun.COM list->td_num = 0; 1299*11337SWilliam.Krier@Sun.COM list->td_domains = calloc(enum_buf->entries_read, 1300*11337SWilliam.Krier@Sun.COM sizeof (smb_domain_t)); 1301*11337SWilliam.Krier@Sun.COM 1302*11337SWilliam.Krier@Sun.COM if (list->td_domains == NULL) 1303*11337SWilliam.Krier@Sun.COM return; 1304*11337SWilliam.Krier@Sun.COM 1305*11337SWilliam.Krier@Sun.COM list->td_num = enum_buf->entries_read; 1306*11337SWilliam.Krier@Sun.COM for (i = 0; i < list->td_num; i++) { 1307*11337SWilliam.Krier@Sun.COM smb_sid_tostr((smb_sid_t *)enum_buf->info[i].sid, sidstr); 1308*11337SWilliam.Krier@Sun.COM smb_domain_set_trust_info( 1309*11337SWilliam.Krier@Sun.COM sidstr, 1310*11337SWilliam.Krier@Sun.COM (char *)enum_buf->info[i].nb_name.str, 1311*11337SWilliam.Krier@Sun.COM (char *)enum_buf->info[i].dns_name.str, 1312*11337SWilliam.Krier@Sun.COM enum_buf->info[i].trust_direction, 1313*11337SWilliam.Krier@Sun.COM enum_buf->info[i].trust_type, 1314*11337SWilliam.Krier@Sun.COM enum_buf->info[i].trust_attrs, 1315*11337SWilliam.Krier@Sun.COM &list->td_domains[i]); 1316*11337SWilliam.Krier@Sun.COM } 1317*11337SWilliam.Krier@Sun.COM } 1318*11337SWilliam.Krier@Sun.COM 1319*11337SWilliam.Krier@Sun.COM static void 1320*11337SWilliam.Krier@Sun.COM lsar_set_trusted_domains(struct mslsa_EnumTrustedDomainBuf *enum_buf, 1321*11337SWilliam.Krier@Sun.COM smb_trusted_domains_t *list) 1322*11337SWilliam.Krier@Sun.COM { 1323*11337SWilliam.Krier@Sun.COM char sidstr[SMB_SID_STRSZ]; 1324*11337SWilliam.Krier@Sun.COM int i; 1325*11337SWilliam.Krier@Sun.COM 1326*11337SWilliam.Krier@Sun.COM if (list == NULL || enum_buf == NULL || enum_buf->entries_read == 0) 1327*11337SWilliam.Krier@Sun.COM return; 1328*11337SWilliam.Krier@Sun.COM 1329*11337SWilliam.Krier@Sun.COM list->td_num = 0; 1330*11337SWilliam.Krier@Sun.COM list->td_domains = calloc(enum_buf->entries_read, 1331*11337SWilliam.Krier@Sun.COM sizeof (smb_domain_t)); 1332*11337SWilliam.Krier@Sun.COM 1333*11337SWilliam.Krier@Sun.COM if (list->td_domains == NULL) 1334*11337SWilliam.Krier@Sun.COM return; 1335*11337SWilliam.Krier@Sun.COM 1336*11337SWilliam.Krier@Sun.COM list->td_num = enum_buf->entries_read; 1337*11337SWilliam.Krier@Sun.COM for (i = 0; i < list->td_num; i++) { 1338*11337SWilliam.Krier@Sun.COM smb_sid_tostr((smb_sid_t *)enum_buf->info[i].sid, sidstr); 1339*11337SWilliam.Krier@Sun.COM smb_domain_set_trust_info( 1340*11337SWilliam.Krier@Sun.COM sidstr, (char *)enum_buf->info[i].name.str, 1341*11337SWilliam.Krier@Sun.COM "", 0, 0, 0, &list->td_domains[i]); 1342*11337SWilliam.Krier@Sun.COM } 1343*11337SWilliam.Krier@Sun.COM } 1344*11337SWilliam.Krier@Sun.COM 1345*11337SWilliam.Krier@Sun.COM static void 1346*11337SWilliam.Krier@Sun.COM smb_account_trace(const smb_account_t *info) 1347*11337SWilliam.Krier@Sun.COM { 1348*11337SWilliam.Krier@Sun.COM char sidbuf[SMB_SID_STRSZ]; 1349*11337SWilliam.Krier@Sun.COM 1350*11337SWilliam.Krier@Sun.COM bzero(sidbuf, SMB_SID_STRSZ); 1351*11337SWilliam.Krier@Sun.COM smb_sid_tostr(info->a_sid, sidbuf); 1352*11337SWilliam.Krier@Sun.COM 1353*11337SWilliam.Krier@Sun.COM smb_tracef("%s %s %s %lu %s", info->a_domain, info->a_name, 1354*11337SWilliam.Krier@Sun.COM sidbuf, info->a_rid, smb_sid_type2str(info->a_type)); 1355*11337SWilliam.Krier@Sun.COM } 1356