Finally got it!
I was freeing the SID buffer ($R4) inside the LookupAccountName macro and as such the SetEntriesInAcl call would fail with error 87 (where did you find the 0x87 error Anders? It is not hex, it is a standard error code after all).
So for anyone who is interested here is a macro that will create a share giving read permission to a specified user. I am including more definitions in case someone wants to modify this in any way:
!include "LogicLib.nsh"
# Definitions and user flags
!define STYPE_DISKTREE 0
!define ACCESS_READ 0x01
!define ACCESS_WRITE 0x02
!define ACCESS_CREATE 0x04
!define ACCESS_EXEC 0x08
!define ACCESS_DELETE 0x10
!define ACCESS_ATRIB 0x20
!define ACCESS_PERM 0x40
!define ACCESS_ALL 0x7F
# Permissions
!define GENERIC_READ 0x80000000
!define GENERIC_WRITE 0x40000000
!define GENERIC_EXECUTE 0x20000000
!define GENERIC_ALL 0x10000000
!define NO_INHERITANCE 0x0
!define SECURITY_DESCRIPTOR_REVISION 1
# ACCESS_MODE values
!define NOT_USED_ACCESS 0
!define GRANT_ACCESS 1
!define SET_ACCESS 2
!define DENY_ACCESS 3
!define REVOKE_ACCESS 4
!define SET_AUDIT_SUCCESS 5
!define SET_AUDIT_FAILURE 6
# MULTIPLE_TRUSTEE_OPERATION values
!define NO_MULTIPLE_TRUSTEE 0
!define TRUSTEE_IS_IMPERSONATE 1
# TRUSTEE_FORM values
!define TRUSTEE_IS_SID 0
!define TRUSTEE_IS_NAME 1
!define TRUSTEE_BAD_FORM 2
!define TRUSTEE_IS_OBJECTS_AND_SID 3
!define TRUSTEE_IS_OBJECTS_AND_NAME 4
# TRUSTEE_TYPE values
!define TRUSTEE_IS_UNKNOWN 0
!define TRUSTEE_IS_USER 1
!define TRUSTEE_IS_GROUP 2
!define TRUSTEE_IS_DOMAIN 3
!define TRUSTEE_IS_ALIAS 4
!define TRUSTEE_IS_WELL_KNOWN_GROUP 5
!define TRUSTEE_IS_DELETED 6
!define TRUSTEE_IS_INVALID 7
!define TRUSTEE_IS_COMPUTER 8
# Structure Definitions
!define strSHARE_INFO_2 '(w,i,w,i,i,i,w,w)i'
!define strSHARE_INFO_502 '(w,i,w,i,i,i,w,w,i,i)i'
!define strEXPLICIT_ACCESS '(i,i,i,i,i,i,i,i)i'
!macro CreateNewShare USERNAME SHARENAME SHARE_TYPE SHARE_COMMENT SHARE_PERMISSIONS ACL_ACCESS MAX_USERS CURRENT_USES SHARE_PATH SHARE_PASS
# Get the user's SID from the username
System::Call /NOUNLOAD '*(&w${NSIS_MAX_STRLEN})i.R9'
System::Call /NOUNLOAD 'advapi32::LookupAccountNameA(,t "${USERNAME}",i R9,*i ${NSIS_MAX_STRLEN},w .R8,*i ${NSIS_MAX_STRLEN},*i .r4)i.r5'
System::Call /NOUNLOAD 'advapi32::ConvertSidToStringSid(i R9,*t .R8)i.r5'
${If} $R8 == ''
MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'User "${USERNAME}" does not exist!$\nAborting...'
System::Free $R9
Quit
${EndIf}
# Create an EXPLICIT_ACCESS structure and place it on $R6
System::Call /NOUNLOAD '*${strEXPLICIT_ACCESS}(${ACL_ACCESS},${SET_ACCESS},${NO_INHERITANCE},0, ${NO_MULTIPLE_TRUSTEE},${TRUSTEE_IS_SID},${TRUSTEE_IS_USER},$R9).R6'
System::Call /NOUNLOAD 'advapi32::SetEntriesInAclA(i 1,i R6,,*i .R5)i.r1'
${If} $1 <> 0
System::Free $R9
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 $R9
System::Free $R6
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 $R9
System::Free $R6
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 <> 0
MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'There was an error creating the share!'
${EndIf}
# Cleanup
System::Free $R9
System::Free $R6
System::Call 'kernel32::LocalFree(i R5)i.r0'
System::Free $R0
!macroend
In order to create a share and give it read access to the user jdoe call the macro like this:
!insertmacro CreateNewShare "jdoe" "Name for the share" ${STYPE_DISKTREE} "share description" ${ACCESS_ALL} ${GENERIC_READ}|${GENERIC_EXECUTE} -1 0 "C:\<some_folder_to_share>" ""
In order to create a share with full access for the user jdoe call the macro like this:
!insertmacro CreateNewShare "jdoe" "Name for the share" ${STYPE_DISKTREE} "share description" ${ACCESS_ALL} ${GENERIC_ALL} -1 0 "C:\<some_folder_to_share>" ""
and so on.
Thanks for the help guys!
CF