title: LDAP in C/Go : Error code 53 "Server is unwilling to perfom" when trying to set unicodePwd
body: <p>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.</p>
  
  <p>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.</p>
  
  <p>Here are some samples of my code, im just testing stuff right now so the coding is really bad:</p>
  
  <p>Setting options :<code>C.ldap_set_option(l, LDAP_OPT_PROTOCOL_VERSION, unsafe.Pointer(&amp;version))
  C.ldap_set_option(l, LDAP_OPT_REFERRALS, unsafe.Pointer(&amp;v))</code></p>
  
  <p>Initialization:<code>C.ldap_initialize(&amp;l, C.CString("ldaps://**.**.**.**:636"))</code></p>
  
  <p>Binding:<code>rc := C.ldap_simple_bind_s(l, C.CString("CN=Administrator,CN=Users,DC=intra,DC=localdomain,DC=com"), C.CString("**********"))</code></p>
  
  <p>And now the important part, adding a user with a password :</p>
  
  <pre><code>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 = &amp;vclass[0]
  
  modCN.mod_op = 0
  modCN.mod_type = C.CString("cn")
  vcn[0] = C.CString("john")
  vcn[1] = nil
  modCN.mod_vals = &amp;vcn[0]
  
  modSN.mod_op = 0
  modSN.mod_type = C.CString("sn")
  vsn[0] = C.CString("mclane")
  vsn[1] = nil
  modSN.mod_vals = &amp;vsn[0]
  
  modPass.mod_op = 0
  modPass.mod_type = C.CString("unicodePwd")
  vpass[0] = C.CString("IgBTAHcAZQBlAHQATgBlAHcAUAB3AGQAMQAyADMAIQAiAA==")
  vpass[1] = nil
  modPass.mod_vals = &amp;vpass[0]
  
  mods[0] = &amp;modClass
  mods[1] = &amp;modCN
  mods[2] = &amp;modSN
  mods[3] = &amp;modPass
  mods[4] = nil
  
  dn := "cn=john,OU=*********,DC=intra,DC=localdomain,DC=com"
  
  rc := C._ldap_add(l, C.CString(dn), &amp;mods[0])
  
  if rc != LDAP_SUCCESS {
      er := C.ldap_err2string(rc)
      fmt.Println("ADD ERROR")
      fmt.Println(rc)
      fmt.Println(C.GoString(er))
  }
  </code></pre>
  
  <p>Oh, and heres the definition of the type LDAPModStr:</p>
  
  <pre><code>typedef struct ldapmod_str {
      int  mod_op;
      char      *mod_type;
      char    **mod_vals;} LDAPModStr;
  </code></pre>
  
  <p>And _ldap_add :</p>
  
  <pre><code>int _ldap_add(LDAP *ld, char* dn, LDAPModStr **attrs){
  
              return ldap_add_ext_s(ld, dn, (LDAPMod **)attrs, NULL, NULL);
          }
  </code></pre>
  
  <p>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.</p>