/* * Lookup a sid and obtain the domain sid and account name. * This is a wrapper for the various lookup sid RPCs. */ uint32_t lsar_lookup_sids(mlsvc_handle_t *lsa_handle, smb_sid_t *sid, smb_account_t *account) { char sidbuf[SMB_SID_STRSZ]; uint32_t status; if (lsa_handle == NULL || sid == NULL || account == NULL) return (NT_STATUS_INVALID_PARAMETER); bzero(account, sizeof (smb_account_t)); bzero(sidbuf, SMB_SID_STRSZ); smb_sid_tostr(sid, sidbuf); smb_tracef("%s", sidbuf); if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) status = lsar_lookup_sids2(lsa_handle, (lsa_sid_t *)sid, account); else status = lsar_lookup_sids1(lsa_handle, (lsa_sid_t *)sid, account); if (status == NT_STATUS_SUCCESS) { if (!smb_account_validate(account)) { smb_account_free(account); status = NT_STATUS_NO_MEMORY; } else { smb_account_trace(account); } } return (status); }
/* * samr_lookup_domain * * Lookup up the domain SID for the specified domain name. The handle * should be one returned from samr_connect. The allocated memory for * the returned SID must be freed by caller. */ smb_sid_t * samr_lookup_domain(mlsvc_handle_t *samr_handle, char *domain_name) { struct samr_LookupDomain arg; smb_sid_t *domsid = NULL; int opnum; size_t length; if (ndr_is_null_handle(samr_handle) || domain_name == NULL) return (NULL); opnum = SAMR_OPNUM_LookupDomain; bzero(&arg, sizeof (struct samr_LookupDomain)); (void) memcpy(&arg.handle, &samr_handle->handle, sizeof (samr_handle_t)); length = smb_wcequiv_strlen(domain_name); if (ndr_rpc_server_os(samr_handle) == NATIVE_OS_WIN2000) length += sizeof (smb_wchar_t); arg.domain_name.length = length; arg.domain_name.allosize = length; arg.domain_name.str = (unsigned char *)domain_name; if (ndr_rpc_call(samr_handle, opnum, &arg) == 0) domsid = smb_sid_dup((smb_sid_t *)arg.sid); ndr_rpc_release(samr_handle); return (domsid); }
/* * samr_lookup_domain_names * * Lookup up the given name in the domain specified by domain_handle. * Upon a successful lookup the information is returned in the account * arg and caller must free allocated memories by calling smb_account_free(). * * Returns NT status codes. */ uint32_t samr_lookup_domain_names(mlsvc_handle_t *domain_handle, char *name, smb_account_t *account) { struct samr_LookupNames arg; int opnum; uint32_t status; size_t length; if (ndr_is_null_handle(domain_handle) || name == NULL || account == NULL) { return (NT_STATUS_INVALID_PARAMETER); } bzero(account, sizeof (smb_account_t)); opnum = SAMR_OPNUM_LookupNames; bzero(&arg, sizeof (struct samr_LookupNames)); (void) memcpy(&arg.handle, &domain_handle->handle, sizeof (samr_handle_t)); arg.n_entry = 1; arg.max_n_entry = 1000; arg.index = 0; arg.total = 1; length = smb_wcequiv_strlen(name); if (ndr_rpc_server_os(domain_handle) == NATIVE_OS_WIN2000) length += sizeof (smb_wchar_t); arg.name.length = length; arg.name.allosize = length; arg.name.str = (unsigned char *)name; if (ndr_rpc_call(domain_handle, opnum, &arg) != 0) { status = NT_STATUS_INVALID_PARAMETER; } else if (arg.status != NT_STATUS_SUCCESS) { status = NT_SC_VALUE(arg.status); /* * Handle none-mapped status quietly. */ if (status != NT_STATUS_NONE_MAPPED) ndr_rpc_status(domain_handle, opnum, arg.status); } else { account->a_type = arg.rid_types.rid_type[0]; account->a_rid = arg.rids.rid[0]; status = NT_STATUS_SUCCESS; } ndr_rpc_release(domain_handle); return (status); }
static struct samr_sid * sam_get_domain_sid(mlsvc_handle_t *samr_handle, char *server, char *domain_name) { smb_sid_t *sid = NULL; smb_domainex_t domain; if (ndr_rpc_server_os(samr_handle) == NATIVE_OS_WIN2000) { if (!smb_domain_getinfo(&domain)) { if (lsa_query_account_domain_info(server, domain_name, &domain.d_primary) != NT_STATUS_SUCCESS) return (NULL); } sid = smb_sid_fromstr(domain.d_primary.di_sid); } else { sid = samr_lookup_domain(samr_handle, domain_name); } return ((struct samr_sid *)sid); }
/* * lsar_lookup_priv_value * * Map a privilege name to a local unique id (LUID). Privilege names * are consistent across the network. LUIDs are machine specific. * This function provides the means to map a privilege name to the * LUID used by a remote server to represent it. The handle here is * a policy handle. */ int lsar_lookup_priv_value(mlsvc_handle_t *lsa_handle, char *name, struct ms_luid *luid) { struct mslsa_LookupPrivValue arg; int opnum; int rc; size_t length; if (lsa_handle == NULL || name == NULL || luid == NULL) return (-1); opnum = LSARPC_OPNUM_LookupPrivValue; bzero(&arg, sizeof (struct mslsa_LookupPrivValue)); (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); length = smb_wcequiv_strlen(name); if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) length += sizeof (smb_wchar_t); arg.name.length = length; arg.name.allosize = length; arg.name.str = (unsigned char *)name; rc = ndr_rpc_call(lsa_handle, opnum, &arg); if (rc == 0) { if (arg.status != 0) rc = -1; else (void) memcpy(luid, &arg.luid, sizeof (struct ms_luid)); } ndr_rpc_release(lsa_handle); return (rc); }
/* * Lookup a name and obtain the sid/rid. * This is a wrapper for the various lookup sid RPCs. */ uint32_t lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, smb_account_t *info) { static lsar_nameop_t ops[] = { lsar_lookup_names3, lsar_lookup_names2, lsar_lookup_names1 }; const srvsvc_server_info_t *svinfo; lsa_names_t names; char *p; uint32_t length; uint32_t status = NT_STATUS_INVALID_PARAMETER; int n_op = (sizeof (ops) / sizeof (ops[0])); int i; if (lsa_handle == NULL || name == NULL || info == NULL) return (NT_STATUS_INVALID_PARAMETER); bzero(info, sizeof (smb_account_t)); svinfo = ndr_rpc_server_info(lsa_handle); if (svinfo->sv_os == NATIVE_OS_WIN2000 && svinfo->sv_version_major == 5 && svinfo->sv_version_minor == 0) { /* * Windows 2000 doesn't like an LSA lookup for * DOMAIN\Administrator. */ if ((p = strchr(name, '\\')) != 0) { ++p; if (strcasecmp(p, "administrator") == 0) name = p; } } length = smb_wcequiv_strlen(name); names.name[0].length = length; names.name[0].allosize = length; names.name[0].str = (unsigned char *)name; names.n_entry = 1; if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) { for (i = 0; i < n_op; ++i) { ndr_rpc_set_nonull(lsa_handle); status = (*ops[i])(lsa_handle, &names, info); if (status != NT_STATUS_INVALID_PARAMETER) break; } } else { ndr_rpc_set_nonull(lsa_handle); status = lsar_lookup_names1(lsa_handle, &names, info); } if (status == NT_STATUS_SUCCESS) { info->a_name = lsar_get_username(name); if (!smb_account_validate(info)) { smb_account_free(info); status = NT_STATUS_NO_MEMORY; } else { smb_account_trace(info); } } return (status); }