static void lsar_set_trusted_domains(struct mslsa_EnumTrustedDomainBuf *enum_buf, smb_trusted_domains_t *list) { char sidstr[SMB_SID_STRSZ]; int i; if (list == NULL || enum_buf == NULL || enum_buf->entries_read == 0) return; list->td_num = 0; list->td_domains = calloc(enum_buf->entries_read, sizeof (smb_domain_t)); if (list->td_domains == NULL) return; list->td_num = enum_buf->entries_read; for (i = 0; i < list->td_num; i++) { smb_sid_tostr((smb_sid_t *)enum_buf->info[i].sid, sidstr); smb_domain_set_trust_info( sidstr, (char *)enum_buf->info[i].name.str, "", 0, 0, 0, &list->td_domains[i]); } }
/* * 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); }
/* * smbadm_group_dump_members * * Dump group members details. */ static void smbadm_group_dump_members(smb_gsid_t *members, int num) { char sidstr[SMB_SID_STRSZ]; lsa_account_t acct; int i; if (num == 0) { (void) printf(gettext("\tNo members\n")); return; } (void) printf(gettext("\tMembers:\n")); for (i = 0; i < num; i++) { smb_sid_tostr(members[i].gs_sid, sidstr); if (smb_lookup_sid(sidstr, &acct) == 0) { if (acct.a_status == NT_STATUS_SUCCESS) smbadm_group_show_name(acct.a_domain, acct.a_name); else (void) printf(gettext("\t\t%s [%s]\n"), sidstr, xlate_nt_status(acct.a_status)); } else { (void) printf(gettext("\t\t%s\n"), sidstr); } } }
static void smb_account_trace(const smb_account_t *info) { char sidbuf[SMB_SID_STRSZ]; bzero(sidbuf, SMB_SID_STRSZ); smb_sid_tostr(info->a_sid, sidbuf); smb_tracef("%s %s %s %lu %s", info->a_domain, info->a_name, sidbuf, info->a_rid, smb_sid_type2str(info->a_type)); }
/* * smbadm_group_dump * * Dump group details. */ static void smbadm_group_dump(smb_group_t *grp, boolean_t show_mem, boolean_t show_privs) { char sidstr[SMB_SID_STRSZ]; (void) printf(gettext("%s (%s)\n"), grp->sg_name, grp->sg_cmnt); smb_sid_tostr(grp->sg_id.gs_sid, sidstr); (void) printf(gettext("\tSID: %s\n"), sidstr); if (show_privs) smbadm_group_dump_privs(grp->sg_privs); if (show_mem) smbadm_group_dump_members(grp->sg_members, grp->sg_nmembers); }
/* * Initialize the ksid based on the given smb_id_t. */ static void smb_cred_set_sid(smb_id_t *id, ksid_t *ksid) { char sidstr[SMB_SID_STRSZ]; int rc; ASSERT(id); ASSERT(id->i_sid); ksid->ks_id = id->i_id; smb_sid_tostr(id->i_sid, sidstr); rc = smb_sid_splitstr(sidstr, &ksid->ks_rid); ASSERT(rc == 0); ksid->ks_attr = id->i_attrs; ksid->ks_domain = ksid_lookupdomain(sidstr); }
/* * lsar_query_info_policy * * The general purpose of this function is to allow various pieces of * information to be queried on the domain controller. The only * information queries supported are MSLSA_POLICY_PRIMARY_DOMAIN_INFO * and MSLSA_POLICY_ACCOUNT_DOMAIN_INFO. * * On success, the return code will be 0 and the user_info structure * will be set up. The sid_name_use field will be set to SidTypeDomain * indicating that the domain name and domain sid fields are vaild. If * the infoClass returned from the server is not one of the supported * values, the sid_name_use willbe set to SidTypeUnknown. If the RPC * fails, a negative error code will be returned, in which case the * user_info will not have been updated. */ DWORD lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass, smb_domain_t *info) { struct mslsa_QueryInfoPolicy arg; struct mslsa_PrimaryDomainInfo *pd_info; struct mslsa_AccountDomainInfo *ad_info; struct mslsa_DnsDomainInfo *dns_info; char guid_str[UUID_PRINTABLE_STRING_LENGTH]; char sidstr[SMB_SID_STRSZ]; int opnum; DWORD status; if (lsa_handle == NULL || info == NULL) return (NT_STATUS_INVALID_PARAMETER); opnum = LSARPC_OPNUM_QueryInfoPolicy; bzero(info, sizeof (smb_domain_t)); bzero(&arg, sizeof (struct mslsa_QueryInfoPolicy)); (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); arg.info_class = infoClass; if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { status = NT_STATUS_INVALID_PARAMETER; } else if (arg.status != 0) { ndr_rpc_status(lsa_handle, opnum, arg.status); status = NT_SC_VALUE(arg.status); } else { switch (infoClass) { case MSLSA_POLICY_PRIMARY_DOMAIN_INFO: pd_info = &arg.ru.pd_info; smb_sid_tostr((smb_sid_t *)pd_info->sid, sidstr); info->di_type = SMB_DOMAIN_PRIMARY; smb_domain_set_basic_info(sidstr, (char *)pd_info->name.str, "", info); status = NT_STATUS_SUCCESS; break; case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO: ad_info = &arg.ru.ad_info; smb_sid_tostr((smb_sid_t *)ad_info->sid, sidstr); info->di_type = SMB_DOMAIN_ACCOUNT; smb_domain_set_basic_info(sidstr, (char *)ad_info->name.str, "", info); status = NT_STATUS_SUCCESS; break; case MSLSA_POLICY_DNS_DOMAIN_INFO: dns_info = &arg.ru.dns_info; ndr_uuid_unparse((ndr_uuid_t *)&dns_info->guid, guid_str); smb_sid_tostr((smb_sid_t *)dns_info->sid, sidstr); info->di_type = SMB_DOMAIN_PRIMARY; smb_domain_set_dns_info(sidstr, (char *)dns_info->nb_domain.str, (char *)dns_info->dns_domain.str, (char *)dns_info->forest.str, guid_str, info); status = NT_STATUS_SUCCESS; break; default: status = NT_STATUS_INVALID_INFO_CLASS; break; } } ndr_rpc_release(lsa_handle); return (status); }
/* * smb_acl_to_zfs * * Converts given Windows ACL to a ZFS ACL. * * fs_acl will contain a pointer to the created ZFS ACL. * The allocated memory should be freed by calling * smb_fsacl_free(). * * Since the output parameter, fs_acl, is allocated in this * function, the caller has to make sure *fs_acl is NULL which * means it's not pointing to any memory. */ uint32_t smb_acl_to_zfs(smb_acl_t *acl, uint32_t flags, int which_acl, acl_t **fs_acl) { smb_ace_t *ace; acl_t *zacl; ace_t *zace; smb_idmap_batch_t sib; smb_idmap_t *sim; idmap_stat idm_stat; char *sidstr; int i; ASSERT(fs_acl); ASSERT(*fs_acl == NULL); if (acl && !smb_acl_isvalid(acl, which_acl)) return (NT_STATUS_INVALID_ACL); if ((acl == NULL) || (acl->sl_acecnt == 0)) { if (which_acl == SMB_DACL_SECINFO) { *fs_acl = smb_fsacl_null_empty(acl == NULL); } return (NT_STATUS_SUCCESS); } idm_stat = smb_idmap_batch_create(&sib, acl->sl_acecnt, SMB_IDMAP_SID2ID); if (idm_stat != IDMAP_SUCCESS) return (NT_STATUS_INTERNAL_ERROR); sidstr = kmem_alloc(SMB_SID_STRSZ, KM_SLEEP); zacl = smb_fsacl_alloc(acl->sl_acecnt, flags); zace = zacl->acl_aclp; ace = acl->sl_aces; sim = sib.sib_maps; for (i = 0; i < acl->sl_acecnt; i++, zace++, ace++, sim++) { zace->a_type = ace->se_hdr.se_type & ACE_ALL_TYPES; zace->a_access_mask = smb_ace_mask_g2s(ace->se_mask); zace->a_flags = smb_ace_flags_tozfs(ace->se_hdr.se_flags); zace->a_who = (uid_t)-1; smb_sid_tostr(ace->se_sid, sidstr); if (!smb_ace_wellknown_update(sidstr, zace)) { sim->sim_id = &zace->a_who; idm_stat = smb_idmap_batch_getid(sib.sib_idmaph, sim, ace->se_sid, SMB_IDMAP_UNKNOWN); if (idm_stat != IDMAP_SUCCESS) { kmem_free(sidstr, SMB_SID_STRSZ); smb_fsacl_free(zacl); smb_idmap_batch_destroy(&sib); return (NT_STATUS_INTERNAL_ERROR); } } } kmem_free(sidstr, SMB_SID_STRSZ); idm_stat = smb_idmap_batch_getmappings(&sib); if (idm_stat != IDMAP_SUCCESS) { smb_fsacl_free(zacl); smb_idmap_batch_destroy(&sib); return (NT_STATUS_NONE_MAPPED); } /* * Set the ACEs group flag based on the type of ID returned. */ zace = zacl->acl_aclp; ace = acl->sl_aces; sim = sib.sib_maps; for (i = 0; i < acl->sl_acecnt; i++, zace++, ace++, sim++) { if (zace->a_who == (uid_t)-1) continue; if (sim->sim_idtype == SMB_IDMAP_GROUP) zace->a_flags |= ACE_IDENTIFIER_GROUP; } smb_idmap_batch_destroy(&sib); *fs_acl = zacl; return (NT_STATUS_SUCCESS); }
/* * lsarpc_s_LookupSids2 * * Other than the use of lsar_lookup_sids2 and lsar_name_entry2, this * is identical to lsarpc_s_LookupSids. * * Ignore lookup_level, it is reserved and should be zero. */ static int lsarpc_s_LookupSids2(void *arg, ndr_xa_t *mxa) { struct lsar_lookup_sids2 *param = arg; struct lsar_name_entry2 *names; struct lsar_name_entry2 *name; struct mslsa_domain_table *domain_table; struct mslsa_domain_entry *domain_entry; smb_account_t account; smb_sid_t *sid; DWORD n_entry; DWORD n_mapped; char sidstr[SMB_SID_STRSZ]; int result; int i; bzero(&account, sizeof (smb_account_t)); n_mapped = 0; n_entry = param->lup_sid_table.n_entry; names = NDR_NEWN(mxa, struct lsar_name_entry2, n_entry); domain_table = NDR_NEW(mxa, struct mslsa_domain_table); domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry, MLSVC_DOMAIN_MAX); if (names == NULL || domain_table == NULL || domain_entry == NULL) goto lookup_sid_failed; domain_table->entries = domain_entry; domain_table->n_entry = 0; domain_table->max_n_entry = MLSVC_DOMAIN_MAX; name = names; for (i = 0; i < n_entry; ++i, name++) { bzero(name, sizeof (struct lsar_name_entry2)); sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid; result = lsa_lookup_sid(sid, &account); if ((result != NT_STATUS_SUCCESS) || (account.a_name == NULL) || (*account.a_name == '\0')) { account.a_type = SidTypeUnknown; smb_sid_tostr(sid, sidstr); if (NDR_MSTRING(mxa, sidstr, (ndr_mstring_t *)&name->name) == -1) goto lookup_sid_failed; } else { if (NDR_MSTRING(mxa, account.a_name, (ndr_mstring_t *)&name->name) == -1) goto lookup_sid_failed; ++n_mapped; } name->sid_name_use = account.a_type; result = lsarpc_s_UpdateDomainTable(mxa, &account, domain_table, &name->domain_ix); if (result == -1) goto lookup_sid_failed; smb_account_free(&account); } param->domain_table = domain_table; param->name_table.n_entry = n_entry; param->name_table.entries = names; param->mapped_count = n_mapped; if (n_mapped == n_entry) param->status = NT_STATUS_SUCCESS; else if (n_mapped == 0) param->status = NT_STATUS_NONE_MAPPED; else param->status = NT_STATUS_SOME_NOT_MAPPED; return (NDR_DRC_OK); lookup_sid_failed: smb_account_free(&account); bzero(param, sizeof (struct lsar_lookup_sids2)); return (NDR_DRC_FAULT_OUT_OF_MEMORY); }