17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate /* SASL server API implementation
77c478bd9Sstevel@tonic-gate * Rob Siemborski
87c478bd9Sstevel@tonic-gate * Tim Martin
97c478bd9Sstevel@tonic-gate * $Id: checkpw.c,v 1.62 2003/03/19 18:25:27 rjs3 Exp $
107c478bd9Sstevel@tonic-gate */
11*1da57d55SToomas Soome /*
127c478bd9Sstevel@tonic-gate * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
157c478bd9Sstevel@tonic-gate * modification, are permitted provided that the following conditions
167c478bd9Sstevel@tonic-gate * are met:
177c478bd9Sstevel@tonic-gate *
187c478bd9Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
19*1da57d55SToomas Soome * notice, this list of conditions and the following disclaimer.
207c478bd9Sstevel@tonic-gate *
217c478bd9Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
227c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
237c478bd9Sstevel@tonic-gate * the documentation and/or other materials provided with the
247c478bd9Sstevel@tonic-gate * distribution.
257c478bd9Sstevel@tonic-gate *
267c478bd9Sstevel@tonic-gate * 3. The name "Carnegie Mellon University" must not be used to
277c478bd9Sstevel@tonic-gate * endorse or promote products derived from this software without
287c478bd9Sstevel@tonic-gate * prior written permission. For permission or any other legal
29*1da57d55SToomas Soome * details, please contact
307c478bd9Sstevel@tonic-gate * Office of Technology Transfer
317c478bd9Sstevel@tonic-gate * Carnegie Mellon University
327c478bd9Sstevel@tonic-gate * 5000 Forbes Avenue
337c478bd9Sstevel@tonic-gate * Pittsburgh, PA 15213-3890
347c478bd9Sstevel@tonic-gate * (412) 268-4387, fax: (412) 268-7395
357c478bd9Sstevel@tonic-gate * tech-transfer@andrew.cmu.edu
367c478bd9Sstevel@tonic-gate *
377c478bd9Sstevel@tonic-gate * 4. Redistributions of any form whatsoever must retain the following
387c478bd9Sstevel@tonic-gate * acknowledgment:
397c478bd9Sstevel@tonic-gate * "This product includes software developed by Computing Services
407c478bd9Sstevel@tonic-gate * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
417c478bd9Sstevel@tonic-gate *
427c478bd9Sstevel@tonic-gate * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
437c478bd9Sstevel@tonic-gate * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
447c478bd9Sstevel@tonic-gate * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
457c478bd9Sstevel@tonic-gate * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
467c478bd9Sstevel@tonic-gate * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
477c478bd9Sstevel@tonic-gate * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
487c478bd9Sstevel@tonic-gate * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
497c478bd9Sstevel@tonic-gate */
507c478bd9Sstevel@tonic-gate
517c478bd9Sstevel@tonic-gate #include <config.h>
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate /* checkpw stuff */
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate #include <stdio.h>
567c478bd9Sstevel@tonic-gate #include "sasl.h"
577c478bd9Sstevel@tonic-gate #include "saslutil.h"
587c478bd9Sstevel@tonic-gate #include "saslplug.h"
597c478bd9Sstevel@tonic-gate #include "saslint.h"
607c478bd9Sstevel@tonic-gate
617c478bd9Sstevel@tonic-gate #include <assert.h>
627c478bd9Sstevel@tonic-gate #ifdef HAVE_UNISTD_H
637c478bd9Sstevel@tonic-gate #include <unistd.h>
647c478bd9Sstevel@tonic-gate #endif
657c478bd9Sstevel@tonic-gate #include <fcntl.h>
667c478bd9Sstevel@tonic-gate #ifdef USE_DOORS
677c478bd9Sstevel@tonic-gate #include <sys/mman.h>
687c478bd9Sstevel@tonic-gate #include <door.h>
697c478bd9Sstevel@tonic-gate #endif
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate #include <stdlib.h>
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate #ifndef WIN32
747c478bd9Sstevel@tonic-gate #include <strings.h>
757c478bd9Sstevel@tonic-gate #include <netdb.h>
767c478bd9Sstevel@tonic-gate #include <netinet/in.h>
777c478bd9Sstevel@tonic-gate #include <sys/un.h>
787c478bd9Sstevel@tonic-gate #else
797c478bd9Sstevel@tonic-gate #include <string.h>
807c478bd9Sstevel@tonic-gate #endif
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gate #include <sys/types.h>
837c478bd9Sstevel@tonic-gate #include <ctype.h>
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gate #ifdef HAVE_PWD_H
867c478bd9Sstevel@tonic-gate #include <pwd.h>
877c478bd9Sstevel@tonic-gate #endif /* HAVE_PWD_H */
887c478bd9Sstevel@tonic-gate #ifdef HAVE_SHADOW_H
897c478bd9Sstevel@tonic-gate #include <shadow.h>
907c478bd9Sstevel@tonic-gate #endif /* HAVE_SHADOW_H */
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate #if defined(HAVE_PWCHECK) || defined(HAVE_SASLAUTHD)
937c478bd9Sstevel@tonic-gate # include <errno.h>
947c478bd9Sstevel@tonic-gate # include <sys/types.h>
957c478bd9Sstevel@tonic-gate # include <sys/socket.h>
967c478bd9Sstevel@tonic-gate # include <sys/un.h>
977c478bd9Sstevel@tonic-gate # ifdef HAVE_UNISTD_H
987c478bd9Sstevel@tonic-gate # include <unistd.h>
997c478bd9Sstevel@tonic-gate # endif
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate extern int errno;
1027c478bd9Sstevel@tonic-gate #endif
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate /* we store the following secret to check plaintext passwords:
1067c478bd9Sstevel@tonic-gate *
1077c478bd9Sstevel@tonic-gate * <salt> \0 <secret>
1087c478bd9Sstevel@tonic-gate *
1097c478bd9Sstevel@tonic-gate * where <secret> = MD5(<salt>, "sasldb", <pass>)
1107c478bd9Sstevel@tonic-gate */
1117c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
_sasl_make_plain_secret(const sasl_utils_t * utils,const char * salt,const char * passwd,size_t passlen,sasl_secret_t ** secret)1127c478bd9Sstevel@tonic-gate static int _sasl_make_plain_secret(const sasl_utils_t *utils, const char *salt,
1137c478bd9Sstevel@tonic-gate const char *passwd, size_t passlen,
1147c478bd9Sstevel@tonic-gate sasl_secret_t **secret)
1157c478bd9Sstevel@tonic-gate #else
116*1da57d55SToomas Soome static int _sasl_make_plain_secret(const char *salt,
1177c478bd9Sstevel@tonic-gate const char *passwd, size_t passlen,
1187c478bd9Sstevel@tonic-gate sasl_secret_t **secret)
1197c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
1207c478bd9Sstevel@tonic-gate {
1217c478bd9Sstevel@tonic-gate MD5_CTX ctx;
1227c478bd9Sstevel@tonic-gate unsigned sec_len = 16 + 1 + 16; /* salt + "\0" + hash */
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
1257c478bd9Sstevel@tonic-gate *secret = (sasl_secret_t *)utils->malloc(sizeof(sasl_secret_t) +
1267c478bd9Sstevel@tonic-gate sec_len * sizeof(char));
1277c478bd9Sstevel@tonic-gate #else
1287c478bd9Sstevel@tonic-gate *secret = (sasl_secret_t *) sasl_ALLOC(sizeof(sasl_secret_t) +
1297c478bd9Sstevel@tonic-gate sec_len * sizeof(char));
1307c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
1317c478bd9Sstevel@tonic-gate if (*secret == NULL) {
1327c478bd9Sstevel@tonic-gate return SASL_NOMEM;
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate _sasl_MD5Init(&ctx);
1367c478bd9Sstevel@tonic-gate _sasl_MD5Update(&ctx, salt, 16);
1377c478bd9Sstevel@tonic-gate _sasl_MD5Update(&ctx, "sasldb", 6);
1387c478bd9Sstevel@tonic-gate _sasl_MD5Update(&ctx, passwd, passlen);
1397c478bd9Sstevel@tonic-gate memcpy((*secret)->data, salt, 16);
1407c478bd9Sstevel@tonic-gate (*secret)->data[16] = '\0';
1417c478bd9Sstevel@tonic-gate _sasl_MD5Final((*secret)->data + 17, &ctx);
1427c478bd9Sstevel@tonic-gate (*secret)->len = sec_len;
143*1da57d55SToomas Soome
1447c478bd9Sstevel@tonic-gate return SASL_OK;
1457c478bd9Sstevel@tonic-gate }
1467c478bd9Sstevel@tonic-gate
1477c478bd9Sstevel@tonic-gate /* erase & dispose of a sasl_secret_t
1487c478bd9Sstevel@tonic-gate */
auxprop_verify_password(sasl_conn_t * conn,const char * userstr,const char * passwd,const char * service,const char * user_realm)1497c478bd9Sstevel@tonic-gate static int auxprop_verify_password(sasl_conn_t *conn,
1507c478bd9Sstevel@tonic-gate const char *userstr,
1517c478bd9Sstevel@tonic-gate const char *passwd,
1527c478bd9Sstevel@tonic-gate const char *service __attribute__((unused)),
1537c478bd9Sstevel@tonic-gate const char *user_realm __attribute__((unused)))
1547c478bd9Sstevel@tonic-gate {
1557c478bd9Sstevel@tonic-gate int ret = SASL_FAIL;
1567c478bd9Sstevel@tonic-gate char *userid = NULL;
1577c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
1587c478bd9Sstevel@tonic-gate char *realm = NULL;
1597c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
1607c478bd9Sstevel@tonic-gate int result = SASL_OK;
1617c478bd9Sstevel@tonic-gate sasl_server_conn_t *sconn = (sasl_server_conn_t *)conn;
1627c478bd9Sstevel@tonic-gate const char *password_request[] = { SASL_AUX_PASSWORD,
1637c478bd9Sstevel@tonic-gate "*cmusaslsecretPLAIN",
1647c478bd9Sstevel@tonic-gate NULL };
1657c478bd9Sstevel@tonic-gate struct propval auxprop_values[3];
166*1da57d55SToomas Soome
1677c478bd9Sstevel@tonic-gate if (!conn || !userstr)
1687c478bd9Sstevel@tonic-gate return SASL_BADPARAM;
1697c478bd9Sstevel@tonic-gate
170*1da57d55SToomas Soome /* We need to clear any previous results and re-canonify to
1717c478bd9Sstevel@tonic-gate * ensure correctness */
1727c478bd9Sstevel@tonic-gate
1737c478bd9Sstevel@tonic-gate prop_clear(sconn->sparams->propctx, 0);
174*1da57d55SToomas Soome
1757c478bd9Sstevel@tonic-gate /* ensure its requested */
1767c478bd9Sstevel@tonic-gate result = prop_request(sconn->sparams->propctx, password_request);
1777c478bd9Sstevel@tonic-gate
1787c478bd9Sstevel@tonic-gate if(result != SASL_OK) return result;
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate result = _sasl_canon_user(conn, userstr, 0,
1817c478bd9Sstevel@tonic-gate SASL_CU_AUTHID | SASL_CU_AUTHZID,
1827c478bd9Sstevel@tonic-gate &(conn->oparams));
1837c478bd9Sstevel@tonic-gate if(result != SASL_OK) return result;
184*1da57d55SToomas Soome
1857c478bd9Sstevel@tonic-gate result = prop_getnames(sconn->sparams->propctx, password_request,
1867c478bd9Sstevel@tonic-gate auxprop_values);
1877c478bd9Sstevel@tonic-gate if(result < 0)
1887c478bd9Sstevel@tonic-gate return result;
1897c478bd9Sstevel@tonic-gate
1907c478bd9Sstevel@tonic-gate if((!auxprop_values[0].name
1917c478bd9Sstevel@tonic-gate || !auxprop_values[0].values || !auxprop_values[0].values[0])
1927c478bd9Sstevel@tonic-gate && (!auxprop_values[1].name
1937c478bd9Sstevel@tonic-gate || !auxprop_values[1].values || !auxprop_values[1].values[0]))
1947c478bd9Sstevel@tonic-gate return SASL_NOUSER;
195*1da57d55SToomas Soome
1967c478bd9Sstevel@tonic-gate /* It is possible for us to get useful information out of just
1977c478bd9Sstevel@tonic-gate * the lookup, so we won't check that we have a password until now */
1987c478bd9Sstevel@tonic-gate if(!passwd) {
1997c478bd9Sstevel@tonic-gate ret = SASL_BADPARAM;
2007c478bd9Sstevel@tonic-gate goto done;
2017c478bd9Sstevel@tonic-gate }
2027c478bd9Sstevel@tonic-gate
2037c478bd9Sstevel@tonic-gate /* At the point this has been called, the username has been canonified
2047c478bd9Sstevel@tonic-gate * and we've done the auxprop lookup. This should be easy. */
2057c478bd9Sstevel@tonic-gate if(auxprop_values[0].name
2067c478bd9Sstevel@tonic-gate && auxprop_values[0].values
2077c478bd9Sstevel@tonic-gate && auxprop_values[0].values[0]
2087c478bd9Sstevel@tonic-gate && !strcmp(auxprop_values[0].values[0], passwd)) {
2097c478bd9Sstevel@tonic-gate /* We have a plaintext version and it matched! */
2107c478bd9Sstevel@tonic-gate return SASL_OK;
2117c478bd9Sstevel@tonic-gate } else if(auxprop_values[1].name
2127c478bd9Sstevel@tonic-gate && auxprop_values[1].values
2137c478bd9Sstevel@tonic-gate && auxprop_values[1].values[0]) {
2147c478bd9Sstevel@tonic-gate const char *db_secret = auxprop_values[1].values[0];
2157c478bd9Sstevel@tonic-gate sasl_secret_t *construct;
216*1da57d55SToomas Soome
2177c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
2187c478bd9Sstevel@tonic-gate ret = _sasl_make_plain_secret(sconn->sparams->utils, db_secret,
2197c478bd9Sstevel@tonic-gate passwd, strlen(passwd),
2207c478bd9Sstevel@tonic-gate &construct);
2217c478bd9Sstevel@tonic-gate #else
2227c478bd9Sstevel@tonic-gate ret = _sasl_make_plain_secret(db_secret, passwd,
2237c478bd9Sstevel@tonic-gate strlen(passwd),
2247c478bd9Sstevel@tonic-gate &construct);
2257c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2267c478bd9Sstevel@tonic-gate if (ret != SASL_OK) {
2277c478bd9Sstevel@tonic-gate goto done;
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate if (!memcmp(db_secret, construct->data, construct->len)) {
2317c478bd9Sstevel@tonic-gate /* password verified! */
2327c478bd9Sstevel@tonic-gate ret = SASL_OK;
2337c478bd9Sstevel@tonic-gate } else {
2347c478bd9Sstevel@tonic-gate /* passwords do not match */
2357c478bd9Sstevel@tonic-gate ret = SASL_BADAUTH;
2367c478bd9Sstevel@tonic-gate }
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
2397c478bd9Sstevel@tonic-gate sconn->sparams->utils->free(construct);
2407c478bd9Sstevel@tonic-gate #else
2417c478bd9Sstevel@tonic-gate sasl_FREE(construct);
2427c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2437c478bd9Sstevel@tonic-gate } else {
2447c478bd9Sstevel@tonic-gate /* passwords do not match */
2457c478bd9Sstevel@tonic-gate ret = SASL_BADAUTH;
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate done:
2497c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
2507c478bd9Sstevel@tonic-gate if (userid) sconn->sparams->utils->free(userid);
2517c478bd9Sstevel@tonic-gate #else
2527c478bd9Sstevel@tonic-gate if (userid) sasl_FREE(userid);
2537c478bd9Sstevel@tonic-gate if (realm) sasl_FREE(realm);
2547c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate /* We're not going to erase the property here because other people
2577c478bd9Sstevel@tonic-gate * may want it */
2587c478bd9Sstevel@tonic-gate return ret;
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate #ifdef DO_SASL_CHECKAPOP
_sasl_auxprop_verify_apop(sasl_conn_t * conn,const char * userstr,const char * challenge,const char * response,const char * user_realm)2627c478bd9Sstevel@tonic-gate int _sasl_auxprop_verify_apop(sasl_conn_t *conn,
2637c478bd9Sstevel@tonic-gate const char *userstr,
2647c478bd9Sstevel@tonic-gate const char *challenge,
2657c478bd9Sstevel@tonic-gate const char *response,
2667c478bd9Sstevel@tonic-gate const char *user_realm __attribute__((unused)))
2677c478bd9Sstevel@tonic-gate {
2687c478bd9Sstevel@tonic-gate int ret = SASL_BADAUTH;
2697c478bd9Sstevel@tonic-gate char *userid = NULL;
2707c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
2717c478bd9Sstevel@tonic-gate char *realm = NULL;
2727c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
2737c478bd9Sstevel@tonic-gate unsigned char digest[16];
2747c478bd9Sstevel@tonic-gate char digeststr[33];
2757c478bd9Sstevel@tonic-gate const char *password_request[] = { SASL_AUX_PASSWORD, NULL };
2767c478bd9Sstevel@tonic-gate struct propval auxprop_values[2];
2777c478bd9Sstevel@tonic-gate sasl_server_conn_t *sconn = (sasl_server_conn_t *)conn;
2787c478bd9Sstevel@tonic-gate MD5_CTX ctx;
2797c478bd9Sstevel@tonic-gate int i;
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate if (!conn || !userstr || !challenge || !response)
2827c478bd9Sstevel@tonic-gate PARAMERROR(conn)
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate /* We've done the auxprop lookup already (in our caller) */
2857c478bd9Sstevel@tonic-gate /* sadly, APOP has no provision for storing secrets */
2867c478bd9Sstevel@tonic-gate ret = prop_getnames(sconn->sparams->propctx, password_request,
2877c478bd9Sstevel@tonic-gate auxprop_values);
2887c478bd9Sstevel@tonic-gate if(ret < 0) {
2897c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
2907c478bd9Sstevel@tonic-gate _sasl_log(conn, SASL_LOG_ERR, "could not perform password lookup");
2917c478bd9Sstevel@tonic-gate #else
2927c478bd9Sstevel@tonic-gate sasl_seterror(conn, 0, "could not perform password lookup");
2937c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2947c478bd9Sstevel@tonic-gate goto done;
2957c478bd9Sstevel@tonic-gate }
296*1da57d55SToomas Soome
2977c478bd9Sstevel@tonic-gate if(!auxprop_values[0].name ||
2987c478bd9Sstevel@tonic-gate !auxprop_values[0].values ||
2997c478bd9Sstevel@tonic-gate !auxprop_values[0].values[0]) {
3007c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
3017c478bd9Sstevel@tonic-gate sasl_seterror(conn, 0, gettext("could not find password"));
3027c478bd9Sstevel@tonic-gate #else
3037c478bd9Sstevel@tonic-gate sasl_seterror(conn, 0, "could not find password");
3047c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
3057c478bd9Sstevel@tonic-gate ret = SASL_NOUSER;
3067c478bd9Sstevel@tonic-gate goto done;
3077c478bd9Sstevel@tonic-gate }
308*1da57d55SToomas Soome
3097c478bd9Sstevel@tonic-gate _sasl_MD5Init(&ctx);
3107c478bd9Sstevel@tonic-gate _sasl_MD5Update(&ctx, challenge, strlen(challenge));
3117c478bd9Sstevel@tonic-gate _sasl_MD5Update(&ctx, auxprop_values[0].values[0],
3127c478bd9Sstevel@tonic-gate strlen(auxprop_values[0].values[0]));
3137c478bd9Sstevel@tonic-gate _sasl_MD5Final(digest, &ctx);
3147c478bd9Sstevel@tonic-gate
3157c478bd9Sstevel@tonic-gate /* convert digest from binary to ASCII hex */
3167c478bd9Sstevel@tonic-gate for (i = 0; i < 16; i++)
3177c478bd9Sstevel@tonic-gate sprintf(digeststr + (i*2), "%02x", digest[i]);
3187c478bd9Sstevel@tonic-gate
3197c478bd9Sstevel@tonic-gate if (!strncasecmp(digeststr, response, 32)) {
3207c478bd9Sstevel@tonic-gate /* password verified! */
3217c478bd9Sstevel@tonic-gate ret = SASL_OK;
3227c478bd9Sstevel@tonic-gate } else {
3237c478bd9Sstevel@tonic-gate /* passwords do not match */
3247c478bd9Sstevel@tonic-gate ret = SASL_BADAUTH;
3257c478bd9Sstevel@tonic-gate }
3267c478bd9Sstevel@tonic-gate
3277c478bd9Sstevel@tonic-gate done:
3287c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
3297c478bd9Sstevel@tonic-gate if (ret == SASL_BADAUTH) sasl_seterror(conn, SASL_NOLOG,
3307c478bd9Sstevel@tonic-gate gettext("login incorrect"));
3317c478bd9Sstevel@tonic-gate #else
3327c478bd9Sstevel@tonic-gate if (ret == SASL_BADAUTH) sasl_seterror(conn, SASL_NOLOG,
3337c478bd9Sstevel@tonic-gate "login incorrect");
3347c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
3357c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
3367c478bd9Sstevel@tonic-gate if (userid) sconn->sparams->utils->free(userid);
3377c478bd9Sstevel@tonic-gate #else
3387c478bd9Sstevel@tonic-gate if (userid) sasl_FREE(userid);
3397c478bd9Sstevel@tonic-gate if (realm) sasl_FREE(realm);
3407c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
3417c478bd9Sstevel@tonic-gate
3427c478bd9Sstevel@tonic-gate return ret;
3437c478bd9Sstevel@tonic-gate }
3447c478bd9Sstevel@tonic-gate #endif /* DO_SASL_CHECKAPOP */
3457c478bd9Sstevel@tonic-gate
3467c478bd9Sstevel@tonic-gate #if defined(HAVE_PWCHECK) || defined(HAVE_SASLAUTHD)
3477c478bd9Sstevel@tonic-gate /*
3487c478bd9Sstevel@tonic-gate * Keep calling the writev() system call with 'fd', 'iov', and 'iovcnt'
3497c478bd9Sstevel@tonic-gate * until all the data is written out or an error occurs.
3507c478bd9Sstevel@tonic-gate */
retry_writev(int fd,struct iovec * iov,int iovcnt)3517c478bd9Sstevel@tonic-gate static int retry_writev(int fd, struct iovec *iov, int iovcnt)
3527c478bd9Sstevel@tonic-gate {
3537c478bd9Sstevel@tonic-gate int n;
3547c478bd9Sstevel@tonic-gate int i;
3557c478bd9Sstevel@tonic-gate int written = 0;
3567c478bd9Sstevel@tonic-gate static int iov_max =
3577c478bd9Sstevel@tonic-gate #ifdef MAXIOV
3587c478bd9Sstevel@tonic-gate MAXIOV
3597c478bd9Sstevel@tonic-gate #else
3607c478bd9Sstevel@tonic-gate #ifdef IOV_MAX
3617c478bd9Sstevel@tonic-gate IOV_MAX
3627c478bd9Sstevel@tonic-gate #else
3637c478bd9Sstevel@tonic-gate 8192
3647c478bd9Sstevel@tonic-gate #endif
3657c478bd9Sstevel@tonic-gate #endif
3667c478bd9Sstevel@tonic-gate ;
367*1da57d55SToomas Soome
3687c478bd9Sstevel@tonic-gate for (;;) {
3697c478bd9Sstevel@tonic-gate while (iovcnt && iov[0].iov_len == 0) {
3707c478bd9Sstevel@tonic-gate iov++;
3717c478bd9Sstevel@tonic-gate iovcnt--;
3727c478bd9Sstevel@tonic-gate }
3737c478bd9Sstevel@tonic-gate
3747c478bd9Sstevel@tonic-gate if (!iovcnt) return written;
3757c478bd9Sstevel@tonic-gate
3767c478bd9Sstevel@tonic-gate n = writev(fd, iov, iovcnt > iov_max ? iov_max : iovcnt);
3777c478bd9Sstevel@tonic-gate if (n == -1) {
3787c478bd9Sstevel@tonic-gate if (errno == EINVAL && iov_max > 10) {
3797c478bd9Sstevel@tonic-gate iov_max /= 2;
3807c478bd9Sstevel@tonic-gate continue;
3817c478bd9Sstevel@tonic-gate }
3827c478bd9Sstevel@tonic-gate if (errno == EINTR) continue;
3837c478bd9Sstevel@tonic-gate return -1;
3847c478bd9Sstevel@tonic-gate }
3857c478bd9Sstevel@tonic-gate
3867c478bd9Sstevel@tonic-gate written += n;
3877c478bd9Sstevel@tonic-gate
3887c478bd9Sstevel@tonic-gate for (i = 0; i < iovcnt; i++) {
3897c478bd9Sstevel@tonic-gate if (iov[i].iov_len > (unsigned) n) {
3907c478bd9Sstevel@tonic-gate iov[i].iov_base = (char *)iov[i].iov_base + n;
3917c478bd9Sstevel@tonic-gate iov[i].iov_len -= n;
3927c478bd9Sstevel@tonic-gate break;
3937c478bd9Sstevel@tonic-gate }
3947c478bd9Sstevel@tonic-gate n -= iov[i].iov_len;
3957c478bd9Sstevel@tonic-gate iov[i].iov_len = 0;
3967c478bd9Sstevel@tonic-gate }
3977c478bd9Sstevel@tonic-gate
3987c478bd9Sstevel@tonic-gate if (i == iovcnt) return written;
3997c478bd9Sstevel@tonic-gate }
4007c478bd9Sstevel@tonic-gate }
4017c478bd9Sstevel@tonic-gate
4027c478bd9Sstevel@tonic-gate #endif
4037c478bd9Sstevel@tonic-gate
4047c478bd9Sstevel@tonic-gate #ifdef HAVE_PWCHECK
4057c478bd9Sstevel@tonic-gate /* pwcheck daemon-authenticated login */
pwcheck_verify_password(sasl_conn_t * conn,const char * userid,const char * passwd,const char * service,const char * user_realm)4067c478bd9Sstevel@tonic-gate static int pwcheck_verify_password(sasl_conn_t *conn,
407*1da57d55SToomas Soome const char *userid,
4087c478bd9Sstevel@tonic-gate const char *passwd,
4097c478bd9Sstevel@tonic-gate const char *service __attribute__((unused)),
410*1da57d55SToomas Soome const char *user_realm
4117c478bd9Sstevel@tonic-gate __attribute__((unused)))
4127c478bd9Sstevel@tonic-gate {
4137c478bd9Sstevel@tonic-gate int s;
4147c478bd9Sstevel@tonic-gate struct sockaddr_un srvaddr;
4157c478bd9Sstevel@tonic-gate int r;
4167c478bd9Sstevel@tonic-gate struct iovec iov[10];
4177c478bd9Sstevel@tonic-gate static char response[1024];
4187c478bd9Sstevel@tonic-gate unsigned start, n;
4197c478bd9Sstevel@tonic-gate char pwpath[1024];
4207c478bd9Sstevel@tonic-gate
4217c478bd9Sstevel@tonic-gate if (strlen(PWCHECKDIR)+8+1 > sizeof(pwpath)) return SASL_FAIL;
4227c478bd9Sstevel@tonic-gate
4237c478bd9Sstevel@tonic-gate strcpy(pwpath, PWCHECKDIR);
4247c478bd9Sstevel@tonic-gate strcat(pwpath, "/pwcheck");
4257c478bd9Sstevel@tonic-gate
4267c478bd9Sstevel@tonic-gate s = socket(AF_UNIX, SOCK_STREAM, 0);
4277c478bd9Sstevel@tonic-gate if (s == -1) return errno;
4287c478bd9Sstevel@tonic-gate
4297c478bd9Sstevel@tonic-gate memset((char *)&srvaddr, 0, sizeof(srvaddr));
4307c478bd9Sstevel@tonic-gate srvaddr.sun_family = AF_UNIX;
4317c478bd9Sstevel@tonic-gate strncpy(srvaddr.sun_path, pwpath, sizeof(srvaddr.sun_path));
4327c478bd9Sstevel@tonic-gate r = connect(s, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
4337c478bd9Sstevel@tonic-gate if (r == -1) {
4347c478bd9Sstevel@tonic-gate sasl_seterror(conn,0,"cannot connect to pwcheck server");
4357c478bd9Sstevel@tonic-gate return SASL_FAIL;
4367c478bd9Sstevel@tonic-gate }
4377c478bd9Sstevel@tonic-gate
4387c478bd9Sstevel@tonic-gate iov[0].iov_base = (char *)userid;
4397c478bd9Sstevel@tonic-gate iov[0].iov_len = strlen(userid)+1;
4407c478bd9Sstevel@tonic-gate iov[1].iov_base = (char *)passwd;
4417c478bd9Sstevel@tonic-gate iov[1].iov_len = strlen(passwd)+1;
4427c478bd9Sstevel@tonic-gate
4437c478bd9Sstevel@tonic-gate retry_writev(s, iov, 2);
4447c478bd9Sstevel@tonic-gate
4457c478bd9Sstevel@tonic-gate start = 0;
4467c478bd9Sstevel@tonic-gate while (start < sizeof(response) - 1) {
4477c478bd9Sstevel@tonic-gate n = read(s, response+start, sizeof(response) - 1 - start);
4487c478bd9Sstevel@tonic-gate if (n < 1) break;
4497c478bd9Sstevel@tonic-gate start += n;
4507c478bd9Sstevel@tonic-gate }
4517c478bd9Sstevel@tonic-gate
4527c478bd9Sstevel@tonic-gate close(s);
4537c478bd9Sstevel@tonic-gate
4547c478bd9Sstevel@tonic-gate if (start > 1 && !strncmp(response, "OK", 2)) {
4557c478bd9Sstevel@tonic-gate return SASL_OK;
4567c478bd9Sstevel@tonic-gate }
4577c478bd9Sstevel@tonic-gate
4587c478bd9Sstevel@tonic-gate response[start] = '\0';
4597c478bd9Sstevel@tonic-gate sasl_seterror(conn,0,response);
4607c478bd9Sstevel@tonic-gate return SASL_BADAUTH;
4617c478bd9Sstevel@tonic-gate }
4627c478bd9Sstevel@tonic-gate
4637c478bd9Sstevel@tonic-gate #endif
4647c478bd9Sstevel@tonic-gate
4657c478bd9Sstevel@tonic-gate #ifdef HAVE_SASLAUTHD
4667c478bd9Sstevel@tonic-gate
4677c478bd9Sstevel@tonic-gate /*
4687c478bd9Sstevel@tonic-gate * Keep calling the read() system call with 'fd', 'buf', and 'nbyte'
4697c478bd9Sstevel@tonic-gate * until all the data is read in or an error occurs.
4707c478bd9Sstevel@tonic-gate */
retry_read(int fd,void * buf0,unsigned nbyte)4717c478bd9Sstevel@tonic-gate static int retry_read(int fd, void *buf0, unsigned nbyte)
4727c478bd9Sstevel@tonic-gate {
4737c478bd9Sstevel@tonic-gate int n;
4747c478bd9Sstevel@tonic-gate int nread = 0;
4757c478bd9Sstevel@tonic-gate char *buf = buf0;
4767c478bd9Sstevel@tonic-gate
4777c478bd9Sstevel@tonic-gate if (nbyte == 0) return 0;
4787c478bd9Sstevel@tonic-gate
4797c478bd9Sstevel@tonic-gate for (;;) {
4807c478bd9Sstevel@tonic-gate n = read(fd, buf, nbyte);
4817c478bd9Sstevel@tonic-gate if (n == -1 || n == 0) {
4827c478bd9Sstevel@tonic-gate if (errno == EINTR || errno == EAGAIN) continue;
4837c478bd9Sstevel@tonic-gate return -1;
4847c478bd9Sstevel@tonic-gate }
4857c478bd9Sstevel@tonic-gate
4867c478bd9Sstevel@tonic-gate nread += n;
4877c478bd9Sstevel@tonic-gate
4887c478bd9Sstevel@tonic-gate if (nread >= (int) nbyte) return nread;
4897c478bd9Sstevel@tonic-gate
4907c478bd9Sstevel@tonic-gate buf += n;
4917c478bd9Sstevel@tonic-gate nbyte -= n;
4927c478bd9Sstevel@tonic-gate }
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate
4957c478bd9Sstevel@tonic-gate /* saslauthd-authenticated login */
saslauthd_verify_password(sasl_conn_t * conn,const char * userid,const char * passwd,const char * service,const char * user_realm)4967c478bd9Sstevel@tonic-gate static int saslauthd_verify_password(sasl_conn_t *conn,
497*1da57d55SToomas Soome const char *userid,
4987c478bd9Sstevel@tonic-gate const char *passwd,
4997c478bd9Sstevel@tonic-gate const char *service,
5007c478bd9Sstevel@tonic-gate const char *user_realm)
5017c478bd9Sstevel@tonic-gate {
5027c478bd9Sstevel@tonic-gate char response[1024];
5037c478bd9Sstevel@tonic-gate char query[8192];
5047c478bd9Sstevel@tonic-gate char *query_end = query;
5057c478bd9Sstevel@tonic-gate int s;
5067c478bd9Sstevel@tonic-gate struct sockaddr_un srvaddr;
5077c478bd9Sstevel@tonic-gate sasl_getopt_t *getopt;
5087c478bd9Sstevel@tonic-gate void *context;
5097c478bd9Sstevel@tonic-gate char pwpath[sizeof(srvaddr.sun_path)];
5107c478bd9Sstevel@tonic-gate const char *p = NULL;
5117c478bd9Sstevel@tonic-gate #ifdef USE_DOORS
5127c478bd9Sstevel@tonic-gate door_arg_t arg;
5137c478bd9Sstevel@tonic-gate #endif
5147c478bd9Sstevel@tonic-gate
5157c478bd9Sstevel@tonic-gate /* check to see if the user configured a rundir */
5167c478bd9Sstevel@tonic-gate if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context) == SASL_OK) {
5177c478bd9Sstevel@tonic-gate getopt(context, NULL, "saslauthd_path", &p, NULL);
5187c478bd9Sstevel@tonic-gate }
5197c478bd9Sstevel@tonic-gate if (p) {
5207c478bd9Sstevel@tonic-gate strncpy(pwpath, p, sizeof(pwpath));
5217c478bd9Sstevel@tonic-gate } else {
5227c478bd9Sstevel@tonic-gate if (strlen(PATH_SASLAUTHD_RUNDIR) + 4 + 1 > sizeof(pwpath))
5237c478bd9Sstevel@tonic-gate return SASL_FAIL;
5247c478bd9Sstevel@tonic-gate
5257c478bd9Sstevel@tonic-gate strcpy(pwpath, PATH_SASLAUTHD_RUNDIR);
5267c478bd9Sstevel@tonic-gate strcat(pwpath, "/mux");
5277c478bd9Sstevel@tonic-gate }
5287c478bd9Sstevel@tonic-gate
5297c478bd9Sstevel@tonic-gate /*
5307c478bd9Sstevel@tonic-gate * build request of the form:
5317c478bd9Sstevel@tonic-gate *
5327c478bd9Sstevel@tonic-gate * count authid count password count service count realm
5337c478bd9Sstevel@tonic-gate */
5347c478bd9Sstevel@tonic-gate {
5357c478bd9Sstevel@tonic-gate unsigned short u_len, p_len, s_len, r_len;
536*1da57d55SToomas Soome
5377c478bd9Sstevel@tonic-gate u_len = (strlen(userid));
5387c478bd9Sstevel@tonic-gate p_len = (strlen(passwd));
5397c478bd9Sstevel@tonic-gate s_len = (strlen(service));
5407c478bd9Sstevel@tonic-gate r_len = ((user_realm ? strlen(user_realm) : 0));
5417c478bd9Sstevel@tonic-gate
5427c478bd9Sstevel@tonic-gate if (u_len + p_len + s_len + r_len + 30 > (unsigned short) sizeof(query)) {
5437c478bd9Sstevel@tonic-gate /* request just too damn big */
5447c478bd9Sstevel@tonic-gate sasl_seterror(conn, 0, "saslauthd request too large");
5457c478bd9Sstevel@tonic-gate return SASL_FAIL;
5467c478bd9Sstevel@tonic-gate }
5477c478bd9Sstevel@tonic-gate
5487c478bd9Sstevel@tonic-gate u_len = htons(u_len);
5497c478bd9Sstevel@tonic-gate p_len = htons(p_len);
5507c478bd9Sstevel@tonic-gate s_len = htons(s_len);
5517c478bd9Sstevel@tonic-gate r_len = htons(r_len);
5527c478bd9Sstevel@tonic-gate
5537c478bd9Sstevel@tonic-gate memcpy(query_end, &u_len, sizeof(unsigned short));
5547c478bd9Sstevel@tonic-gate query_end += sizeof(unsigned short);
5557c478bd9Sstevel@tonic-gate while (*userid) *query_end++ = *userid++;
5567c478bd9Sstevel@tonic-gate
5577c478bd9Sstevel@tonic-gate memcpy(query_end, &p_len, sizeof(unsigned short));
5587c478bd9Sstevel@tonic-gate query_end += sizeof(unsigned short);
5597c478bd9Sstevel@tonic-gate while (*passwd) *query_end++ = *passwd++;
5607c478bd9Sstevel@tonic-gate
5617c478bd9Sstevel@tonic-gate memcpy(query_end, &s_len, sizeof(unsigned short));
5627c478bd9Sstevel@tonic-gate query_end += sizeof(unsigned short);
5637c478bd9Sstevel@tonic-gate while (*service) *query_end++ = *service++;
5647c478bd9Sstevel@tonic-gate
5657c478bd9Sstevel@tonic-gate memcpy(query_end, &r_len, sizeof(unsigned short));
5667c478bd9Sstevel@tonic-gate query_end += sizeof(unsigned short);
5677c478bd9Sstevel@tonic-gate if (user_realm) while (*user_realm) *query_end++ = *user_realm++;
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate
5707c478bd9Sstevel@tonic-gate #ifdef USE_DOORS
5717c478bd9Sstevel@tonic-gate s = open(pwpath, O_RDONLY);
5727c478bd9Sstevel@tonic-gate if (s < 0) {
5737c478bd9Sstevel@tonic-gate sasl_seterror(conn, 0, "cannot open door to saslauthd server: %m", errno);
5747c478bd9Sstevel@tonic-gate return SASL_FAIL;
5757c478bd9Sstevel@tonic-gate }
5767c478bd9Sstevel@tonic-gate
5777c478bd9Sstevel@tonic-gate arg.data_ptr = query;
5787c478bd9Sstevel@tonic-gate arg.data_size = query_end - query;
5797c478bd9Sstevel@tonic-gate arg.desc_ptr = NULL;
5807c478bd9Sstevel@tonic-gate arg.desc_num = 0;
5817c478bd9Sstevel@tonic-gate arg.rbuf = response;
5827c478bd9Sstevel@tonic-gate arg.rsize = sizeof(response);
5837c478bd9Sstevel@tonic-gate
5847c478bd9Sstevel@tonic-gate door_call(s, &arg);
5857c478bd9Sstevel@tonic-gate
5867c478bd9Sstevel@tonic-gate if (arg.data_ptr != response || arg.data_size >= sizeof(response)) {
5877c478bd9Sstevel@tonic-gate /* oh damn, we got back a really long response */
5887c478bd9Sstevel@tonic-gate munmap(arg.rbuf, arg.rsize);
5897c478bd9Sstevel@tonic-gate sasl_seterror(conn, 0, "saslauthd sent an overly long response");
5907c478bd9Sstevel@tonic-gate return SASL_FAIL;
5917c478bd9Sstevel@tonic-gate }
5927c478bd9Sstevel@tonic-gate response[arg.data_size] = '\0';
5937c478bd9Sstevel@tonic-gate
5947c478bd9Sstevel@tonic-gate close(s);
5957c478bd9Sstevel@tonic-gate #else
5967c478bd9Sstevel@tonic-gate /* unix sockets */
5977c478bd9Sstevel@tonic-gate
5987c478bd9Sstevel@tonic-gate s = socket(AF_UNIX, SOCK_STREAM, 0);
5997c478bd9Sstevel@tonic-gate if (s == -1) {
6007c478bd9Sstevel@tonic-gate sasl_seterror(conn, 0, "cannot create socket for saslauthd: %m", errno);
6017c478bd9Sstevel@tonic-gate return SASL_FAIL;
6027c478bd9Sstevel@tonic-gate }
6037c478bd9Sstevel@tonic-gate
6047c478bd9Sstevel@tonic-gate memset((char *)&srvaddr, 0, sizeof(srvaddr));
6057c478bd9Sstevel@tonic-gate srvaddr.sun_family = AF_UNIX;
6067c478bd9Sstevel@tonic-gate strncpy(srvaddr.sun_path, pwpath, sizeof(srvaddr.sun_path));
6077c478bd9Sstevel@tonic-gate
6087c478bd9Sstevel@tonic-gate {
6097c478bd9Sstevel@tonic-gate int r = connect(s, (struct sockaddr *) &srvaddr, sizeof(srvaddr));
6107c478bd9Sstevel@tonic-gate if (r == -1) {
6117c478bd9Sstevel@tonic-gate sasl_seterror(conn, 0, "cannot connect to saslauthd server: %m", errno);
6127c478bd9Sstevel@tonic-gate return SASL_FAIL;
6137c478bd9Sstevel@tonic-gate }
6147c478bd9Sstevel@tonic-gate }
6157c478bd9Sstevel@tonic-gate
6167c478bd9Sstevel@tonic-gate {
6177c478bd9Sstevel@tonic-gate struct iovec iov[8];
618*1da57d55SToomas Soome
6197c478bd9Sstevel@tonic-gate iov[0].iov_len = query_end - query;
6207c478bd9Sstevel@tonic-gate iov[0].iov_base = query;
6217c478bd9Sstevel@tonic-gate
6227c478bd9Sstevel@tonic-gate if (retry_writev(s, iov, 1) == -1) {
6237c478bd9Sstevel@tonic-gate sasl_seterror(conn, 0, "write failed");
6247c478bd9Sstevel@tonic-gate return SASL_FAIL;
6257c478bd9Sstevel@tonic-gate }
6267c478bd9Sstevel@tonic-gate }
6277c478bd9Sstevel@tonic-gate
6287c478bd9Sstevel@tonic-gate {
6297c478bd9Sstevel@tonic-gate unsigned short count = 0;
6307c478bd9Sstevel@tonic-gate
6317c478bd9Sstevel@tonic-gate /*
6327c478bd9Sstevel@tonic-gate * read response of the form:
6337c478bd9Sstevel@tonic-gate *
6347c478bd9Sstevel@tonic-gate * count result
6357c478bd9Sstevel@tonic-gate */
6367c478bd9Sstevel@tonic-gate if (retry_read(s, &count, sizeof(count)) < (int) sizeof(count)) {
6377c478bd9Sstevel@tonic-gate sasl_seterror(conn, 0, "size read failed");
6387c478bd9Sstevel@tonic-gate return SASL_FAIL;
6397c478bd9Sstevel@tonic-gate }
640*1da57d55SToomas Soome
6417c478bd9Sstevel@tonic-gate count = ntohs(count);
6427c478bd9Sstevel@tonic-gate if (count < 2) { /* MUST have at least "OK" or "NO" */
6437c478bd9Sstevel@tonic-gate close(s);
6447c478bd9Sstevel@tonic-gate sasl_seterror(conn, 0, "bad response from saslauthd");
6457c478bd9Sstevel@tonic-gate return SASL_FAIL;
6467c478bd9Sstevel@tonic-gate }
647*1da57d55SToomas Soome
6487c478bd9Sstevel@tonic-gate count = (int)sizeof(response) < count ? sizeof(response) : count;
6497c478bd9Sstevel@tonic-gate if (retry_read(s, response, count) < count) {
6507c478bd9Sstevel@tonic-gate close(s);
6517c478bd9Sstevel@tonic-gate sasl_seterror(conn, 0, "read failed");
6527c478bd9Sstevel@tonic-gate return SASL_FAIL;
6537c478bd9Sstevel@tonic-gate }
6547c478bd9Sstevel@tonic-gate response[count] = '\0';
6557c478bd9Sstevel@tonic-gate }
6567c478bd9Sstevel@tonic-gate
6577c478bd9Sstevel@tonic-gate close(s);
6587c478bd9Sstevel@tonic-gate #endif /* USE_DOORS */
659*1da57d55SToomas Soome
6607c478bd9Sstevel@tonic-gate if (!strncmp(response, "OK", 2)) {
6617c478bd9Sstevel@tonic-gate return SASL_OK;
6627c478bd9Sstevel@tonic-gate }
663*1da57d55SToomas Soome
6647c478bd9Sstevel@tonic-gate sasl_seterror(conn, SASL_NOLOG, "authentication failed");
6657c478bd9Sstevel@tonic-gate return SASL_BADAUTH;
6667c478bd9Sstevel@tonic-gate }
6677c478bd9Sstevel@tonic-gate
6687c478bd9Sstevel@tonic-gate #endif
6697c478bd9Sstevel@tonic-gate
6707c478bd9Sstevel@tonic-gate #ifdef HAVE_ALWAYSTRUE
always_true(sasl_conn_t * conn,const char * userstr,const char * passwd,const char * service,const char * user_realm)6717c478bd9Sstevel@tonic-gate static int always_true(sasl_conn_t *conn,
6727c478bd9Sstevel@tonic-gate const char *userstr,
6737c478bd9Sstevel@tonic-gate const char *passwd __attribute__((unused)),
6747c478bd9Sstevel@tonic-gate const char *service __attribute__((unused)),
675*1da57d55SToomas Soome const char *user_realm __attribute__((unused)))
6767c478bd9Sstevel@tonic-gate {
6777c478bd9Sstevel@tonic-gate _sasl_log(conn, SASL_LOG_WARN, "AlwaysTrue Password Verifier Verified: %s",
6787c478bd9Sstevel@tonic-gate userstr);
6797c478bd9Sstevel@tonic-gate return SASL_OK;
6807c478bd9Sstevel@tonic-gate }
6817c478bd9Sstevel@tonic-gate #endif
6827c478bd9Sstevel@tonic-gate
6837c478bd9Sstevel@tonic-gate struct sasl_verify_password_s _sasl_verify_password[] = {
6847c478bd9Sstevel@tonic-gate { "auxprop", &auxprop_verify_password },
6857c478bd9Sstevel@tonic-gate #ifdef HAVE_PWCHECK
6867c478bd9Sstevel@tonic-gate { "pwcheck", &pwcheck_verify_password },
6877c478bd9Sstevel@tonic-gate #endif
6887c478bd9Sstevel@tonic-gate #ifdef HAVE_SASLAUTHD
6897c478bd9Sstevel@tonic-gate { "saslauthd", &saslauthd_verify_password },
6907c478bd9Sstevel@tonic-gate #endif
6917c478bd9Sstevel@tonic-gate #ifdef HAVE_ALWAYSTRUE
6927c478bd9Sstevel@tonic-gate { "alwaystrue", &always_true },
693*1da57d55SToomas Soome #endif
6947c478bd9Sstevel@tonic-gate { NULL, NULL }
6957c478bd9Sstevel@tonic-gate };
696