Skip to content
⌘ NSIS Forum Archive

Create share and multiples users by SID

9 posts

MehdiAli#

Create share and multiples users by SID

Hello,

My problem is the nearly the same of this thread :

Are you a developer who uses NSIS to distribute your application? Are you a Winamp plug-in developer who wants to use NSIS to distribute your plug-in? Have suggestions for other people like you? This is the place.


I want add multiples users on a share by SID, I tried to follow this link :


The problem is the script looked if the user (or group) is in the domain before to get his SID but it's not my case.

I tried to add myself by SID, in my script.
NB: MyMap is a hashmap with key = group and value = SID

Someone can help me to fix my problem, I cannot create a share and add groups by SID, thanks.

!macro CreateNewShare NAME1 NAME2 NAME3 SHARENAME SHARE_TYPE SHARE_COMMENT SHARE_PERMISSIONS ACL_ACCESS MAX_USERS CURRENT_USES SHARE_PATH SHARE_PASS
  ${Map.Get} $SID MyMap ${NAME1}
  System::Call 'ADVAPI32::ConvertStringSidToSid(ts,*p.r1)i.r5' "$SID" 
  ${Map.Get} $SID MyMap ${NAME2}
  System::Call 'ADVAPI32::ConvertStringSidToSid(ts,*p.r2)i.5' "$SID" 
  ${If} ${NAME3} != ''
    ${Map.Get} $SID MyMap ${NAME3}
    System::Call 'ADVAPI32::ConvertStringSidToSid(ts,*p.r3)i.r5' "$SID" 
  ${Endif}
# Create an EXPLICIT_ACCESS structure that contains users and place it on $R6
  System::Call /NOUNLOAD '*(i ${ACL_ACCESS},i ${SET_ACCESS},i ${NO_INHERITANCE},i 0,i ${NO_MULTIPLE_TRUSTEE},i ${TRUSTEE_IS_SID},i ${TRUSTEE_IS_GROUP},i $R9,i ${ACL_ACCESS},i ${SET_ACCESS},i ${NO_INHERITANCE},i 0,i ${NO_MULTIPLE_TRUSTEE},i ${TRUSTEE_IS_SID},i ${TRUSTEE_IS_GROUP},i $R7)i.R6'
  System::Call /NOUNLOAD 'advapi32::SetEntriesInAclA(i $NBGROUP,i R6,,*i .R5)i.r1'
  ${If} $1 <> 0
    System::Free $R6
    Quit
  ${EndIf}
# Create an empty security descriptor and place it in R4.
  System::Alloc ${NSIS_MAX_STRLEN}
  Pop $R4
  System::Call /NOUNLOAD 'advapi32::InitializeSecurityDescriptor(i R4,i ${SECURITY_DESCRIPTOR_REVISION})i.r1'
  ${If} $1 == 0
    System::Free $R6
    System::Call 'KERNEL32::LocalFree(pr1)' 
    System::Call 'KERNEL32::LocalFree(pr2)'
    System::Call 'KERNEL32::LocalFree(pr3)' 
    System::Call 'kernel32::LocalFree(i R5)i.r0'
    Quit
  ${EndIf}
# Add the ACL to the security descriptor
  System::Call /NOUNLOAD 'advapi32::SetSecurityDescriptorDacl(i R4,i 1,i R5,i 0)i.r1'
  ${If} $1 == 0
    System::Free $R6
    System::Call 'KERNEL32::LocalFree(pr1)' 
    System::Call 'KERNEL32::LocalFree(pr2)'
    System::Call 'KERNEL32::LocalFree(pr3)' 
    System::Call 'kernel32::LocalFree(i R5)i.r0'
    Quit
  ${EndIf}
# Generate the structure that holds the share info and place it on $R0
  System::Call /NOUNLOAD '*${strSHARE_INFO_502}("${SHARENAME}",${SHARE_TYPE},"${SHARE_COMMENT}",${SHARE_PERMISSIONS},${MAX_USERS},${CURRENT_USES},"${SHARE_PATH}","${SHARE_PASS}",0,R4).R0'
  System::Call /NOUNLOAD 'netapi32::NetShareAdd(".", i 502, i R0, *i .R1) i .r1'
  ${If} $1 = 2118
    ${if} ${Silent}
        !insertmacro SilentMode "Folder ${SHARE_PATH} has already been shared!"
        Quit
    ${Else}
        DetailPrint 'Folder "${SHARE_PATH}" has already been shared!'
        FileWrite $LOG_FH 'Folder "${SHARE_PATH}" has already been shared!'
    ${EndIf}
  ${EndIf}
  ${If} $1 <> 0
  ${AndIf} $1 <> 2118
    ${if} ${Silent}
        !insertmacro SilentMode "Error encountered while creating share ${SHARENAME} on ${SHARE_PATH}"
    ${Else}
        DetailPrint 'Error encountered while creating share ${SHARENAME} on ${SHARE_PATH}'
        FileWrite $LOG_FH 'Error encountered while creating share ${SHARENAME} on ${SHARE_PATH}$\r$\n'
    ${EndIf}
    Abort
  ${Else}
    DetailPrint "${SHARENAME} share added on ${SHARE_PATH}"
    FileWrite $LOG_FH "${SHARENAME} share added on ${SHARE_PATH}$\r$\n"
  ${EndIf}
# Cleanup
  System::Free $R6
  System::Call 'KERNEL32::LocalFree(pr1)' 
  System::Call 'KERNEL32::LocalFree(pr2)'
  System::Call 'KERNEL32::LocalFree(pr3)' 
  System::Call 'kernel32::LocalFree(i R5)i.r0'
  System::Free $R0
!macroend 
Anders#
Add DetailPrint with the return value after every System::Call to narrow down where the problem is...
MehdiAli#
Hello Anders,

Here

${Map.Get} $SID MyMap ${NAME1}
System::Call 'ADVAPI32::ConvertStringSidToSid(ts,*p.r1)i.r5' "$SID"
${Map.Get} $SID MyMap ${NAME2}
System::Call 'ADVAPI32::ConvertStringSidToSid(ts,*p.r2)i.5' "$SID"

Both System::Call return 1 but when I print the SID, I have a valid SID.

The syntax isn't good ?
MehdiAli#
Hello,

Sorry for the delay

The problem seem be this line :
System::Call /NOUNLOAD '*(i ${ACL_ACCESS},i ${SET_ACCESS},i ${NO_INHERITANCE},i 0,i ${NO_MULTIPLE_TRUSTEE},i ${TRUSTEE_IS_SID},i ${TRUSTEE_IS_GROUP},i $R9,i ${ACL_ACCESS},i ${SET_ACCESS},i ${NO_INHERITANCE},i 0,i ${NO_MULTIPLE_TRUSTEE},i ${TRUSTEE_IS_SID},i ${TRUSTEE_IS_GROUP},i $R7)i.R6' 
In this link, R7 and R9 doesn't exist because I use only ConvertSidToStringSID, I don't know how use this call without R7 and R9.
Anders#
You are merging code from different places so of course you have to adjust the variables used etc.
MehdiAli#
The problem seems be : LPTSTR ptstrName;
Identifies the user account, group account, or logon session to which an access control entry (ACE) applies. (ANSI)


I can give it "Pointer to the SID of the trustee."

At the start of my macro I do
"System::Call 'ADVAPI32::ConvertStringSidToSid(ts,*p.r1)i.r5' "$SID"

Can I stock also this Call in another stake like R7 or R9 ?

After that, I can give R7 or R9 in order to ptstrName is valid.

Thanks
MehdiAli#
Hello,

I tried to fix the problem with this code

  ${Map.Get} $SID MyMap ${NAME1}
  DetailPrint "Le SID : $SID"
  System::Call 'ADVAPI32::ConvertStringSidToSid(ts,*p.r1)i.r5' "$SID"
  DetailPrint "This check is OK $1"
  ${Map.Get} $SID MyMap ${NAME2}
  DetailPrint "Le SID : $SID"
  System::Call 'ADVAPI32::ConvertStringSidToSid(ts,*p.r2)i.5' "$SID" 
  DetailPrint "This check is OK $5"
  ; ${If} ${NAME3} != ""
    ; ${Map.Get} $SID MyMap ${NAME3}
    ; System::Call 'ADVAPI32::ConvertStringSidToSid(ts,*p.r3)i.r5' "$SID" 
    ; DetailPrint "CHECK $5"
  ; ${Endif}
# Create an EXPLICIT_ACCESS structure that contains users and place it on $R6
  System::Call /NOUNLOAD '*(i ${ACL_ACCESS},i ${SET_ACCESS},i ${NO_INHERITANCE},i 0,i ${NO_MULTIPLE_TRUSTEE},i ${TRUSTEE_IS_SID},i ${TRUSTEE_IS_GROUP},i $1,i ${ACL_ACCESS},i ${SET_ACCESS},i ${NO_INHERITANCE},i 0,i ${NO_MULTIPLE_TRUSTEE},i ${TRUSTEE_IS_SID},i ${TRUSTEE_IS_GROUP},i $2)i.R6'
  System::Call /NOUNLOAD 'advapi32::SetEntriesInAclA(i 2,i R6,,*i .R5)i.r1'
  DetailPrint "CHECK $1" 
but it doesn't work. For PEXPLICIT_ACCESS, I give $1 and $2 which are the Sid of the first group and the sid of the second group ?

Do you have any idea why it doesn't valid like that ?

Thanks
Anders#
SetEntriesInAcl returns 0 on success, you have to lookup each function on MSDN when checking the return value.

Section
!define MyAccessPermissions "${GENERIC_ALL}"
System::Call 'ADVAPI32::ConvertStringSidToSid(ts,*p0r1)i.r0' "S-1-5-32-545"
DetailPrint "ConvertStringSidToSid success=$0, PSID=$1"
System::Call 'ADVAPI32::ConvertStringSidToSid(ts,*p0r2)i.r0' "S-1-5-32-544"
DetailPrint "ConvertStringSidToSid success=$0, PSID=$2"
System::Call '*(i ${MyAccessPermissions},i ${SET_ACCESS},i ${NO_INHERITANCE},p 0,i ${NO_MULTIPLE_TRUSTEE},i ${TRUSTEE_IS_SID},i ${TRUSTEE_IS_GROUP},p $1,i ${MyAccessPermissions},i ${SET_ACCESS},i ${NO_INHERITANCE},p 0,i ${NO_MULTIPLE_TRUSTEE},i ${TRUSTEE_IS_SID},i ${TRUSTEE_IS_GROUP},p $2)i.R6'
DetailPrint 'EXPLICIT_ACCESS array: $R6'
StrCmp $R6 "" freesids
System::Call 'ADVAPI32::SetEntriesInAcl(i 2, p R6, p0, *p 0 R5)i.r0'
System::Free $R6
DetailPrint "SetEntriesInAcl error=$0, PACL=$R5"
IntCmp $0 0 "" freesids freesids
DetailPrint "Do something with PACL=$R5..."
freeacl:
System::Call 'KERNEL32::LocalFree(pR5)'
freesids:
System::Call 'KERNEL32::LocalFree(pr1)'
System::Call 'KERNEL32::LocalFree(pr2)'
SectionEnd