diff -urNp cyrus-sasl-2.1.22/plugins/ntlm.c cyrus-sasl-2.1.22-patch/plugins/ntlm.c --- cyrus-sasl-2.1.22/plugins/ntlm.c 2005-07-07 18:10:14.000000000 +0200 +++ cyrus-sasl-2.1.22-patch/plugins/ntlm.c 2008-05-04 14:56:54.000000000 +0200 @@ -1525,14 +1525,46 @@ static int ntlm_server_mech_step2(server struct propval auxprop_values[2]; unsigned char hash[NTLM_HASH_LENGTH]; unsigned char resp[NTLM_RESP_LENGTH]; + + unsigned char *combined_username = NULL; /* fetch user's password */ result = sparams->utils->prop_request(sparams->propctx, password_request); if (result != SASL_OK) goto cleanup; - /* this will trigger the getting of the aux properties */ - result = sparams->canon_user(sparams->utils->conn, authid, authid_len, + /////////////////////////////////////////////////////////////////// + // patch by office@chcnet.net + // rights: GPL + // older pop3, imap, smtp ntlm clients are sending first + // client-user: usernamex + // client-domain: NTDOMAIN/WORKGROUP + // and if thats denied by us, they retry with + // client-user: user@realdomainname.tld + // without a client domain + // outlook 2007 changed that behaviour to support properly + // also other mail servers. They are thus sending already (hurray!) + // as the first try: client-user: username + // and as client domain: the users emaildomain + /////////////////////////////////////////////////////////////////// + if (domain) { + // to match the outlook 2007 method + combined_username = sparams->utils->malloc(authid_len + domain_len + 1); + if (combined_username == NULL) { + MEMERROR(sparams->utils); + return SASL_NOMEM; + } + sprintf(combined_username, "%s@%s", authid, domain); + result = sparams->canon_user(sparams->utils->conn, combined_username, strlen(combined_username), SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + sparams->utils->free(combined_username); + } + else { + // use old method (ignore the first try and match the second + result = sparams->canon_user(sparams->utils->conn, authid, authid_len, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + } + + /* this will trigger the getting of the aux properties */ if (result != SASL_OK) goto cleanup; result = sparams->utils->prop_getnames(sparams->propctx,