xref: /onnv-gate/usr/src/cmd/ndmpd/ndmp/ndmpd_connect.c (revision 8731:accad831e993)
17917SReza.Sabdar@Sun.COM /*
27917SReza.Sabdar@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
37917SReza.Sabdar@Sun.COM  * Use is subject to license terms.
47917SReza.Sabdar@Sun.COM  */
57917SReza.Sabdar@Sun.COM 
67917SReza.Sabdar@Sun.COM /*
77917SReza.Sabdar@Sun.COM  * BSD 3 Clause License
87917SReza.Sabdar@Sun.COM  *
97917SReza.Sabdar@Sun.COM  * Copyright (c) 2007, The Storage Networking Industry Association.
107917SReza.Sabdar@Sun.COM  *
117917SReza.Sabdar@Sun.COM  * Redistribution and use in source and binary forms, with or without
127917SReza.Sabdar@Sun.COM  * modification, are permitted provided that the following conditions
137917SReza.Sabdar@Sun.COM  * are met:
147917SReza.Sabdar@Sun.COM  * 	- Redistributions of source code must retain the above copyright
157917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer.
167917SReza.Sabdar@Sun.COM  *
177917SReza.Sabdar@Sun.COM  * 	- Redistributions in binary form must reproduce the above copyright
187917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer in
197917SReza.Sabdar@Sun.COM  *	  the documentation and/or other materials provided with the
207917SReza.Sabdar@Sun.COM  *	  distribution.
217917SReza.Sabdar@Sun.COM  *
227917SReza.Sabdar@Sun.COM  *	- Neither the name of The Storage Networking Industry Association (SNIA)
237917SReza.Sabdar@Sun.COM  *	  nor the names of its contributors may be used to endorse or promote
247917SReza.Sabdar@Sun.COM  *	  products derived from this software without specific prior written
257917SReza.Sabdar@Sun.COM  *	  permission.
267917SReza.Sabdar@Sun.COM  *
277917SReza.Sabdar@Sun.COM  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
287917SReza.Sabdar@Sun.COM  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
297917SReza.Sabdar@Sun.COM  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
307917SReza.Sabdar@Sun.COM  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
317917SReza.Sabdar@Sun.COM  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
327917SReza.Sabdar@Sun.COM  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
337917SReza.Sabdar@Sun.COM  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
347917SReza.Sabdar@Sun.COM  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
357917SReza.Sabdar@Sun.COM  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
367917SReza.Sabdar@Sun.COM  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
377917SReza.Sabdar@Sun.COM  * POSSIBILITY OF SUCH DAMAGE.
387917SReza.Sabdar@Sun.COM  */
397917SReza.Sabdar@Sun.COM /* Copyright (c) 2007, The Storage Networking Industry Association. */
407917SReza.Sabdar@Sun.COM /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
417917SReza.Sabdar@Sun.COM 
427917SReza.Sabdar@Sun.COM #include <sys/types.h>
437917SReza.Sabdar@Sun.COM #include <errno.h>
447917SReza.Sabdar@Sun.COM #include <pwd.h>
457917SReza.Sabdar@Sun.COM #include <sys/socket.h>
467917SReza.Sabdar@Sun.COM #include <netinet/in.h>
477917SReza.Sabdar@Sun.COM #include <sys/queue.h>
487917SReza.Sabdar@Sun.COM #include <arpa/inet.h>
497917SReza.Sabdar@Sun.COM #include <md5.h>
507917SReza.Sabdar@Sun.COM #include <shadow.h>
517917SReza.Sabdar@Sun.COM #include <crypt.h>
527917SReza.Sabdar@Sun.COM #include <alloca.h>
537917SReza.Sabdar@Sun.COM #include "ndmpd_common.h"
547917SReza.Sabdar@Sun.COM #include "ndmpd.h"
557917SReza.Sabdar@Sun.COM #include <libndmp.h>
567917SReza.Sabdar@Sun.COM #include <ndmpd_door.h>
577917SReza.Sabdar@Sun.COM #include <security/pam_appl.h>
587917SReza.Sabdar@Sun.COM 
597917SReza.Sabdar@Sun.COM 
607917SReza.Sabdar@Sun.COM static int ndmpd_connect_auth_text(char *uname, char *auth_id,
617917SReza.Sabdar@Sun.COM     char *auth_password);
627917SReza.Sabdar@Sun.COM static int ndmpd_connect_auth_md5(char *uname, char *auth_id, char *auth_digest,
637917SReza.Sabdar@Sun.COM     unsigned char *auth_challenge);
647917SReza.Sabdar@Sun.COM static struct conn_list *ndmp_connect_list_find(ndmp_connection_t *connection);
657917SReza.Sabdar@Sun.COM static void create_md5_digest(unsigned char *digest, char *passwd,
667917SReza.Sabdar@Sun.COM     unsigned char *challenge);
677917SReza.Sabdar@Sun.COM static struct conn_list *ndmp_connect_list_find_id(int id);
687917SReza.Sabdar@Sun.COM 
697917SReza.Sabdar@Sun.COM /* routines for connection info */
707917SReza.Sabdar@Sun.COM void ndmp_connect_list_get(ndmp_door_ctx_t *enc_ctx);
717917SReza.Sabdar@Sun.COM static void connection_get(struct conn_list *clp, ndmp_door_ctx_t *enc_ctx);
727917SReza.Sabdar@Sun.COM static void ndmp_connect_get_conn(struct conn_list *clp,
737917SReza.Sabdar@Sun.COM     ndmp_door_ctx_t *enc_ctx);
747917SReza.Sabdar@Sun.COM static void ndmp_connect_get_v2(ndmp_connection_t *connection,
757917SReza.Sabdar@Sun.COM     ndmp_door_ctx_t *enc_ctx);
767917SReza.Sabdar@Sun.COM static void ndmp_connect_get_scsi_v2(ndmpd_session_t *session,
777917SReza.Sabdar@Sun.COM     ndmp_door_ctx_t *enc_ctx);
787917SReza.Sabdar@Sun.COM static void ndmp_connect_get_tape_v2(ndmpd_session_t *session,
797917SReza.Sabdar@Sun.COM     ndmp_door_ctx_t *enc_ctx);
807917SReza.Sabdar@Sun.COM static void ndmp_connect_get_mover_v2(ndmpd_session_t *session,
817917SReza.Sabdar@Sun.COM     ndmp_door_ctx_t *enc_ctx);
827917SReza.Sabdar@Sun.COM static void ndmp_connect_get_data_v2(ndmpd_session_t *session,
837917SReza.Sabdar@Sun.COM     ndmp_door_ctx_t *enc_ctx);
847917SReza.Sabdar@Sun.COM static void ndmp_connect_get_v3(ndmp_connection_t *connection,
857917SReza.Sabdar@Sun.COM     ndmp_door_ctx_t *enc_ctx);
867917SReza.Sabdar@Sun.COM static void ndmp_connect_get_mover_v3(ndmpd_session_t *session,
877917SReza.Sabdar@Sun.COM     ndmp_door_ctx_t *enc_ctx);
887917SReza.Sabdar@Sun.COM static void ndmp_connect_get_data_v3(ndmpd_session_t *session,
897917SReza.Sabdar@Sun.COM     ndmp_door_ctx_t *enc_ctx);
907917SReza.Sabdar@Sun.COM void ndmpd_get_devs(ndmp_door_ctx_t *enc_ctx);
917917SReza.Sabdar@Sun.COM 
927917SReza.Sabdar@Sun.COM #ifndef LIST_FOREACH
937917SReza.Sabdar@Sun.COM #define	LIST_FOREACH(var, head, field)					\
947917SReza.Sabdar@Sun.COM 	for ((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
957917SReza.Sabdar@Sun.COM #endif /* LIST_FOREACH */
967917SReza.Sabdar@Sun.COM 
977917SReza.Sabdar@Sun.COM /*
987917SReza.Sabdar@Sun.COM  * List of active connections.
997917SReza.Sabdar@Sun.COM  */
1007917SReza.Sabdar@Sun.COM struct conn_list {
1017917SReza.Sabdar@Sun.COM 	LIST_ENTRY(conn_list) cl_q;
1027917SReza.Sabdar@Sun.COM 	int cl_id;
1037917SReza.Sabdar@Sun.COM 	ndmp_connection_t *cl_conn;
1047917SReza.Sabdar@Sun.COM };
1057917SReza.Sabdar@Sun.COM LIST_HEAD(cl_head, conn_list);
1067917SReza.Sabdar@Sun.COM 
1077917SReza.Sabdar@Sun.COM /*
1087917SReza.Sabdar@Sun.COM  * Head of the active connections.
1097917SReza.Sabdar@Sun.COM  */
1107917SReza.Sabdar@Sun.COM static struct cl_head cl_head;
1117917SReza.Sabdar@Sun.COM 
1127917SReza.Sabdar@Sun.COM mutex_t cl_mutex = DEFAULTMUTEX;
1137917SReza.Sabdar@Sun.COM 
1147917SReza.Sabdar@Sun.COM 
1157917SReza.Sabdar@Sun.COM /*
1167917SReza.Sabdar@Sun.COM  * Set this variable to non-zero to print verbose information.
1177917SReza.Sabdar@Sun.COM  */
1187917SReza.Sabdar@Sun.COM int ndmp_connect_print_verbose = 0;
1197917SReza.Sabdar@Sun.COM 
1207917SReza.Sabdar@Sun.COM 
1217917SReza.Sabdar@Sun.COM /*
1227917SReza.Sabdar@Sun.COM  * ************************************************************************
1237917SReza.Sabdar@Sun.COM  * NDMP V2 HANDLERS
1247917SReza.Sabdar@Sun.COM  * ************************************************************************
1257917SReza.Sabdar@Sun.COM  */
1267917SReza.Sabdar@Sun.COM 
1277917SReza.Sabdar@Sun.COM /*
1287917SReza.Sabdar@Sun.COM  * ndmpd_connect_open_v2
1297917SReza.Sabdar@Sun.COM  *
1307917SReza.Sabdar@Sun.COM  * This handler sets the protocol version to be used on the connection.
1317917SReza.Sabdar@Sun.COM  *
1327917SReza.Sabdar@Sun.COM  * Parameters:
1337917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
1347917SReza.Sabdar@Sun.COM  *   body       (input) - request message body.
1357917SReza.Sabdar@Sun.COM  *
1367917SReza.Sabdar@Sun.COM  * Returns:
1377917SReza.Sabdar@Sun.COM  *   void
1387917SReza.Sabdar@Sun.COM  */
1397917SReza.Sabdar@Sun.COM 
1407917SReza.Sabdar@Sun.COM void
ndmpd_connect_open_v2(ndmp_connection_t * connection,void * body)1417917SReza.Sabdar@Sun.COM ndmpd_connect_open_v2(ndmp_connection_t *connection, void *body)
1427917SReza.Sabdar@Sun.COM {
1437917SReza.Sabdar@Sun.COM 	ndmp_connect_open_request *request = (ndmp_connect_open_request *)body;
1447917SReza.Sabdar@Sun.COM 	ndmp_connect_open_reply reply;
1457917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session;
1467917SReza.Sabdar@Sun.COM 
1477917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
1487917SReza.Sabdar@Sun.COM 
1497917SReza.Sabdar@Sun.COM 	if (!(session = (ndmpd_session_t *)ndmp_get_client_data(connection)))
1507917SReza.Sabdar@Sun.COM 		return;
1517917SReza.Sabdar@Sun.COM 
1527917SReza.Sabdar@Sun.COM 	if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE ||
1537917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_state != NDMP_DATA_STATE_IDLE)
1547917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_STATE_ERR;
1557917SReza.Sabdar@Sun.COM 	else if (request->protocol_version > ndmp_ver)
1567917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
1577917SReza.Sabdar@Sun.COM 
1587917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, (void *) &reply,
1597917SReza.Sabdar@Sun.COM 	    "sending connect_open reply");
1607917SReza.Sabdar@Sun.COM 
1617917SReza.Sabdar@Sun.COM 	/*
1627917SReza.Sabdar@Sun.COM 	 * Set the protocol version.
1637917SReza.Sabdar@Sun.COM 	 * Must wait until after sending the reply since the reply
1647917SReza.Sabdar@Sun.COM 	 * must be sent using the same protocol version that was used
1657917SReza.Sabdar@Sun.COM 	 * to process the request.
1667917SReza.Sabdar@Sun.COM 	 */
1677917SReza.Sabdar@Sun.COM 	if (reply.error == NDMP_NO_ERR) {
1687917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "set ver to: %d",
1697917SReza.Sabdar@Sun.COM 		    request->protocol_version);
1707917SReza.Sabdar@Sun.COM 		ndmp_set_version(connection, request->protocol_version);
1717917SReza.Sabdar@Sun.COM 		session->ns_protocol_version = request->protocol_version;
1727917SReza.Sabdar@Sun.COM 	}
1737917SReza.Sabdar@Sun.COM }
1747917SReza.Sabdar@Sun.COM 
1757917SReza.Sabdar@Sun.COM 
1767917SReza.Sabdar@Sun.COM /*
1777917SReza.Sabdar@Sun.COM  * ndmpd_connect_client_auth_v2
1787917SReza.Sabdar@Sun.COM  *
1797917SReza.Sabdar@Sun.COM  * This handler authorizes the NDMP connection.
1807917SReza.Sabdar@Sun.COM  *
1817917SReza.Sabdar@Sun.COM  * Parameters:
1827917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
1837917SReza.Sabdar@Sun.COM  *   msginfo    (input) - request message.
1847917SReza.Sabdar@Sun.COM  *
1857917SReza.Sabdar@Sun.COM  * Returns:
1867917SReza.Sabdar@Sun.COM  *   void
1877917SReza.Sabdar@Sun.COM  */
1887917SReza.Sabdar@Sun.COM void
ndmpd_connect_client_auth_v2(ndmp_connection_t * connection,void * body)1897917SReza.Sabdar@Sun.COM ndmpd_connect_client_auth_v2(ndmp_connection_t *connection, void *body)
1907917SReza.Sabdar@Sun.COM {
1917917SReza.Sabdar@Sun.COM 	ndmp_connect_client_auth_request *request;
1927917SReza.Sabdar@Sun.COM 	ndmp_connect_client_auth_reply reply;
1937917SReza.Sabdar@Sun.COM 	ndmp_auth_text *auth;
1947917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session;
1957917SReza.Sabdar@Sun.COM 	ndmp_auth_md5 *md5;
1967917SReza.Sabdar@Sun.COM 	unsigned char md5_digest[16];
1977917SReza.Sabdar@Sun.COM 	char *passwd, *dec_passwd;
1987917SReza.Sabdar@Sun.COM 	char *uname;
1997917SReza.Sabdar@Sun.COM 
2007917SReza.Sabdar@Sun.COM 	request = (ndmp_connect_client_auth_request *)body;
2017917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "auth_type:%s",
2027917SReza.Sabdar@Sun.COM 	    request->auth_data.auth_type == NDMP_AUTH_NONE ? "None" :
2037917SReza.Sabdar@Sun.COM 	    (request->auth_data.auth_type == NDMP_AUTH_TEXT ? "Text" :
2047917SReza.Sabdar@Sun.COM 	    (request->auth_data.auth_type == NDMP_AUTH_MD5 ? "MD5" :
2057917SReza.Sabdar@Sun.COM 	    "Invalid")));
2067917SReza.Sabdar@Sun.COM 
2077917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
2087917SReza.Sabdar@Sun.COM 
2097917SReza.Sabdar@Sun.COM 	switch (request->auth_data.auth_type) {
2107917SReza.Sabdar@Sun.COM 	case NDMP_AUTH_NONE:
2117917SReza.Sabdar@Sun.COM 		/*
2127917SReza.Sabdar@Sun.COM 		 * Allow no authorization for development.
2137917SReza.Sabdar@Sun.COM 		 * Comment the following for a non-secure production server.
2147917SReza.Sabdar@Sun.COM 		 */
2157917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Authorization denied.");
2167917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR,
2177917SReza.Sabdar@Sun.COM 		    "Authorization type should be md5 or cleartext.");
2187917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
2197917SReza.Sabdar@Sun.COM 		ndmpd_audit_connect(connection, EINVAL);
2207917SReza.Sabdar@Sun.COM 		break;
2217917SReza.Sabdar@Sun.COM 
2227917SReza.Sabdar@Sun.COM 	case NDMP_AUTH_TEXT:
2237917SReza.Sabdar@Sun.COM 		/* Check authorization.  */
2247917SReza.Sabdar@Sun.COM 		if ((uname = ndmpd_get_prop(NDMP_CLEARTEXT_USERNAME)) == NULL ||
2257917SReza.Sabdar@Sun.COM 		    *uname == 0) {
2267917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "Authorization denied.");
2277917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "User name is not set at server.");
2287917SReza.Sabdar@Sun.COM 			reply.error = NDMP_NOT_AUTHORIZED_ERR;
2297917SReza.Sabdar@Sun.COM 			ndmp_set_authorized(connection, FALSE);
2307917SReza.Sabdar@Sun.COM 			ndmp_send_reply(connection, (void *) &reply,
2317917SReza.Sabdar@Sun.COM 			    "sending ndmp_connect_client_auth reply");
2327917SReza.Sabdar@Sun.COM 			ndmpd_audit_connect(connection,
2337917SReza.Sabdar@Sun.COM 			    ADT_FAIL_PAM + PAM_AUTH_ERR);
2347917SReza.Sabdar@Sun.COM 			return;
2357917SReza.Sabdar@Sun.COM 		}
2367917SReza.Sabdar@Sun.COM 		auth = &request->auth_data.ndmp_auth_data_u.auth_text;
2377917SReza.Sabdar@Sun.COM 		if (strcmp(uname, auth->user) != 0) {
2387917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR,
2397917SReza.Sabdar@Sun.COM 			    "Authorization denied. Not a valid user.");
2407917SReza.Sabdar@Sun.COM 			reply.error = NDMP_NOT_AUTHORIZED_ERR;
2417917SReza.Sabdar@Sun.COM 			ndmpd_audit_connect(connection,
2427917SReza.Sabdar@Sun.COM 			    ADT_FAIL_PAM + PAM_AUTH_ERR);
2437917SReza.Sabdar@Sun.COM 			break;
2447917SReza.Sabdar@Sun.COM 		}
2457917SReza.Sabdar@Sun.COM 		passwd = ndmpd_get_prop(NDMP_CLEARTEXT_PASSWORD);
2467917SReza.Sabdar@Sun.COM 		if (!passwd || !*passwd) {
2477917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "Authorization denied.");
2487917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR,
2497917SReza.Sabdar@Sun.COM 			    "Cleartext password is not set at server.");
2507917SReza.Sabdar@Sun.COM 			reply.error = NDMP_NOT_AUTHORIZED_ERR;
2517917SReza.Sabdar@Sun.COM 			ndmp_set_authorized(connection, FALSE);
2527917SReza.Sabdar@Sun.COM 			ndmp_send_reply(connection, (void *) &reply,
2537917SReza.Sabdar@Sun.COM 			    "sending ndmp_connect_client_auth reply");
2547917SReza.Sabdar@Sun.COM 			ndmpd_audit_connect(connection,
2557917SReza.Sabdar@Sun.COM 			    ADT_FAIL_PAM + PAM_AUTH_ERR);
2567917SReza.Sabdar@Sun.COM 			return;
2577917SReza.Sabdar@Sun.COM 		} else {
2587917SReza.Sabdar@Sun.COM 			dec_passwd = ndmp_base64_decode(passwd);
2597917SReza.Sabdar@Sun.COM 		}
2607917SReza.Sabdar@Sun.COM 		if (!dec_passwd || !*dec_passwd ||
2617917SReza.Sabdar@Sun.COM 		    strcmp(auth->password, dec_passwd) != 0) {
2627917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR,
2637917SReza.Sabdar@Sun.COM 			    "Authorization denied. Invalid password.");
2647917SReza.Sabdar@Sun.COM 			reply.error = NDMP_NOT_AUTHORIZED_ERR;
2657917SReza.Sabdar@Sun.COM 		} else {
2667917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "Authorization granted.");
2677917SReza.Sabdar@Sun.COM 		}
2687917SReza.Sabdar@Sun.COM 		ndmpd_audit_connect(connection, reply.error ?
2697917SReza.Sabdar@Sun.COM 		    ADT_FAIL_PAM + PAM_AUTH_ERR : 0);
2707917SReza.Sabdar@Sun.COM 
2717917SReza.Sabdar@Sun.COM 		free(dec_passwd);
2727917SReza.Sabdar@Sun.COM 		break;
2737917SReza.Sabdar@Sun.COM 
2747917SReza.Sabdar@Sun.COM 	case NDMP_AUTH_MD5:
2757917SReza.Sabdar@Sun.COM 		/* Check authorization.  */
2767917SReza.Sabdar@Sun.COM 		if ((uname = ndmpd_get_prop(NDMP_CRAM_MD5_USERNAME)) == NULL ||
2777917SReza.Sabdar@Sun.COM 		    *uname == 0) {
2787917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "Authorization denied.");
2797917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR,  "User name is not set at server.");
2807917SReza.Sabdar@Sun.COM 			reply.error = NDMP_NOT_AUTHORIZED_ERR;
2817917SReza.Sabdar@Sun.COM 			ndmp_set_authorized(connection, FALSE);
2827917SReza.Sabdar@Sun.COM 			ndmp_send_reply(connection, (void *) &reply,
2837917SReza.Sabdar@Sun.COM 			    "sending ndmp_connect_client_auth reply");
2847917SReza.Sabdar@Sun.COM 			ndmpd_audit_connect(connection,
2857917SReza.Sabdar@Sun.COM 			    ADT_FAIL_PAM + PAM_AUTH_ERR);
2867917SReza.Sabdar@Sun.COM 			return;
2877917SReza.Sabdar@Sun.COM 		}
2887917SReza.Sabdar@Sun.COM 		md5 = &request->auth_data.ndmp_auth_data_u.auth_md5;
2897917SReza.Sabdar@Sun.COM 		passwd = ndmpd_get_prop(NDMP_CRAM_MD5_PASSWORD);
2907917SReza.Sabdar@Sun.COM 		if (!passwd || !*passwd) {
2917917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "Authorization denied.");
2927917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "MD5 password is not set at server.");
2937917SReza.Sabdar@Sun.COM 			reply.error = NDMP_NOT_AUTHORIZED_ERR;
2947917SReza.Sabdar@Sun.COM 			ndmp_set_authorized(connection, FALSE);
2957917SReza.Sabdar@Sun.COM 			ndmp_send_reply(connection, (void *) &reply,
2967917SReza.Sabdar@Sun.COM 			    "sending ndmp_connect_client_auth reply");
2977917SReza.Sabdar@Sun.COM 			ndmpd_audit_connect(connection,
2987917SReza.Sabdar@Sun.COM 			    ADT_FAIL_PAM + PAM_AUTH_ERR);
2997917SReza.Sabdar@Sun.COM 			return;
3007917SReza.Sabdar@Sun.COM 		} else {
3017917SReza.Sabdar@Sun.COM 			dec_passwd = ndmp_base64_decode(passwd);
3027917SReza.Sabdar@Sun.COM 		}
3037917SReza.Sabdar@Sun.COM 		session = ndmp_get_client_data(connection);
3047917SReza.Sabdar@Sun.COM 		create_md5_digest(md5_digest, dec_passwd,
3057917SReza.Sabdar@Sun.COM 		    session->ns_challenge);
3067917SReza.Sabdar@Sun.COM 
3077917SReza.Sabdar@Sun.COM 		if (strcmp(uname, md5->user) != 0) {
3087917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR,
3097917SReza.Sabdar@Sun.COM 			    "Authorization denied. Not a valid user.");
3107917SReza.Sabdar@Sun.COM 			reply.error = NDMP_NOT_AUTHORIZED_ERR;
3117917SReza.Sabdar@Sun.COM 		} else if (memcmp(md5_digest, md5->auth_digest,
3127917SReza.Sabdar@Sun.COM 		    sizeof (md5_digest)) != 0) {
3137917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR,
3147917SReza.Sabdar@Sun.COM 			    "Authorization denied. Invalid password.");
3157917SReza.Sabdar@Sun.COM 			reply.error = NDMP_NOT_AUTHORIZED_ERR;
3167917SReza.Sabdar@Sun.COM 		} else {
3177917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_DEBUG, "Authorization granted");
3187917SReza.Sabdar@Sun.COM 		}
3197917SReza.Sabdar@Sun.COM 		ndmpd_audit_connect(connection, reply.error ?
3207917SReza.Sabdar@Sun.COM 		    ADT_FAIL_PAM + PAM_AUTH_ERR : 0);
3217917SReza.Sabdar@Sun.COM 
3227917SReza.Sabdar@Sun.COM 		free(dec_passwd);
3237917SReza.Sabdar@Sun.COM 		break;
3247917SReza.Sabdar@Sun.COM 
3257917SReza.Sabdar@Sun.COM 	default:
3267917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
3277917SReza.Sabdar@Sun.COM 	}
3287917SReza.Sabdar@Sun.COM 
3297917SReza.Sabdar@Sun.COM 	if (reply.error == NDMP_NO_ERR)
3307917SReza.Sabdar@Sun.COM 		ndmp_set_authorized(connection, TRUE);
3317917SReza.Sabdar@Sun.COM 	else
3327917SReza.Sabdar@Sun.COM 		ndmp_set_authorized(connection, FALSE);
3337917SReza.Sabdar@Sun.COM 
3347917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, (void *) &reply,
3357917SReza.Sabdar@Sun.COM 	    "sending ndmp_connect_client_auth reply");
3367917SReza.Sabdar@Sun.COM }
3377917SReza.Sabdar@Sun.COM 
3387917SReza.Sabdar@Sun.COM 
3397917SReza.Sabdar@Sun.COM /*
3407917SReza.Sabdar@Sun.COM  * ndmpd_connect_server_auth_v2
3417917SReza.Sabdar@Sun.COM  *
3427917SReza.Sabdar@Sun.COM  * This handler authenticates the server to the client.
3437917SReza.Sabdar@Sun.COM  *
3447917SReza.Sabdar@Sun.COM  * Parameters:
3457917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
3467917SReza.Sabdar@Sun.COM  *   msginfo    (input) - request message.
3477917SReza.Sabdar@Sun.COM  *
3487917SReza.Sabdar@Sun.COM  * Returns:
3497917SReza.Sabdar@Sun.COM  *   void
3507917SReza.Sabdar@Sun.COM  */
3517917SReza.Sabdar@Sun.COM void
ndmpd_connect_server_auth_v2(ndmp_connection_t * connection,void * body)3527917SReza.Sabdar@Sun.COM ndmpd_connect_server_auth_v2(ndmp_connection_t *connection, void *body)
3537917SReza.Sabdar@Sun.COM {
3547917SReza.Sabdar@Sun.COM 	ndmp_connect_server_auth_request *request;
3557917SReza.Sabdar@Sun.COM 	ndmp_connect_server_auth_reply reply;
3567917SReza.Sabdar@Sun.COM 
3577917SReza.Sabdar@Sun.COM 	request = (ndmp_connect_server_auth_request *)body;
3587917SReza.Sabdar@Sun.COM 
3597917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "auth_type:%s",
3607917SReza.Sabdar@Sun.COM 	    request->client_attr.auth_type == NDMP_AUTH_NONE ? "None" :
3617917SReza.Sabdar@Sun.COM 	    (request->client_attr.auth_type == NDMP_AUTH_TEXT ? "Text" :
3627917SReza.Sabdar@Sun.COM 	    (request->client_attr.auth_type == NDMP_AUTH_MD5 ? "MD5" :
3637917SReza.Sabdar@Sun.COM 	    "Invalid")));
3647917SReza.Sabdar@Sun.COM 
3657917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
3667917SReza.Sabdar@Sun.COM 	reply.auth_result.auth_type = request->client_attr.auth_type;
3677917SReza.Sabdar@Sun.COM 	switch (request->client_attr.auth_type) {
3687917SReza.Sabdar@Sun.COM 	case NDMP_AUTH_NONE:
3697917SReza.Sabdar@Sun.COM 		break;
3707917SReza.Sabdar@Sun.COM 
3717917SReza.Sabdar@Sun.COM 	case NDMP_AUTH_TEXT:
3727917SReza.Sabdar@Sun.COM 		reply.auth_result.ndmp_auth_data_u.auth_text.user = "ndmpd";
3737917SReza.Sabdar@Sun.COM 		reply.auth_result.ndmp_auth_data_u.auth_text.password =
3747917SReza.Sabdar@Sun.COM 		    "ndmpsdk";
3757917SReza.Sabdar@Sun.COM 		break;
3767917SReza.Sabdar@Sun.COM 
3777917SReza.Sabdar@Sun.COM 	case NDMP_AUTH_MD5:
3787917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
3797917SReza.Sabdar@Sun.COM 		break;
3807917SReza.Sabdar@Sun.COM 
3817917SReza.Sabdar@Sun.COM 	default:
3827917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
3837917SReza.Sabdar@Sun.COM 	}
3847917SReza.Sabdar@Sun.COM 
3857917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, (void *) &reply,
3867917SReza.Sabdar@Sun.COM 	    "sending ndmp_connect_auth reply");
3877917SReza.Sabdar@Sun.COM }
3887917SReza.Sabdar@Sun.COM 
3897917SReza.Sabdar@Sun.COM 
3907917SReza.Sabdar@Sun.COM /*
3917917SReza.Sabdar@Sun.COM  * ndmpd_connect_close_v2
3927917SReza.Sabdar@Sun.COM  *
3937917SReza.Sabdar@Sun.COM  * This handler closes the connection.
3947917SReza.Sabdar@Sun.COM  *
3957917SReza.Sabdar@Sun.COM  * Parameters:
3967917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
3977917SReza.Sabdar@Sun.COM  *   msginfo    (input) - request message.
3987917SReza.Sabdar@Sun.COM  *
3997917SReza.Sabdar@Sun.COM  * Returns:
4007917SReza.Sabdar@Sun.COM  *   void
4017917SReza.Sabdar@Sun.COM  */
4027917SReza.Sabdar@Sun.COM /*ARGSUSED*/
4037917SReza.Sabdar@Sun.COM void
ndmpd_connect_close_v2(ndmp_connection_t * connection,void * body)4047917SReza.Sabdar@Sun.COM ndmpd_connect_close_v2(ndmp_connection_t *connection, void *body)
4057917SReza.Sabdar@Sun.COM {
4067917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session;
4077917SReza.Sabdar@Sun.COM 
4087917SReza.Sabdar@Sun.COM 	if ((session = (ndmpd_session_t *)ndmp_get_client_data(connection))) {
4097917SReza.Sabdar@Sun.COM 		(void) ndmp_close(connection);
4107917SReza.Sabdar@Sun.COM 		session->ns_eof = TRUE;
4117917SReza.Sabdar@Sun.COM 	}
4127917SReza.Sabdar@Sun.COM }
4137917SReza.Sabdar@Sun.COM 
4147917SReza.Sabdar@Sun.COM /*
4157917SReza.Sabdar@Sun.COM  * ************************************************************************
4167917SReza.Sabdar@Sun.COM  * NDMP V3 HANDLERS
4177917SReza.Sabdar@Sun.COM  * ************************************************************************
4187917SReza.Sabdar@Sun.COM  */
4197917SReza.Sabdar@Sun.COM 
4207917SReza.Sabdar@Sun.COM /*
4217917SReza.Sabdar@Sun.COM  * ndmpd_connect_client_auth_v3
4227917SReza.Sabdar@Sun.COM  *
4237917SReza.Sabdar@Sun.COM  * This handler authorizes the NDMP connection.
4247917SReza.Sabdar@Sun.COM  *
4257917SReza.Sabdar@Sun.COM  * Parameters:
4267917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
4277917SReza.Sabdar@Sun.COM  *   msginfo    (input) - request message.
4287917SReza.Sabdar@Sun.COM  *
4297917SReza.Sabdar@Sun.COM  * Returns:
4307917SReza.Sabdar@Sun.COM  *   void
4317917SReza.Sabdar@Sun.COM  */
4327917SReza.Sabdar@Sun.COM void
ndmpd_connect_client_auth_v3(ndmp_connection_t * connection,void * body)4337917SReza.Sabdar@Sun.COM ndmpd_connect_client_auth_v3(ndmp_connection_t *connection, void *body)
4347917SReza.Sabdar@Sun.COM {
4357917SReza.Sabdar@Sun.COM 	ndmp_connect_client_auth_request_v3 *request;
4367917SReza.Sabdar@Sun.COM 	ndmp_connect_client_auth_reply_v3 reply;
4377917SReza.Sabdar@Sun.COM 	ndmp_auth_text_v3 *auth;
4387917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session;
4397917SReza.Sabdar@Sun.COM 	ndmp_auth_md5_v3 *md5;
4407917SReza.Sabdar@Sun.COM 	struct in_addr addr;
4417917SReza.Sabdar@Sun.COM 	char *uname;
4427917SReza.Sabdar@Sun.COM 	char *type;
4437917SReza.Sabdar@Sun.COM 
4447917SReza.Sabdar@Sun.COM 	request = (ndmp_connect_client_auth_request_v3 *)body;
4457917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "auth_type %s",
4467917SReza.Sabdar@Sun.COM 	    request->auth_data.auth_type == NDMP_AUTH_NONE ? "None" :
4477917SReza.Sabdar@Sun.COM 	    request->auth_data.auth_type == NDMP_AUTH_TEXT ? "Text" :
4487917SReza.Sabdar@Sun.COM 	    request->auth_data.auth_type == NDMP_AUTH_MD5 ? "MD5" : "Invalid");
4497917SReza.Sabdar@Sun.COM 
4507917SReza.Sabdar@Sun.COM 	reply.error = NDMP_NO_ERR;
4517917SReza.Sabdar@Sun.COM 
4527917SReza.Sabdar@Sun.COM 	switch (request->auth_data.auth_type) {
4537917SReza.Sabdar@Sun.COM 	case NDMP_AUTH_NONE:
4547917SReza.Sabdar@Sun.COM 		type = "none";
4557917SReza.Sabdar@Sun.COM 		reply.error = NDMP_NOT_SUPPORTED_ERR;
4567917SReza.Sabdar@Sun.COM 		ndmpd_audit_connect(connection, ENOTSUP);
4577917SReza.Sabdar@Sun.COM 		break;
4587917SReza.Sabdar@Sun.COM 
4597917SReza.Sabdar@Sun.COM 	case NDMP_AUTH_TEXT:
4607917SReza.Sabdar@Sun.COM 		/* Check authorization.  */
4617917SReza.Sabdar@Sun.COM 		if ((uname = ndmpd_get_prop(NDMP_CLEARTEXT_USERNAME)) == NULL ||
4627917SReza.Sabdar@Sun.COM 		    *uname == 0) {
4637917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "Authorization denied.");
4647917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "User name is not set at server.");
4657917SReza.Sabdar@Sun.COM 			reply.error = NDMP_NOT_AUTHORIZED_ERR;
4667917SReza.Sabdar@Sun.COM 			ndmp_set_authorized(connection, FALSE);
4677917SReza.Sabdar@Sun.COM 			ndmp_send_reply(connection, (void *) &reply,
4687917SReza.Sabdar@Sun.COM 			    "sending ndmp_connect_client_auth reply");
4697917SReza.Sabdar@Sun.COM 			ndmpd_audit_connect(connection,
4707917SReza.Sabdar@Sun.COM 			    ADT_FAIL_PAM + PAM_AUTH_ERR);
4717917SReza.Sabdar@Sun.COM 			return;
4727917SReza.Sabdar@Sun.COM 		}
4737917SReza.Sabdar@Sun.COM 		type = "text";
4747917SReza.Sabdar@Sun.COM 		auth = &request->auth_data.ndmp_auth_data_v3_u.auth_text;
4757917SReza.Sabdar@Sun.COM 		reply.error = ndmpd_connect_auth_text(uname, auth->auth_id,
4767917SReza.Sabdar@Sun.COM 		    auth->auth_password);
4777917SReza.Sabdar@Sun.COM 		ndmpd_audit_connect(connection, reply.error ?
4787917SReza.Sabdar@Sun.COM 		    ADT_FAIL_PAM + PAM_AUTH_ERR : 0);
4797917SReza.Sabdar@Sun.COM 		break;
4807917SReza.Sabdar@Sun.COM 
4817917SReza.Sabdar@Sun.COM 	case NDMP_AUTH_MD5:
4827917SReza.Sabdar@Sun.COM 		/* Check authorization.  */
4837917SReza.Sabdar@Sun.COM 		if ((uname = ndmpd_get_prop(NDMP_CRAM_MD5_USERNAME)) == NULL ||
4847917SReza.Sabdar@Sun.COM 		    *uname == 0) {
4857917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "Authorization denied.");
4867917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "User name is not set at server.");
4877917SReza.Sabdar@Sun.COM 			reply.error = NDMP_NOT_AUTHORIZED_ERR;
4887917SReza.Sabdar@Sun.COM 			ndmp_set_authorized(connection, FALSE);
4897917SReza.Sabdar@Sun.COM 			ndmp_send_reply(connection, (void *) &reply,
4907917SReza.Sabdar@Sun.COM 			    "sending ndmp_connect_client_auth reply");
4917917SReza.Sabdar@Sun.COM 			ndmpd_audit_connect(connection,
4927917SReza.Sabdar@Sun.COM 			    ADT_FAIL_PAM + PAM_AUTH_ERR);
4937917SReza.Sabdar@Sun.COM 			return;
4947917SReza.Sabdar@Sun.COM 		}
4957917SReza.Sabdar@Sun.COM 		type = "md5";
4967917SReza.Sabdar@Sun.COM 		session = ndmp_get_client_data(connection);
4977917SReza.Sabdar@Sun.COM 		md5 = &request->auth_data.ndmp_auth_data_v3_u.auth_md5;
4987917SReza.Sabdar@Sun.COM 		reply.error = ndmpd_connect_auth_md5(uname, md5->auth_id,
4997917SReza.Sabdar@Sun.COM 		    md5->auth_digest, session->ns_challenge);
5007917SReza.Sabdar@Sun.COM 		ndmpd_audit_connect(connection, reply.error ?
5017917SReza.Sabdar@Sun.COM 		    ADT_FAIL_PAM + PAM_AUTH_ERR : 0);
5027917SReza.Sabdar@Sun.COM 		break;
5037917SReza.Sabdar@Sun.COM 
5047917SReza.Sabdar@Sun.COM 	default:
5057917SReza.Sabdar@Sun.COM 		type = "unknown";
5067917SReza.Sabdar@Sun.COM 		reply.error = NDMP_ILLEGAL_ARGS_ERR;
5077917SReza.Sabdar@Sun.COM 		ndmpd_audit_connect(connection, EINVAL);
5087917SReza.Sabdar@Sun.COM 	}
5097917SReza.Sabdar@Sun.COM 
5107917SReza.Sabdar@Sun.COM 	if (reply.error == NDMP_NO_ERR) {
5117917SReza.Sabdar@Sun.COM 		ndmp_set_authorized(connection, TRUE);
5127917SReza.Sabdar@Sun.COM 	} else {
5137917SReza.Sabdar@Sun.COM 		ndmp_set_authorized(connection, FALSE);
5147917SReza.Sabdar@Sun.COM 		if (tcp_get_peer(connection->conn_sock, &addr.s_addr,
5157917SReza.Sabdar@Sun.COM 		    NULL) != -1) {
5167917SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR,
5177917SReza.Sabdar@Sun.COM 			    "Authorization(%s) denied for %s.", type,
5187917SReza.Sabdar@Sun.COM 			    inet_ntoa(IN_ADDR(addr)));
5197917SReza.Sabdar@Sun.COM 		}
5207917SReza.Sabdar@Sun.COM 	}
5217917SReza.Sabdar@Sun.COM 
5227917SReza.Sabdar@Sun.COM 	ndmp_send_reply(connection, (void *) &reply,
5237917SReza.Sabdar@Sun.COM 	    "sending ndmp_connect_auth reply");
5247917SReza.Sabdar@Sun.COM }
5257917SReza.Sabdar@Sun.COM 
5267917SReza.Sabdar@Sun.COM 
5277917SReza.Sabdar@Sun.COM /*
5287917SReza.Sabdar@Sun.COM  * ndmpd_connect_close_v3
5297917SReza.Sabdar@Sun.COM  *
5307917SReza.Sabdar@Sun.COM  * Close the connection to the DMA.
5317917SReza.Sabdar@Sun.COM  * Send the SHUTDOWN message before closing the socket connection to the DMA.
5327917SReza.Sabdar@Sun.COM  *
5337917SReza.Sabdar@Sun.COM  * Parameters:
5347917SReza.Sabdar@Sun.COM  *   connection (input) - connection handle.
5357917SReza.Sabdar@Sun.COM  *   msginfo    (input) - request message.
5367917SReza.Sabdar@Sun.COM  *
5377917SReza.Sabdar@Sun.COM  * Returns:
5387917SReza.Sabdar@Sun.COM  *   void
5397917SReza.Sabdar@Sun.COM  */
5407917SReza.Sabdar@Sun.COM /*ARGSUSED*/
5417917SReza.Sabdar@Sun.COM void
ndmpd_connect_close_v3(ndmp_connection_t * connection,void * body)5427917SReza.Sabdar@Sun.COM ndmpd_connect_close_v3(ndmp_connection_t *connection, void *body)
5437917SReza.Sabdar@Sun.COM {
5447917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session;
5457917SReza.Sabdar@Sun.COM 	ndmp_notify_connected_request req;
5467917SReza.Sabdar@Sun.COM 
5477917SReza.Sabdar@Sun.COM 	if (!(session = (ndmpd_session_t *)ndmp_get_client_data(connection)))
5487917SReza.Sabdar@Sun.COM 		return;
5497917SReza.Sabdar@Sun.COM 
5507917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "ver: %u",
5517917SReza.Sabdar@Sun.COM 	    session->ns_protocol_version);
5527917SReza.Sabdar@Sun.COM 
5537917SReza.Sabdar@Sun.COM 	/* Send the SHUTDOWN message before closing the connection. */
5547917SReza.Sabdar@Sun.COM 	req.reason = NDMP_SHUTDOWN;
5557917SReza.Sabdar@Sun.COM 	req.protocol_version = session->ns_protocol_version;
5567917SReza.Sabdar@Sun.COM 	req.text_reason = "Connection closed by server.";
5577917SReza.Sabdar@Sun.COM 
5587917SReza.Sabdar@Sun.COM 	if (ndmp_send_request(connection, NDMP_NOTIFY_CONNECTION_STATUS,
5597917SReza.Sabdar@Sun.COM 	    NDMP_NO_ERR, (void *) &req, 0) < 0) {
5607917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_NOTICE, "Sending connection shutdown notify");
5617917SReza.Sabdar@Sun.COM 		return;
5627917SReza.Sabdar@Sun.COM 	}
5637917SReza.Sabdar@Sun.COM 
5647917SReza.Sabdar@Sun.COM 	ndmp_close(connection);
5657917SReza.Sabdar@Sun.COM 	session->ns_eof = TRUE;
5667917SReza.Sabdar@Sun.COM }
5677917SReza.Sabdar@Sun.COM 
5687917SReza.Sabdar@Sun.COM /*
5697917SReza.Sabdar@Sun.COM  * ************************************************************************
5707917SReza.Sabdar@Sun.COM  * NDMP V4 HANDLERS
5717917SReza.Sabdar@Sun.COM  * ************************************************************************
5727917SReza.Sabdar@Sun.COM  */
5737917SReza.Sabdar@Sun.COM 
5747917SReza.Sabdar@Sun.COM /*
5757917SReza.Sabdar@Sun.COM  * ************************************************************************
5767917SReza.Sabdar@Sun.COM  * LOCALS
5777917SReza.Sabdar@Sun.COM  * ************************************************************************
5787917SReza.Sabdar@Sun.COM  */
5797917SReza.Sabdar@Sun.COM 
5807917SReza.Sabdar@Sun.COM /*
5817917SReza.Sabdar@Sun.COM  * create_md5_digest
5827917SReza.Sabdar@Sun.COM  *
5837917SReza.Sabdar@Sun.COM  * This function uses the MD5 message-digest algorithm described
5847917SReza.Sabdar@Sun.COM  * in RFC1321 to authenticate the client using a shared secret (password).
5857917SReza.Sabdar@Sun.COM  * The message used to compute the MD5 digest is a concatenation of password,
5867917SReza.Sabdar@Sun.COM  * null padding, the 64 byte fixed length challenge and a repeat of the
5877917SReza.Sabdar@Sun.COM  * password. The length of the null padding is chosen to result in a 128 byte
5887917SReza.Sabdar@Sun.COM  * fixed length message. The lengh of the padding can be computed as
5897917SReza.Sabdar@Sun.COM  * 64 - 2*(length of the password). The client digest is computed using the
5907917SReza.Sabdar@Sun.COM  * server challenge from the NDMP_CONFIG_GET_AUTH_ATTR reply.
5917917SReza.Sabdar@Sun.COM  *
5927917SReza.Sabdar@Sun.COM  * Parameters:
5937917SReza.Sabdar@Sun.COM  *   digest (output) - 16 bytes MD5 digest
5947917SReza.Sabdar@Sun.COM  *   passwd (input) - user password
5957917SReza.Sabdar@Sun.COM  *   challenge (input) - 64 bytes server challenge
5967917SReza.Sabdar@Sun.COM  *
5977917SReza.Sabdar@Sun.COM  * Returns:
5987917SReza.Sabdar@Sun.COM  *   void
5997917SReza.Sabdar@Sun.COM  */
6007917SReza.Sabdar@Sun.COM static void
create_md5_digest(unsigned char * digest,char * passwd,unsigned char * challenge)6017917SReza.Sabdar@Sun.COM create_md5_digest(unsigned char *digest, char *passwd, unsigned char *challenge)
6027917SReza.Sabdar@Sun.COM {
6037917SReza.Sabdar@Sun.COM 	char buf[130];
6047917SReza.Sabdar@Sun.COM 	char *p = &buf[0];
6057917SReza.Sabdar@Sun.COM 	int len, i;
6067917SReza.Sabdar@Sun.COM 	MD5_CTX md;
6077917SReza.Sabdar@Sun.COM 	char *pwd;
6087917SReza.Sabdar@Sun.COM 
6097917SReza.Sabdar@Sun.COM 	*p = 0;
6107917SReza.Sabdar@Sun.COM 	pwd = passwd;
6117917SReza.Sabdar@Sun.COM 	if ((len = strlen(pwd)) > MD5_PASS_LIMIT)
6127917SReza.Sabdar@Sun.COM 		len = MD5_PASS_LIMIT;
6137917SReza.Sabdar@Sun.COM 	(void) memcpy(p, pwd, len);
6147917SReza.Sabdar@Sun.COM 	p += len;
6157917SReza.Sabdar@Sun.COM 
6167917SReza.Sabdar@Sun.COM 	for (i = 0; i < MD5_CHALLENGE_SIZE - 2 * len; i++)
6177917SReza.Sabdar@Sun.COM 		*p++ = 0;
6187917SReza.Sabdar@Sun.COM 
6197917SReza.Sabdar@Sun.COM 	(void) memcpy(p, challenge, MD5_CHALLENGE_SIZE);
6207917SReza.Sabdar@Sun.COM 	p += MD5_CHALLENGE_SIZE;
6217917SReza.Sabdar@Sun.COM 	(void) strlcpy(p, pwd, MD5_PASS_LIMIT);
6227917SReza.Sabdar@Sun.COM 
6237917SReza.Sabdar@Sun.COM 	MD5Init(&md);
6247917SReza.Sabdar@Sun.COM 	MD5Update(&md, buf, 128);
6257917SReza.Sabdar@Sun.COM 	MD5Final(digest, &md);
6267917SReza.Sabdar@Sun.COM }
6277917SReza.Sabdar@Sun.COM 
6287917SReza.Sabdar@Sun.COM /*
6297917SReza.Sabdar@Sun.COM  * ndmp_connect_list_find
6307917SReza.Sabdar@Sun.COM  *
6317917SReza.Sabdar@Sun.COM  * Find the element in the active connection list.
6327917SReza.Sabdar@Sun.COM  *
6337917SReza.Sabdar@Sun.COM  * Parameters:
6347917SReza.Sabdar@Sun.COM  *   connection (input) - connection handler.
6357917SReza.Sabdar@Sun.COM  *
6367917SReza.Sabdar@Sun.COM  * Returns:
6377917SReza.Sabdar@Sun.COM  *   NULL - error
6387917SReza.Sabdar@Sun.COM  *   connection list element pointer
6397917SReza.Sabdar@Sun.COM  */
6407917SReza.Sabdar@Sun.COM static struct conn_list *
ndmp_connect_list_find(ndmp_connection_t * connection)6417917SReza.Sabdar@Sun.COM ndmp_connect_list_find(ndmp_connection_t *connection)
6427917SReza.Sabdar@Sun.COM {
6437917SReza.Sabdar@Sun.COM 	struct conn_list *clp;
6447917SReza.Sabdar@Sun.COM 
6457917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "connection: 0x%p",
6467917SReza.Sabdar@Sun.COM 	    connection);
6477917SReza.Sabdar@Sun.COM 
6487917SReza.Sabdar@Sun.COM 	LIST_FOREACH(clp, &cl_head, cl_q) {
6497917SReza.Sabdar@Sun.COM 		if (clp->cl_conn == connection) {
6507917SReza.Sabdar@Sun.COM 			(void) mutex_unlock(&cl_mutex);
6517917SReza.Sabdar@Sun.COM 			return (clp);
6527917SReza.Sabdar@Sun.COM 		}
6537917SReza.Sabdar@Sun.COM 	}
6547917SReza.Sabdar@Sun.COM 	return (NULL);
6557917SReza.Sabdar@Sun.COM }
6567917SReza.Sabdar@Sun.COM 
6577917SReza.Sabdar@Sun.COM /*
6587917SReza.Sabdar@Sun.COM  * ndmpconnect_list_add
6597917SReza.Sabdar@Sun.COM  *
6607917SReza.Sabdar@Sun.COM  * Add the new connection to the list of the active connections.
6617917SReza.Sabdar@Sun.COM  *
6627917SReza.Sabdar@Sun.COM  * Parameters:
6637917SReza.Sabdar@Sun.COM  *   connection (input) - connection handler.
6647917SReza.Sabdar@Sun.COM  *   id (input/output) - pointer to connection id.
6657917SReza.Sabdar@Sun.COM  *
6667917SReza.Sabdar@Sun.COM  * Returns:
6677917SReza.Sabdar@Sun.COM  *   0 - success
6687917SReza.Sabdar@Sun.COM  *  -1 - error
6697917SReza.Sabdar@Sun.COM  */
6707917SReza.Sabdar@Sun.COM int
ndmp_connect_list_add(ndmp_connection_t * connection,int * id)6717917SReza.Sabdar@Sun.COM ndmp_connect_list_add(ndmp_connection_t *connection, int *id)
6727917SReza.Sabdar@Sun.COM {
6737917SReza.Sabdar@Sun.COM 	struct conn_list *clp;
6747917SReza.Sabdar@Sun.COM 
6757917SReza.Sabdar@Sun.COM 	if (connection == NULL) {
6767917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Invalid argument");
6777917SReza.Sabdar@Sun.COM 		return (-1);
6787917SReza.Sabdar@Sun.COM 	}
6797917SReza.Sabdar@Sun.COM 
6807917SReza.Sabdar@Sun.COM 	if ((clp = ndmp_malloc(sizeof (struct conn_list))) == NULL)
6817917SReza.Sabdar@Sun.COM 		return (-1);
6827917SReza.Sabdar@Sun.COM 
6837917SReza.Sabdar@Sun.COM 	clp->cl_conn = connection;
6847917SReza.Sabdar@Sun.COM 	clp->cl_id = *id;
6857917SReza.Sabdar@Sun.COM 
6867917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&cl_mutex);
6877917SReza.Sabdar@Sun.COM 	LIST_INSERT_HEAD(&cl_head, clp, cl_q);
6887917SReza.Sabdar@Sun.COM 	(*id)++;
6897917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&cl_mutex);
6907917SReza.Sabdar@Sun.COM 
6917917SReza.Sabdar@Sun.COM 	return (0);
6927917SReza.Sabdar@Sun.COM }
6937917SReza.Sabdar@Sun.COM 
6947917SReza.Sabdar@Sun.COM /*
6957917SReza.Sabdar@Sun.COM  * ndmp_connect_list_del
6967917SReza.Sabdar@Sun.COM  *
6977917SReza.Sabdar@Sun.COM  * Delete the specified connection from the list.
6987917SReza.Sabdar@Sun.COM  *
6997917SReza.Sabdar@Sun.COM  * Parameters:
7007917SReza.Sabdar@Sun.COM  *   connection (input) - connection handler.
7017917SReza.Sabdar@Sun.COM  *
7027917SReza.Sabdar@Sun.COM  * Returns:
7037917SReza.Sabdar@Sun.COM  *   0 - success
7047917SReza.Sabdar@Sun.COM  *  -1 - error
7057917SReza.Sabdar@Sun.COM  */
7067917SReza.Sabdar@Sun.COM int
ndmp_connect_list_del(ndmp_connection_t * connection)7077917SReza.Sabdar@Sun.COM ndmp_connect_list_del(ndmp_connection_t *connection)
7087917SReza.Sabdar@Sun.COM {
7097917SReza.Sabdar@Sun.COM 	struct conn_list *clp;
7107917SReza.Sabdar@Sun.COM 
7117917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&cl_mutex);
7127917SReza.Sabdar@Sun.COM 	if (!(clp = ndmp_connect_list_find(connection))) {
7137917SReza.Sabdar@Sun.COM 		(void) mutex_unlock(&cl_mutex);
7147917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "connection not found");
7157917SReza.Sabdar@Sun.COM 		return (-1);
7167917SReza.Sabdar@Sun.COM 	}
7177917SReza.Sabdar@Sun.COM 
7187917SReza.Sabdar@Sun.COM 	LIST_REMOVE(clp, cl_q);
7197917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&cl_mutex);
7207917SReza.Sabdar@Sun.COM 	free(clp);
7217917SReza.Sabdar@Sun.COM 
7227917SReza.Sabdar@Sun.COM 	return (0);
7237917SReza.Sabdar@Sun.COM }
7247917SReza.Sabdar@Sun.COM 
7257917SReza.Sabdar@Sun.COM 
7267917SReza.Sabdar@Sun.COM /*
7277917SReza.Sabdar@Sun.COM  * ndmpconnect_list_find_id
7287917SReza.Sabdar@Sun.COM  *
7297917SReza.Sabdar@Sun.COM  * Find the element specified by its id in the list of active connections.
7307917SReza.Sabdar@Sun.COM  *
7317917SReza.Sabdar@Sun.COM  * Parameters:
7327917SReza.Sabdar@Sun.COM  *   id (input) - connection id.
7337917SReza.Sabdar@Sun.COM  *
7347917SReza.Sabdar@Sun.COM  * Returns:
7357917SReza.Sabdar@Sun.COM  *   NULL - error
7367917SReza.Sabdar@Sun.COM  *   connection list element pointer
7377917SReza.Sabdar@Sun.COM  */
7387917SReza.Sabdar@Sun.COM static struct conn_list *
ndmp_connect_list_find_id(int id)7397917SReza.Sabdar@Sun.COM ndmp_connect_list_find_id(int id)
7407917SReza.Sabdar@Sun.COM {
7417917SReza.Sabdar@Sun.COM 	struct conn_list *clp;
7427917SReza.Sabdar@Sun.COM 
7437917SReza.Sabdar@Sun.COM 	NDMP_LOG(LOG_DEBUG, "id: %d", id);
7447917SReza.Sabdar@Sun.COM 
7457917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&cl_mutex);
7467917SReza.Sabdar@Sun.COM 	LIST_FOREACH(clp, &cl_head, cl_q) {
7477917SReza.Sabdar@Sun.COM 		if (clp->cl_id == id) {
7487917SReza.Sabdar@Sun.COM 			(void) mutex_unlock(&cl_mutex);
7497917SReza.Sabdar@Sun.COM 			return (clp);
7507917SReza.Sabdar@Sun.COM 		}
7517917SReza.Sabdar@Sun.COM 	}
7527917SReza.Sabdar@Sun.COM 
7537917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&cl_mutex);
7547917SReza.Sabdar@Sun.COM 	return (NULL);
7557917SReza.Sabdar@Sun.COM }
7567917SReza.Sabdar@Sun.COM 
7577917SReza.Sabdar@Sun.COM /*
7587917SReza.Sabdar@Sun.COM  * Get common fields of the active connection.
7597917SReza.Sabdar@Sun.COM  */
7607917SReza.Sabdar@Sun.COM static void
ndmp_connect_get_conn(struct conn_list * clp,ndmp_door_ctx_t * enc_ctx)7617917SReza.Sabdar@Sun.COM ndmp_connect_get_conn(struct conn_list *clp, ndmp_door_ctx_t *enc_ctx)
7627917SReza.Sabdar@Sun.COM {
7637917SReza.Sabdar@Sun.COM 	int port;
7647917SReza.Sabdar@Sun.COM 	struct in_addr addr;
7657917SReza.Sabdar@Sun.COM 	char cl_addr[NDMP_CL_ADDR_LEN];
7667917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session;
7677917SReza.Sabdar@Sun.COM 
7687917SReza.Sabdar@Sun.COM 	if (!(session = (ndmpd_session_t *)ndmp_get_client_data(clp->cl_conn)))
7697917SReza.Sabdar@Sun.COM 		return;
7707917SReza.Sabdar@Sun.COM 
7717917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, clp->cl_id);
7727917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_protocol_version);
7737917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, clp->cl_conn->conn_authorized);
7747917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_eof);
7757917SReza.Sabdar@Sun.COM 	if (tcp_get_peer(clp->cl_conn->conn_sock, &(addr.s_addr), &port) != -1)
7767917SReza.Sabdar@Sun.COM 		(void) snprintf(cl_addr, NDMP_CL_ADDR_LEN, "%s:%d",
7777917SReza.Sabdar@Sun.COM 		    (char *)inet_ntoa(addr), port);
7787917SReza.Sabdar@Sun.COM 	else
7797917SReza.Sabdar@Sun.COM 		cl_addr[0] = '\0';
7807917SReza.Sabdar@Sun.COM 	ndmp_door_put_string(enc_ctx, cl_addr);
7817917SReza.Sabdar@Sun.COM }
7827917SReza.Sabdar@Sun.COM 
7837917SReza.Sabdar@Sun.COM /*
7847917SReza.Sabdar@Sun.COM  * Get the connection SCSI info.
7857917SReza.Sabdar@Sun.COM  */
7867917SReza.Sabdar@Sun.COM static void
ndmp_connect_get_scsi_v2(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)7877917SReza.Sabdar@Sun.COM ndmp_connect_get_scsi_v2(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
7887917SReza.Sabdar@Sun.COM {
7897917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_scsi.sd_is_open);
7907917SReza.Sabdar@Sun.COM 	ndmp_door_put_string(enc_ctx, session->ns_scsi.sd_adapter_name);
7917917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_scsi.sd_valid_target_set);
7927917SReza.Sabdar@Sun.COM 	if (session->ns_scsi.sd_valid_target_set) {
7937917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, session->ns_scsi.sd_sid);
7947917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, session->ns_scsi.sd_lun);
7957917SReza.Sabdar@Sun.COM 	}
7967917SReza.Sabdar@Sun.COM }
7977917SReza.Sabdar@Sun.COM 
7987917SReza.Sabdar@Sun.COM /*
7997917SReza.Sabdar@Sun.COM  * Get the connection tape info.
8007917SReza.Sabdar@Sun.COM  */
8017917SReza.Sabdar@Sun.COM static void
ndmp_connect_get_tape_v2(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)8027917SReza.Sabdar@Sun.COM ndmp_connect_get_tape_v2(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
8037917SReza.Sabdar@Sun.COM {
8047917SReza.Sabdar@Sun.COM 	char dev_name[NDMP_TAPE_DEV_NAME];
8057917SReza.Sabdar@Sun.COM 
8067917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_tape.td_fd);
8077917SReza.Sabdar@Sun.COM 	if (session->ns_tape.td_fd != -1) {
8087917SReza.Sabdar@Sun.COM 		ndmp_door_put_uint64(enc_ctx, session->ns_tape.td_record_count);
8097917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, session->ns_tape.td_mode);
8107917SReza.Sabdar@Sun.COM 		(void) snprintf(dev_name, NDMP_TAPE_DEV_NAME, "%st%02x%x",
8117917SReza.Sabdar@Sun.COM 		    session->ns_tape.td_adapter_name, session->ns_tape.td_sid,
8127917SReza.Sabdar@Sun.COM 		    session->ns_tape.td_lun);
8137917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, dev_name);
8147917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, session->ns_tape.td_adapter_name);
8157917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, session->ns_tape.td_sid);
8167917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, session->ns_tape.td_lun);
8177917SReza.Sabdar@Sun.COM 	}
8187917SReza.Sabdar@Sun.COM }
8197917SReza.Sabdar@Sun.COM 
8207917SReza.Sabdar@Sun.COM /*
8217917SReza.Sabdar@Sun.COM  * Get the connection mover info.
8227917SReza.Sabdar@Sun.COM  */
8237917SReza.Sabdar@Sun.COM static void
ndmp_connect_get_mover_v2(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)8247917SReza.Sabdar@Sun.COM ndmp_connect_get_mover_v2(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
8257917SReza.Sabdar@Sun.COM {
8267917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_mover.md_state);
8277917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_mover.md_mode);
8287917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_mover.md_pause_reason);
8297917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_mover.md_halt_reason);
8307917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint64(enc_ctx, session->ns_mover.md_record_size);
8317917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint64(enc_ctx, session->ns_mover.md_record_num);
8327917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint64(enc_ctx, session->ns_mover.md_position);
8337917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint64(enc_ctx, session->ns_mover.md_window_offset);
8347917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint64(enc_ctx, session->ns_mover.md_window_length);
8357917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_mover.md_sock);
8367917SReza.Sabdar@Sun.COM }
8377917SReza.Sabdar@Sun.COM 
8387917SReza.Sabdar@Sun.COM /*
8397917SReza.Sabdar@Sun.COM  * Get the connection common data info.
8407917SReza.Sabdar@Sun.COM  */
8417917SReza.Sabdar@Sun.COM static void
ndmp_connect_get_data_common(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)8427917SReza.Sabdar@Sun.COM ndmp_connect_get_data_common(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
8437917SReza.Sabdar@Sun.COM {
8447917SReza.Sabdar@Sun.COM 	int i;
8457917SReza.Sabdar@Sun.COM 	ndmp_pval *ep;
8467917SReza.Sabdar@Sun.COM 	int len;
8477917SReza.Sabdar@Sun.COM 
8487917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_data.dd_operation);
8497917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_data.dd_state);
8507917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_data.dd_halt_reason);
8517917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_data.dd_sock);
8527917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_data.dd_mover.addr_type);
8537917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_data.dd_abort);
8547917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint64(enc_ctx, session->ns_data.dd_read_offset);
8557917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint64(enc_ctx, session->ns_data.dd_read_length);
8567917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint64(enc_ctx, session->ns_data.dd_data_size);
8577917SReza.Sabdar@Sun.COM 	/* verify data.env has as much data as in session->ns_data.dd_env_len */
8587917SReza.Sabdar@Sun.COM 	len = 0;
8597917SReza.Sabdar@Sun.COM 	ep = session->ns_data.dd_env;
8607917SReza.Sabdar@Sun.COM 	for (i = 0; ep && i < session->ns_data.dd_env_len; i++, ep++)
8617917SReza.Sabdar@Sun.COM 		len++;
8627917SReza.Sabdar@Sun.COM 
8637917SReza.Sabdar@Sun.COM 	/* put the len */
8647917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&session->ns_lock);
8657917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint64(enc_ctx, len);
8667917SReza.Sabdar@Sun.COM 	ep = session->ns_data.dd_env;
8677917SReza.Sabdar@Sun.COM 	for (i = 0; i < len; i++, ep++) {
8687917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, ep->name);
8697917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, ep->value);
8707917SReza.Sabdar@Sun.COM 	}
8717917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&session->ns_lock);
8727917SReza.Sabdar@Sun.COM }
8737917SReza.Sabdar@Sun.COM 
8747917SReza.Sabdar@Sun.COM /*
8757917SReza.Sabdar@Sun.COM  * Get the connection data info.
8767917SReza.Sabdar@Sun.COM  */
8777917SReza.Sabdar@Sun.COM static void
ndmp_connect_get_data_v2(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)8787917SReza.Sabdar@Sun.COM ndmp_connect_get_data_v2(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
8797917SReza.Sabdar@Sun.COM {
8807917SReza.Sabdar@Sun.COM 	int i;
8817917SReza.Sabdar@Sun.COM 	ndmp_name *np;
8827917SReza.Sabdar@Sun.COM 	char tcp_addr[NDMP_TCP_ADDR_SIZE];
8837917SReza.Sabdar@Sun.COM 
8847917SReza.Sabdar@Sun.COM 	ndmp_connect_get_data_common(session, enc_ctx);
8857917SReza.Sabdar@Sun.COM 
8867917SReza.Sabdar@Sun.COM 	switch (session->ns_data.dd_mover.addr_type) {
8877917SReza.Sabdar@Sun.COM 	case NDMP_ADDR_LOCAL:
8887917SReza.Sabdar@Sun.COM 		(void) snprintf(tcp_addr, NDMP_TCP_ADDR_SIZE, "%s", "Local");
8897917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, tcp_addr);
8907917SReza.Sabdar@Sun.COM 		break;
8917917SReza.Sabdar@Sun.COM 	case NDMP_ADDR_TCP:
8927917SReza.Sabdar@Sun.COM 		(void) snprintf(tcp_addr, NDMP_TCP_ADDR_SIZE, "%s:%d",
8937917SReza.Sabdar@Sun.COM 		    (char *)inet_ntoa(IN_ADDR(
8947917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_mover.ndmp_mover_addr_u.addr.ip_addr)),
8957917SReza.Sabdar@Sun.COM 		    session->ns_data.dd_mover.ndmp_mover_addr_u.addr.port);
8967917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, tcp_addr);
8977917SReza.Sabdar@Sun.COM 		break;
8987917SReza.Sabdar@Sun.COM 	default:
8997917SReza.Sabdar@Sun.COM 		(void) snprintf(tcp_addr, NDMP_TCP_ADDR_SIZE, "%s", "Unknown");
9007917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, tcp_addr);
9017917SReza.Sabdar@Sun.COM 	}
9027917SReza.Sabdar@Sun.COM 
9037917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint64(enc_ctx, session->ns_data.dd_nlist_len);
9047917SReza.Sabdar@Sun.COM 	np = session->ns_data.dd_nlist;
9057917SReza.Sabdar@Sun.COM 	for (i = 0; np && i < (int)session->ns_data.dd_nlist_len; i++, np++) {
9067917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, np->name);
9077917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, np->dest);
9087917SReza.Sabdar@Sun.COM 	}
9097917SReza.Sabdar@Sun.COM }
9107917SReza.Sabdar@Sun.COM 
9117917SReza.Sabdar@Sun.COM /*
9127917SReza.Sabdar@Sun.COM  * Get V2 connection info.
9137917SReza.Sabdar@Sun.COM  */
9147917SReza.Sabdar@Sun.COM static void
ndmp_connect_get_v2(ndmp_connection_t * connection,ndmp_door_ctx_t * enc_ctx)9157917SReza.Sabdar@Sun.COM ndmp_connect_get_v2(ndmp_connection_t *connection, ndmp_door_ctx_t *enc_ctx)
9167917SReza.Sabdar@Sun.COM {
9177917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session;
9187917SReza.Sabdar@Sun.COM 
9197917SReza.Sabdar@Sun.COM 	if ((session = (ndmpd_session_t *)ndmp_get_client_data(connection))) {
9207917SReza.Sabdar@Sun.COM 		ndmp_connect_get_scsi_v2(session, enc_ctx);
9217917SReza.Sabdar@Sun.COM 		ndmp_connect_get_tape_v2(session, enc_ctx);
9227917SReza.Sabdar@Sun.COM 		ndmp_connect_get_mover_v2(session, enc_ctx);
9237917SReza.Sabdar@Sun.COM 		ndmp_connect_get_data_v2(session, enc_ctx);
9247917SReza.Sabdar@Sun.COM 	}
9257917SReza.Sabdar@Sun.COM }
9267917SReza.Sabdar@Sun.COM 
9277917SReza.Sabdar@Sun.COM /*
9287917SReza.Sabdar@Sun.COM  * Get the V3 connection mover info.
9297917SReza.Sabdar@Sun.COM  */
9307917SReza.Sabdar@Sun.COM static void
ndmp_connect_get_mover_v3(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)9317917SReza.Sabdar@Sun.COM ndmp_connect_get_mover_v3(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
9327917SReza.Sabdar@Sun.COM {
9337917SReza.Sabdar@Sun.COM 	char tcp_addr[NDMP_TCP_ADDR_SIZE];
9347917SReza.Sabdar@Sun.COM 
9357917SReza.Sabdar@Sun.COM 	/* get all the V2 mover data first */
9367917SReza.Sabdar@Sun.COM 	ndmp_connect_get_mover_v2(session, enc_ctx);
9377917SReza.Sabdar@Sun.COM 
9387917SReza.Sabdar@Sun.COM 	/* get the V3 mover data now */
9397917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_mover.md_listen_sock);
9407917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_mover.md_data_addr.addr_type);
9417917SReza.Sabdar@Sun.COM 	tcp_addr[0] = '\0';
9427917SReza.Sabdar@Sun.COM 	(void) snprintf(tcp_addr, NDMP_TCP_ADDR_SIZE, "%s:%d",
9437917SReza.Sabdar@Sun.COM 	    (char *)
9447917SReza.Sabdar@Sun.COM 	    inet_ntoa(IN_ADDR(session->ns_mover.md_data_addr.tcp_ip_v3)),
9457917SReza.Sabdar@Sun.COM 	    (int)session->ns_mover.md_data_addr.tcp_port_v3);
9467917SReza.Sabdar@Sun.COM 	ndmp_door_put_string(enc_ctx, tcp_addr);
9477917SReza.Sabdar@Sun.COM }
9487917SReza.Sabdar@Sun.COM 
9497917SReza.Sabdar@Sun.COM /*
9507917SReza.Sabdar@Sun.COM  * Get the connection data info.
9517917SReza.Sabdar@Sun.COM  */
9527917SReza.Sabdar@Sun.COM static void
ndmp_connect_get_data_v3(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)9537917SReza.Sabdar@Sun.COM ndmp_connect_get_data_v3(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
9547917SReza.Sabdar@Sun.COM {
9557917SReza.Sabdar@Sun.COM 	ulong_t i;
9567917SReza.Sabdar@Sun.COM 	mem_ndmp_name_v3_t *np;
9577917SReza.Sabdar@Sun.COM 	char tcp_addr[NDMP_TCP_ADDR_SIZE];
9587917SReza.Sabdar@Sun.COM 
9597917SReza.Sabdar@Sun.COM 	ndmp_connect_get_data_common(session, enc_ctx);
9607917SReza.Sabdar@Sun.COM 
9617917SReza.Sabdar@Sun.COM 	(void) snprintf(tcp_addr, NDMP_TCP_ADDR_SIZE, "%s:%d",
9627917SReza.Sabdar@Sun.COM 	    (char *)inet_ntoa(IN_ADDR(session->ns_data.dd_data_addr.tcp_ip_v3)),
9637917SReza.Sabdar@Sun.COM 	    (int)session->ns_data.dd_data_addr.tcp_port_v3);
9647917SReza.Sabdar@Sun.COM 	ndmp_door_put_string(enc_ctx, tcp_addr);
9657917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, session->ns_data.dd_listen_sock);
9667917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint64(enc_ctx,
9677917SReza.Sabdar@Sun.COM 	    session->ns_data.dd_module.dm_stats.ms_bytes_processed);
9687917SReza.Sabdar@Sun.COM 	ndmp_door_put_uint64(enc_ctx, session->ns_data.dd_nlist_len);
9697917SReza.Sabdar@Sun.COM 	np = session->ns_data.dd_nlist_v3;
9707917SReza.Sabdar@Sun.COM 	for (i = 0; np && i < (int)session->ns_data.dd_nlist_len; i++, np++) {
9717917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, np->nm3_opath);
9727917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, np->nm3_dpath);
9737917SReza.Sabdar@Sun.COM 		ndmp_door_put_uint64(enc_ctx, np->nm3_node);
9747917SReza.Sabdar@Sun.COM 		ndmp_door_put_uint64(enc_ctx, np->nm3_fh_info);
9757917SReza.Sabdar@Sun.COM 	}
9767917SReza.Sabdar@Sun.COM }
9777917SReza.Sabdar@Sun.COM 
9787917SReza.Sabdar@Sun.COM /*
9797917SReza.Sabdar@Sun.COM  * Get V3 connection info.
9807917SReza.Sabdar@Sun.COM  */
9817917SReza.Sabdar@Sun.COM static void
ndmp_connect_get_v3(ndmp_connection_t * connection,ndmp_door_ctx_t * enc_ctx)9827917SReza.Sabdar@Sun.COM ndmp_connect_get_v3(ndmp_connection_t *connection, ndmp_door_ctx_t *enc_ctx)
9837917SReza.Sabdar@Sun.COM {
9847917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session;
9857917SReza.Sabdar@Sun.COM 
9867917SReza.Sabdar@Sun.COM 	if ((session = (ndmpd_session_t *)ndmp_get_client_data(connection))) {
9877917SReza.Sabdar@Sun.COM 		ndmp_connect_get_scsi_v2(session, enc_ctx);
9887917SReza.Sabdar@Sun.COM 		ndmp_connect_get_tape_v2(session, enc_ctx);
9897917SReza.Sabdar@Sun.COM 		ndmp_connect_get_mover_v3(session, enc_ctx);
9907917SReza.Sabdar@Sun.COM 		ndmp_connect_get_data_v3(session, enc_ctx);
9917917SReza.Sabdar@Sun.COM 	}
9927917SReza.Sabdar@Sun.COM }
9937917SReza.Sabdar@Sun.COM 
9947917SReza.Sabdar@Sun.COM /*
9957917SReza.Sabdar@Sun.COM  * Get the list of all active sessions to the clients.  For each version,
9967917SReza.Sabdar@Sun.COM  * call the appropriate get function.
9977917SReza.Sabdar@Sun.COM  */
9987917SReza.Sabdar@Sun.COM static void
connection_get(struct conn_list * clp,ndmp_door_ctx_t * enc_ctx)9997917SReza.Sabdar@Sun.COM connection_get(struct conn_list *clp, ndmp_door_ctx_t *enc_ctx)
10007917SReza.Sabdar@Sun.COM {
10017917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session;
10027917SReza.Sabdar@Sun.COM 
10037917SReza.Sabdar@Sun.COM 	session = (ndmpd_session_t *)ndmp_get_client_data(clp->cl_conn);
10047917SReza.Sabdar@Sun.COM 	if (!session) {
10057917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, NDMP_SESSION_NODATA);
10067917SReza.Sabdar@Sun.COM 		return;
10077917SReza.Sabdar@Sun.COM 	}
10087917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, NDMP_SESSION_DATA);
10097917SReza.Sabdar@Sun.COM 
10107917SReza.Sabdar@Sun.COM 	switch (session->ns_protocol_version) {
10117917SReza.Sabdar@Sun.COM 	case NDMPV2:
10127917SReza.Sabdar@Sun.COM 		ndmp_connect_get_conn(clp, enc_ctx);
10137917SReza.Sabdar@Sun.COM 		ndmp_connect_get_v2(clp->cl_conn, enc_ctx);
10147917SReza.Sabdar@Sun.COM 		break;
10157917SReza.Sabdar@Sun.COM 	case NDMPV3:
10167917SReza.Sabdar@Sun.COM 	case NDMPV4:
10177917SReza.Sabdar@Sun.COM 		ndmp_connect_get_conn(clp, enc_ctx);
10187917SReza.Sabdar@Sun.COM 		ndmp_connect_get_v3(clp->cl_conn, enc_ctx);
10197917SReza.Sabdar@Sun.COM 		break;
10207917SReza.Sabdar@Sun.COM 	default:
10217917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG,
10227917SReza.Sabdar@Sun.COM 		    "Invalid session (0x%p) version 0x%x", session,
10237917SReza.Sabdar@Sun.COM 		    session->ns_protocol_version);
10247917SReza.Sabdar@Sun.COM 	}
10257917SReza.Sabdar@Sun.COM }
10267917SReza.Sabdar@Sun.COM 
10277917SReza.Sabdar@Sun.COM /*
10287917SReza.Sabdar@Sun.COM  * ndmpd_connect_kill
10297917SReza.Sabdar@Sun.COM  *
10307917SReza.Sabdar@Sun.COM  * Kill the connection based on its version.
10317917SReza.Sabdar@Sun.COM  *
10327917SReza.Sabdar@Sun.COM  * Parameters:
10337917SReza.Sabdar@Sun.COM  *   connection (input) - connection handler.
10347917SReza.Sabdar@Sun.COM  *
10357917SReza.Sabdar@Sun.COM  * Returns:
10367917SReza.Sabdar@Sun.COM  *   0 - success
10377917SReza.Sabdar@Sun.COM  *  -1 - error
10387917SReza.Sabdar@Sun.COM  */
10397917SReza.Sabdar@Sun.COM int
ndmpd_connect_kill(ndmp_connection_t * connection)10407917SReza.Sabdar@Sun.COM ndmpd_connect_kill(ndmp_connection_t *connection)
10417917SReza.Sabdar@Sun.COM {
10427917SReza.Sabdar@Sun.COM 	ndmpd_session_t *session;
10437917SReza.Sabdar@Sun.COM 
10447917SReza.Sabdar@Sun.COM 	if (!(session = (ndmpd_session_t *)ndmp_get_client_data(connection)))
10457917SReza.Sabdar@Sun.COM 		return (-1);
10467917SReza.Sabdar@Sun.COM 
10477917SReza.Sabdar@Sun.COM 	switch (session->ns_protocol_version) {
10487917SReza.Sabdar@Sun.COM 	case NDMPV2:
10497917SReza.Sabdar@Sun.COM 		nlp_event_rv_set(session, -2);
10507917SReza.Sabdar@Sun.COM 		nlp_event_nw(session);
10517917SReza.Sabdar@Sun.COM 		ndmpd_connect_close_v2(connection, (void *)NULL);
10527917SReza.Sabdar@Sun.COM 		break;
10537917SReza.Sabdar@Sun.COM 	case NDMPV3:
10547917SReza.Sabdar@Sun.COM 	case NDMPV4:
10557917SReza.Sabdar@Sun.COM 		nlp_event_rv_set(session, -2);
10567917SReza.Sabdar@Sun.COM 		nlp_event_nw(session);
10577917SReza.Sabdar@Sun.COM 		ndmpd_connect_close_v3(connection, (void *)NULL);
10587917SReza.Sabdar@Sun.COM 		break;
10597917SReza.Sabdar@Sun.COM 	default:
10607917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG,
10617917SReza.Sabdar@Sun.COM 		    "Invalid session (0x%p) version 0x%x", session,
10627917SReza.Sabdar@Sun.COM 		    session->ns_protocol_version);
10637917SReza.Sabdar@Sun.COM 	}
10647917SReza.Sabdar@Sun.COM 
10657917SReza.Sabdar@Sun.COM 	return (0);
10667917SReza.Sabdar@Sun.COM }
10677917SReza.Sabdar@Sun.COM 
10687917SReza.Sabdar@Sun.COM /*
10697917SReza.Sabdar@Sun.COM  * Get the list of all active sessions to the clients.
10707917SReza.Sabdar@Sun.COM  */
10717917SReza.Sabdar@Sun.COM void
ndmp_connect_list_get(ndmp_door_ctx_t * enc_ctx)10727917SReza.Sabdar@Sun.COM ndmp_connect_list_get(ndmp_door_ctx_t *enc_ctx)
10737917SReza.Sabdar@Sun.COM {
10747917SReza.Sabdar@Sun.COM 	int n;
10757917SReza.Sabdar@Sun.COM 	struct conn_list *clp;
10767917SReza.Sabdar@Sun.COM 
10777917SReza.Sabdar@Sun.COM 	n = 0;
10787917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&cl_mutex);
10797917SReza.Sabdar@Sun.COM 	LIST_FOREACH(clp, &cl_head, cl_q) {
10807917SReza.Sabdar@Sun.COM 		n++;
10817917SReza.Sabdar@Sun.COM 	}
10827917SReza.Sabdar@Sun.COM 	/* write number of connections */
10837917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, n);
10847917SReza.Sabdar@Sun.COM 	n = 0;
10857917SReza.Sabdar@Sun.COM 	LIST_FOREACH(clp, &cl_head, cl_q) {
10867917SReza.Sabdar@Sun.COM 		connection_get(clp, enc_ctx);
10877917SReza.Sabdar@Sun.COM 		n++;
10887917SReza.Sabdar@Sun.COM 	}
10897917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&cl_mutex);
10907917SReza.Sabdar@Sun.COM }
10917917SReza.Sabdar@Sun.COM 
10927917SReza.Sabdar@Sun.COM /*
10937917SReza.Sabdar@Sun.COM  * ndmpd_connect_kill_id
10947917SReza.Sabdar@Sun.COM  *
10957917SReza.Sabdar@Sun.COM  * Find a connection by its id and kill it.
10967917SReza.Sabdar@Sun.COM  *
10977917SReza.Sabdar@Sun.COM  * Parameters:
10987917SReza.Sabdar@Sun.COM  *   id (input) - connection id.
10997917SReza.Sabdar@Sun.COM  *
11007917SReza.Sabdar@Sun.COM  * Returns:
11017917SReza.Sabdar@Sun.COM  *   0 - success
11027917SReza.Sabdar@Sun.COM  *  -1 - error
11037917SReza.Sabdar@Sun.COM  */
11047917SReza.Sabdar@Sun.COM int
ndmpd_connect_kill_id(int id)11057917SReza.Sabdar@Sun.COM ndmpd_connect_kill_id(int id)
11067917SReza.Sabdar@Sun.COM {
11077917SReza.Sabdar@Sun.COM 	struct conn_list *clp;
11087917SReza.Sabdar@Sun.COM 
11097917SReza.Sabdar@Sun.COM 	if (!(clp = ndmp_connect_list_find_id(id)))
11107917SReza.Sabdar@Sun.COM 		return (-1);
11117917SReza.Sabdar@Sun.COM 
11127917SReza.Sabdar@Sun.COM 	return (ndmpd_connect_kill(clp->cl_conn));
11137917SReza.Sabdar@Sun.COM }
11147917SReza.Sabdar@Sun.COM 
11157917SReza.Sabdar@Sun.COM /* Get the devices info */
11167917SReza.Sabdar@Sun.COM void
ndmpd_get_devs(ndmp_door_ctx_t * enc_ctx)11177917SReza.Sabdar@Sun.COM ndmpd_get_devs(ndmp_door_ctx_t *enc_ctx)
11187917SReza.Sabdar@Sun.COM {
11197917SReza.Sabdar@Sun.COM 	int i, n;
11207917SReza.Sabdar@Sun.COM 	sasd_drive_t *sd;
11217917SReza.Sabdar@Sun.COM 	scsi_link_t *slink;
11227917SReza.Sabdar@Sun.COM 
11237917SReza.Sabdar@Sun.COM 	if ((n = sasd_dev_count()) == 0) {
11247917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, n);
11257917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "No device attached.");
11267917SReza.Sabdar@Sun.COM 		return;
11277917SReza.Sabdar@Sun.COM 	}
11287917SReza.Sabdar@Sun.COM 	ndmp_door_put_int32(enc_ctx, n);
11297917SReza.Sabdar@Sun.COM 
11307917SReza.Sabdar@Sun.COM 	for (i = 0; i < n; i++) {
11317917SReza.Sabdar@Sun.COM 		sd = sasd_drive(i);
11327917SReza.Sabdar@Sun.COM 		slink = sasd_dev_slink(i);
11337917SReza.Sabdar@Sun.COM 
11347917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, slink->sl_type);
11357917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, sd->sd_name);
11367917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, slink->sl_lun);
11377917SReza.Sabdar@Sun.COM 		ndmp_door_put_int32(enc_ctx, slink->sl_sid);
11387917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, sd->sd_vendor);
11397917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, sd->sd_id);
11407917SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, sd->sd_rev);
1141*8193SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, sd->sd_serial);
1142*8193SReza.Sabdar@Sun.COM 		ndmp_door_put_string(enc_ctx, sd->sd_wwn);
11437917SReza.Sabdar@Sun.COM 	}
11447917SReza.Sabdar@Sun.COM }
11457917SReza.Sabdar@Sun.COM 
11467917SReza.Sabdar@Sun.COM /*
11477917SReza.Sabdar@Sun.COM  * ndmpd_connect_auth_text
11487917SReza.Sabdar@Sun.COM  *
11497917SReza.Sabdar@Sun.COM  * Checks text authorization.
11507917SReza.Sabdar@Sun.COM  *
11517917SReza.Sabdar@Sun.COM  * Parameters:
11527917SReza.Sabdar@Sun.COM  *   auth_id (input) - user name
11537917SReza.Sabdar@Sun.COM  *   auth_password(input) - password
11547917SReza.Sabdar@Sun.COM  *
11557917SReza.Sabdar@Sun.COM  * Returns:
11567917SReza.Sabdar@Sun.COM  *   NDMP_NO_ERR: on success
11577917SReza.Sabdar@Sun.COM  *   Other NDMP_ error: invalid user name and password
11587917SReza.Sabdar@Sun.COM  */
11597917SReza.Sabdar@Sun.COM int
ndmpd_connect_auth_text(char * uname,char * auth_id,char * auth_password)11607917SReza.Sabdar@Sun.COM ndmpd_connect_auth_text(char *uname, char *auth_id, char *auth_password)
11617917SReza.Sabdar@Sun.COM {
11627917SReza.Sabdar@Sun.COM 	char *passwd, *dec_passwd;
11637917SReza.Sabdar@Sun.COM 	int rv;
11647917SReza.Sabdar@Sun.COM 
11657917SReza.Sabdar@Sun.COM 	if (strcmp(uname, auth_id) != 0) {
11667917SReza.Sabdar@Sun.COM 		rv = NDMP_NOT_AUTHORIZED_ERR;
11677917SReza.Sabdar@Sun.COM 	} else {
11687917SReza.Sabdar@Sun.COM 		passwd = ndmpd_get_prop(NDMP_CLEARTEXT_PASSWORD);
11697917SReza.Sabdar@Sun.COM 		if (!passwd || !*passwd) {
11707917SReza.Sabdar@Sun.COM 			rv = NDMP_NOT_AUTHORIZED_ERR;
11717917SReza.Sabdar@Sun.COM 		} else {
11727917SReza.Sabdar@Sun.COM 			dec_passwd = ndmp_base64_decode(passwd);
11737917SReza.Sabdar@Sun.COM 			if (dec_passwd == NULL || *dec_passwd == 0)
11747917SReza.Sabdar@Sun.COM 				rv = NDMP_NOT_AUTHORIZED_ERR;
11757917SReza.Sabdar@Sun.COM 			else if (strcmp(auth_password, dec_passwd) != 0)
11767917SReza.Sabdar@Sun.COM 				rv = NDMP_NOT_AUTHORIZED_ERR;
11777917SReza.Sabdar@Sun.COM 			else
11787917SReza.Sabdar@Sun.COM 				rv = NDMP_NO_ERR;
11797917SReza.Sabdar@Sun.COM 
11807917SReza.Sabdar@Sun.COM 			free(dec_passwd);
11817917SReza.Sabdar@Sun.COM 		}
11827917SReza.Sabdar@Sun.COM 	}
11837917SReza.Sabdar@Sun.COM 
11847917SReza.Sabdar@Sun.COM 	if (rv == NDMP_NO_ERR) {
11857917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Authorization granted.");
11867917SReza.Sabdar@Sun.COM 	} else {
11877917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Authorization denied.");
11887917SReza.Sabdar@Sun.COM 	}
11897917SReza.Sabdar@Sun.COM 
11907917SReza.Sabdar@Sun.COM 	return (rv);
11917917SReza.Sabdar@Sun.COM }
11927917SReza.Sabdar@Sun.COM 
11937917SReza.Sabdar@Sun.COM 
11947917SReza.Sabdar@Sun.COM /*
11957917SReza.Sabdar@Sun.COM  * ndmpd_connect_auth_md5
11967917SReza.Sabdar@Sun.COM  *
11977917SReza.Sabdar@Sun.COM  * Checks MD5 authorization.
11987917SReza.Sabdar@Sun.COM  *
11997917SReza.Sabdar@Sun.COM  * Parameters:
12007917SReza.Sabdar@Sun.COM  *   auth_id (input) - user name
12017917SReza.Sabdar@Sun.COM  *   auth_digest(input) - MD5 digest
12027917SReza.Sabdar@Sun.COM  * 	This is a 16 bytes digest info which is a MD5 transform of 128 bytes
12037917SReza.Sabdar@Sun.COM  * 	message (password + padding + server challenge + password). Server
12047917SReza.Sabdar@Sun.COM  * 	challenge is a 64 bytes random string per NDMP session sent out to the
12057917SReza.Sabdar@Sun.COM  * 	client on demand (See NDMP_CONFIG_GET_AUTH_ATTR command).
12067917SReza.Sabdar@Sun.COM  *
12077917SReza.Sabdar@Sun.COM  * Returns:
12087917SReza.Sabdar@Sun.COM  *   NDMP_NO_ERR: on success
12097917SReza.Sabdar@Sun.COM  *   Other NDMP_ error: invalid user name and password
12107917SReza.Sabdar@Sun.COM  */
12117917SReza.Sabdar@Sun.COM int
ndmpd_connect_auth_md5(char * uname,char * auth_id,char * auth_digest,unsigned char * auth_challenge)12127917SReza.Sabdar@Sun.COM ndmpd_connect_auth_md5(char *uname, char *auth_id, char *auth_digest,
12137917SReza.Sabdar@Sun.COM     unsigned char *auth_challenge)
12147917SReza.Sabdar@Sun.COM {
12157917SReza.Sabdar@Sun.COM 	char *passwd, *dec_passwd;
12167917SReza.Sabdar@Sun.COM 	unsigned char digest[16];
12177917SReza.Sabdar@Sun.COM 	int rv;
12187917SReza.Sabdar@Sun.COM 
12197917SReza.Sabdar@Sun.COM 	if (strcmp(uname, auth_id) != 0) {
12207917SReza.Sabdar@Sun.COM 		rv = NDMP_NOT_AUTHORIZED_ERR;
12217917SReza.Sabdar@Sun.COM 	} else {
12227917SReza.Sabdar@Sun.COM 		passwd = ndmpd_get_prop(NDMP_CRAM_MD5_PASSWORD);
12237917SReza.Sabdar@Sun.COM 		if (passwd == NULL || *passwd == 0) {
12247917SReza.Sabdar@Sun.COM 			rv = NDMP_NOT_AUTHORIZED_ERR;
12257917SReza.Sabdar@Sun.COM 		} else {
12267917SReza.Sabdar@Sun.COM 			dec_passwd = ndmp_base64_decode(passwd);
12277917SReza.Sabdar@Sun.COM 
12287917SReza.Sabdar@Sun.COM 			if (dec_passwd == NULL || *dec_passwd == 0) {
12297917SReza.Sabdar@Sun.COM 				rv = NDMP_NOT_AUTHORIZED_ERR;
12307917SReza.Sabdar@Sun.COM 			} else {
12317917SReza.Sabdar@Sun.COM 				create_md5_digest(digest, dec_passwd,
12327917SReza.Sabdar@Sun.COM 				    auth_challenge);
12337917SReza.Sabdar@Sun.COM 				if (memcmp(digest, auth_digest,
12347917SReza.Sabdar@Sun.COM 				    sizeof (digest)) != 0) {
12357917SReza.Sabdar@Sun.COM 					rv = NDMP_NOT_AUTHORIZED_ERR;
12367917SReza.Sabdar@Sun.COM 				} else {
12377917SReza.Sabdar@Sun.COM 					rv = NDMP_NO_ERR;
12387917SReza.Sabdar@Sun.COM 				}
12397917SReza.Sabdar@Sun.COM 			}
12407917SReza.Sabdar@Sun.COM 			free(dec_passwd);
12417917SReza.Sabdar@Sun.COM 		}
12427917SReza.Sabdar@Sun.COM 	}
12437917SReza.Sabdar@Sun.COM 
12447917SReza.Sabdar@Sun.COM 	if (rv == NDMP_NO_ERR) {
12457917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Authorization granted.");
12467917SReza.Sabdar@Sun.COM 	} else {
12477917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_ERR, "Authorization denied.");
12487917SReza.Sabdar@Sun.COM 	}
12497917SReza.Sabdar@Sun.COM 
12507917SReza.Sabdar@Sun.COM 	return (rv);
12517917SReza.Sabdar@Sun.COM }
1252