So i'm coding a program in Go, with C bindings thanks to CGo, and i'm using ldap to perform search, add and modify operations. I could manage to do all that, but now im trying to set a password in the unicodePwd mod_type and i can't seem to get around the Error 53: Server is unwilling to perfom.
I know a lot of stuff can cause this error so: I'm connected with ldaps. I hard-coded for testing purpose a password made of 10 characters, with double quotes at the beginning and the end, and got that in UTF-16LE, Base64. The password hase lowercase letters, uppercase letters and punctuations symbols.
Here are some samples of my code, im just testing stuff right now so the coding is really bad:
Setting options :C.ldap_set_option(l, LDAP_OPT_PROTOCOL_VERSION, unsafe.Pointer(&version))
C.ldap_set_option(l, LDAP_OPT_REFERRALS, unsafe.Pointer(&v))
Initialization:C.ldap_initialize(&l, C.CString("ldaps://**.**.**.**:636"))
Binding:rc := C.ldap_simple_bind_s(l, C.CString("CN=Administrator,CN=Users,DC=intra,DC=localdomain,DC=com"), C.CString("**********"))
And now the important part, adding a user with a password :
add_user(l, "ldaps://**.**.**.**", "636", "CN=Administrator,CN=Users,DC=intra,DC=localdomain,DC=com", "OU=*******,DC=intra,DC=localdomain,DC=com")
func add_user(l *C.LDAP, host string, port string, login string, container string) {
var mods [5]*C.LDAPModStr
var modClass, modCN, modSN, modPass C.LDAPModStr
var vclass [5]*C.char
var vcn [4]*C.char
var vsn [2]*C.char
var vpass [2]*C.char
modClass.mod_op = 0
modClass.mod_type = C.CString("objectclass")
vclass[0] = C.CString("top")
vclass[1] = C.CString("person")
vclass[2] = C.CString("organizationalPerson")
vclass[3] = C.CString("User")
vclass[4] = nil
modClass.mod_vals = &vclass[0]
modCN.mod_op = 0
modCN.mod_type = C.CString("cn")
vcn[0] = C.CString("john")
vcn[1] = nil
modCN.mod_vals = &vcn[0]
modSN.mod_op = 0
modSN.mod_type = C.CString("sn")
vsn[0] = C.CString("mclane")
vsn[1] = nil
modSN.mod_vals = &vsn[0]
modPass.mod_op = 0
modPass.mod_type = C.CString("unicodePwd")
vpass[0] = C.CString("IgBTAHcAZQBlAHQATgBlAHcAUAB3AGQAMQAyADMAIQAiAA==")
vpass[1] = nil
modPass.mod_vals = &vpass[0]
mods[0] = &modClass
mods[1] = &modCN
mods[2] = &modSN
mods[3] = &modPass
mods[4] = nil
dn := "cn=john,OU=*********,DC=intra,DC=localdomain,DC=com"
rc := C._ldap_add(l, C.CString(dn), &mods[0])
if rc != LDAP_SUCCESS {
er := C.ldap_err2string(rc)
fmt.Println("ADD ERROR")
fmt.Println(rc)
fmt.Println(C.GoString(er))
}
Oh, and heres the definition of the type LDAPModStr:
typedef struct ldapmod_str {
int mod_op;
char *mod_type;
char **mod_vals;} LDAPModStr;
And _ldap_add :
int _ldap_add(LDAP *ld, char* dn, LDAPModStr **attrs){
return ldap_add_ext_s(ld, dn, (LDAPMod **)attrs, NULL, NULL);
}
I'm probably missing something obvious here, since i'm kinda new to GO and LDAP, but if you could help me solve this i would really be grateful. I dont know if this is relevant but the programs connects to the Active Directory of Windows Server 2012 R2, which is running on the same computer in a virtual machine. Also i'm kinda new here, i can post all of my code here if its easier for you, but i thought posting just important steps was maybe better.