A participant using transaction to update/add another participant - hyperledger-composer

Suppose I create two Participant type A and B respectively, and a transaction X which can only be executed by participant type B or admin.
Moreover, I added some permission rule that Participant A can be created/updated only by the admin or other Participant of type A.
Now, my logic in transaction X requires creation/updating of Participant A. So, If I execute the transaction X using one of the Participant B registry ID, will it be able to create/update the participant A? If not, then is there any way to do so?

If I have understood your requirement correctly, then these rules should work for the core of what you want:
(This example uses the default Basic Sample Network)
rule BforX {
description: "Allow B access to transaction X"
participant: "org.example.basic.SampleParticipantB"
operation: READ, CREATE, UPDATE
resource: "org.example.basic.SampleTransactionX"
action: ALLOW
}
rule BforAinX {
description: "Allow B access to A whilst in X"
participant: "org.example.basic.SampleParticipantB"
operation: READ, CREATE, UPDATE
resource: "org.example.basic.SampleParticipantA"
transaction: "org.example.basic.SampleTransactionX"
action: ALLOW
}
rule NotAforX {
description: "Deny A access to transaction X"
participant: "org.example.basic.SampleParticipantA"
operation: ALL
resource: "org.example.basic.SampleTransactionX"
action: DENY
}
rule AforA {
description: "Allow A access to Participant_A"
participant: "org.example.basic.SampleParticipantA"
operation: READ, CREATE, UPDATE
resource: "org.example.basic.SampleParticipantA"
action: ALLOW
}

Related

How can I use the `close_account` function properly in order to close an Associated Token Account?

I am trying to close an Associated Token Account (ATA) from inside a program. The ATA belongs to the program. I found a function called close_account, but I haven't figured out how to use it properly. I'm using Anchor.
The desired flow of my program is:
Send a token from the program ATA to the user ATA (I've done this successfully)
Close the program ATA that was used for the token
This is what the implementation of close_account looks like:
pub fn close_account<'a, 'b, 'c, 'info>(
ctx: CpiContext<'a, 'b, 'c, 'info, CloseAccount<'info>>,
) -> Result<()> {
let ix = spl_token::instruction::close_account(
&spl_token::ID,
ctx.accounts.account.key,
ctx.accounts.destination.key,
ctx.accounts.authority.key,
&[], // TODO: support multisig
)?;
solana_program::program::invoke_signed(
&ix,
&[
ctx.accounts.account.clone(),
ctx.accounts.destination.clone(),
ctx.accounts.authority.clone(),
],
ctx.signer_seeds,
)
.map_err(Into::into)
}
The CloseAccount struct looks as follows:
#[derive(Accounts)]
pub struct CloseAccount<'info> {
pub account: AccountInfo<'info>,
pub destination: AccountInfo<'info>,
pub authority: AccountInfo<'info>,
}
(I assume) the account is the ATA and the authority is my program - but what is the destination in this context? Why would closing an account need a destination and which account should I use as the destination account?
what is the destination in this context? Why would closing an account need a destination and which account should I use as the destination account?
Since token accounts are like any other account in Solana, they must have enough SOL to cover the minimum balance requirement. When closing an account, you must send that SOL somewhere else, hence the "destination". The best option is to use a wallet / SOL account that is only used for SOL and nothing else.
More info at https://spl.solana.com/token#closing-accounts

Could not create program address with signer seeds when creating a token account

I have a PDA and I'm trying to create a token account for it, using Solana Spl Associated Token Account(https://spl.solana.com/associated-token-account):
let (token_account_key, token_account_key_bump_seed) = Pubkey::find_program_address(&[&stake_info_bytes, &token_program_bytes, &mint_address_bytes], spl_associated_token_program.key);
Now I'm trying to create the account:
let account_rent = rent.minimum_balance(Account::LEN);
let authority_signature_seeds = [&stake_info_bytes[..32], &token_program_bytes[..32], &mint_address_bytes[..32], &[token_account_key_bump_seed]];
let signers = &[&authority_signature_seeds[..]];
let create_ix = create_account(
feepayer.key,
token_account.key,
account_rent,
Account::LEN as u64,
spl_associated_token_program.key
);
invoke_signed(&create_ix, &[
spl_associated_token_program.clone(),
feepayer.clone(),
token_account.clone()
], signers);
But I'm getting this error:
> Program returned error: Could not create program address with signer seeds: Provided seeds do not result in a valid address
With PDAs, your program can only "sign" for PDAs generated using its program id. In this case, your program is using the associated token account program as the program id, when it should be using itself. So this should become:
let (token_account_key, token_account_key_bump_seed) = Pubkey::find_program_address(&[&stake_info_bytes, &token_program_bytes, &mint_address_bytes], my_program_id);
Using your program's id as my_program_id, and then you would actually use this as:
let create_ix = create_account(
feepayer.key,
token_account.key,
account_rent,
Account::LEN as u64,
spl_token_program.key
);
invoke_signed(&create_ix, &[
feepayer.clone(),
token_account.clone()
], signers);
Note: I'm assuming that you're trying to create a token account, which must be owned by the token program.
Otherwise, it would be possible to fake "signatures" for another program, which would be a huge security risk. For example, associated token accounts must be signed and created by the associated token account program.

My Token.createMintToInstruction is throwing "Error processing instruction 0: invalid account data for instruction"

I'm trying to mint some tokens on the frontend like this:
let transaction = new Transaction();
let mintToInstruction = Token.createMintToInstruction(
splToken.TOKEN_PROGRAM_ID,
myTokenMint.publicKey,
userAccount.publicKey,
airdropAdmin.publicKey,
[],
sendAmount.toNumber()
)
transaction.add(mintToInstruction);
let conn: Connection = ctx.connection;
const tx1 = await conn.sendTransaction(
transaction,
[airdropAdmin]
);
But I get an obscure error:
Error processing Instruction 0: invalid account data for instruction
What's happening?
One of the accounts you're passing in is not the account the Token Program expected.
Either:
The userAccount is incorrect. This must be a Token Account, did you use the user's System Account instead?
The myMintAccount is incorrect. Is this a real token mint?
Consider logging those public keys and putting them into the explorer. Does the userAccount say "Token Account" at the top? Does the myMintAccount say "Token Mint"?
The invalid account data for instruction typically happens when a program can't run unpack on the data inside the account you're passing in.
So either the Account::unpack is failing, or the the Mint::unpack is failing.

Spring LDAP querybuilder PartialResultException

I'm trying to get all the users from my LDAP server, doing the search from the base, this is my code:
public LdapTemplate ldapTemplate() {
LdapContextSource ctxSrc = new LdapContextSource();
ctxSrc.setUrl("ldap://127.0.0.1:389/");
ctxSrc.setBase("dc=test,dc=com");
ctxSrc.setUserDn("admin");
ctxSrc.setPassword("password");
ctxSrc.afterPropertiesSet();
LdapTemplate lt = new LdapTemplate(ctxSrc);
return lt;
}
private LdapTemplate ldapTemplate = ldapTemplate();
public List<User> getAllUsers() {
LdapQuery query= query().base("").where("objectclass").is("user");
return ldapTemplate.search(query, new UserAttributesMapper());
}
This is the error:
10:07:09.406 [main] DEBUG o.s.l.c.s.AbstractContextSource - AuthenticationSource not set - using default implementation
10:07:09.413 [main] DEBUG o.s.l.c.s.AbstractContextSource - Not using LDAP pooling
10:07:09.416 [main] DEBUG o.s.l.c.s.AbstractContextSource - Trying provider Urls: ldap://127.0.0.1:389/dc=test,dc=com
10:07:09.548 [main] DEBUG o.s.l.c.s.AbstractContextSource - Got Ldap context on server 'ldap://127.0.0.1:389/dc=test,dc=com'
Exception in thread "main" org.springframework.ldap.PartialResultException: Unprocessed Continuation Reference(s); nested exception is javax.naming.PartialResultException: Unprocessed Continuation Reference(s); remaining name '/'
at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:216)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:385)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:309)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:616)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:586)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:1651)
at ldap.example.UserRepositoryImpl.getAllUsers(UserRepositoryImpl.java:81)
at ldap.example.test.LdapApp.main(LdapApp.java:23)
Caused by: javax.naming.PartialResultException: Unprocessed Continuation Reference(s); remaining name '/'
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2914)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2888)
at com.sun.jndi.ldap.AbstractLdapNamingEnumeration.getNextBatch(AbstractLdapNamingEnumeration.java:148)
at com.sun.jndi.ldap.AbstractLdapNamingEnumeration.hasMoreImpl(AbstractLdapNamingEnumeration.java:217)
at com.sun.jndi.ldap.AbstractLdapNamingEnumeration.hasMore(AbstractLdapNamingEnumeration.java:189)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:365)
... 6 more
BUILD FAILED (total time: 1 second)
When I filter by ou it works, but I need to filter from the root.
You write in question's comment that changing port helps.
But changing port doesn't solve this problem.
Port 3268 points to Active Directory special place - Global Catalog. There is set of all object - but each of them has only small subset of attributes (for example distinguishedName, cn, sAMAccountName...).
So - it works until you don't need more specific attributes.
Problem analysis
The exception occurs because AD, as the result of your query, returns referral objects:
[Active Directory] (...) generate referrals in response to queries that request data about objects that exist in the forest, but not contained on the directory server handling the request. These are called internal cross references, because they refer to domains, schema, and configuration containers within the forest.
And if referral chasing is disabled:
If referral chasing is not enabled and a subtree search is performed, the search will return all objects within the specified domain that meet the search criteria. The search will also return referrals to any subordinate domains that are direct descendants of the directory server domain. The client must resolve the referrals by binding to the path specified by the referral and submitting another query.
You can enable referral chasing, but it cost - it slow down application - you can read about this here. And I think it is not necessary in most cases.
Solution 1:
Sometimes the sufficient solution is to assign more specific baseDN - ctxSrc.setBase() method in your question. Maybe all your users are inside inner path e.g "ou=user,dc=department,dc=test,dc=com".
Read more in this answer.
Solution 2:
In Spring LdapTemplate you can also ignore this exception with method setIgnorePartialResultException():
ldapTemplate.setIgnorePartialResultException(true);
Read more in this answer.

How to add synchronisation right in a SDDL string for CreateEvent

My Windows service creates 2 Events with CreateEvent for communication with a user app.
The service and the user app are not running under the same user account.
The user app opens the event and set it to signaled without error. But the event is never received by the service. The other event works in the opposite direction.
So I think the events miss the syncronization right.
Service:
SECURITY_ATTRIBUTES security;
ZeroMemory(&security, sizeof(security));
security.nLength = sizeof(security);
ConvertStringSecurityDescriptorToSecurityDescriptor(L"D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GWGR;;;IU)", SDDL_REVISION_1, &security.lpSecurityDescriptor, NULL);
EvtCreateNewUserSession = CreateEventW(
&security, // security attributes
TRUE, // manual-reset event
FALSE, // initial state is not signaled
L"Global\\MyEvent" // object name
);
Interactive App:
HANDLE EvtCreateNewUserSession = OpenEventW(
EVENT_MODIFY_STATE | SYNCHRONIZE, // default security attributes
FALSE, // initial state is not signaled
L"Global\\MyEvent" // object name
;
Thanks for your help,
Olivier
Instead of using 'string SDDL rights' (like GA) use 0xXXXXXXXX format (you can combine flags and then convert them to hex-string).
For example this SDDL: D:(A;;0x001F0003;;;BA)(A;;0x00100002;;;AU) creates DACL for:
- BA=Administrators, 0x001F0003=EVENT_ALL_ACCESS (LocalSystem and LocalService are in Administrators group, but NetworkService is not)
- AU=Authenticated Users, 0x00100002=SYNCHRONIZE | EVENT_MODIFY_STATE
http://msdn.microsoft.com/en-us/library/windows/desktop/aa374928(v=vs.85).aspx - field rights
A string that indicates the access rights controlled by the ACE.
This string can be a hexadecimal string representation of the access rights,
such as "0x7800003F", or it can be a concatenation of the following strings.
...

Resources