12654012fSReza Sabdar /*
22654012fSReza Sabdar * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
32654012fSReza Sabdar * Use is subject to license terms.
42654012fSReza Sabdar */
52654012fSReza Sabdar
62654012fSReza Sabdar /*
72654012fSReza Sabdar * BSD 3 Clause License
82654012fSReza Sabdar *
92654012fSReza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
102654012fSReza Sabdar *
112654012fSReza Sabdar * Redistribution and use in source and binary forms, with or without
122654012fSReza Sabdar * modification, are permitted provided that the following conditions
132654012fSReza Sabdar * are met:
142654012fSReza Sabdar * - Redistributions of source code must retain the above copyright
152654012fSReza Sabdar * notice, this list of conditions and the following disclaimer.
162654012fSReza Sabdar *
172654012fSReza Sabdar * - Redistributions in binary form must reproduce the above copyright
182654012fSReza Sabdar * notice, this list of conditions and the following disclaimer in
192654012fSReza Sabdar * the documentation and/or other materials provided with the
202654012fSReza Sabdar * distribution.
212654012fSReza Sabdar *
222654012fSReza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA)
232654012fSReza Sabdar * nor the names of its contributors may be used to endorse or promote
242654012fSReza Sabdar * products derived from this software without specific prior written
252654012fSReza Sabdar * permission.
262654012fSReza Sabdar *
272654012fSReza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
282654012fSReza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
292654012fSReza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
302654012fSReza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
312654012fSReza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
322654012fSReza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
332654012fSReza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
342654012fSReza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
352654012fSReza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
362654012fSReza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
372654012fSReza Sabdar * POSSIBILITY OF SUCH DAMAGE.
382654012fSReza Sabdar */
392654012fSReza Sabdar /* Copyright (c) 2007, The Storage Networking Industry Association. */
402654012fSReza Sabdar /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
41*a23888a3SJan Kryl /* Copyright 2014 Nexenta Systems, Inc. All rights reserved. */
422654012fSReza Sabdar
432654012fSReza Sabdar #include <sys/types.h>
442654012fSReza Sabdar #include <errno.h>
452654012fSReza Sabdar #include <pwd.h>
462654012fSReza Sabdar #include <sys/socket.h>
472654012fSReza Sabdar #include <netinet/in.h>
482654012fSReza Sabdar #include <sys/queue.h>
492654012fSReza Sabdar #include <arpa/inet.h>
502654012fSReza Sabdar #include <md5.h>
512654012fSReza Sabdar #include <shadow.h>
522654012fSReza Sabdar #include <crypt.h>
532654012fSReza Sabdar #include <alloca.h>
542654012fSReza Sabdar #include "ndmpd_common.h"
552654012fSReza Sabdar #include "ndmpd.h"
562654012fSReza Sabdar #include <libndmp.h>
572654012fSReza Sabdar #include <ndmpd_door.h>
582654012fSReza Sabdar #include <security/pam_appl.h>
592654012fSReza Sabdar
602654012fSReza Sabdar
612654012fSReza Sabdar static int ndmpd_connect_auth_text(char *uname, char *auth_id,
622654012fSReza Sabdar char *auth_password);
632654012fSReza Sabdar static int ndmpd_connect_auth_md5(char *uname, char *auth_id, char *auth_digest,
642654012fSReza Sabdar unsigned char *auth_challenge);
652654012fSReza Sabdar static struct conn_list *ndmp_connect_list_find(ndmp_connection_t *connection);
662654012fSReza Sabdar static void create_md5_digest(unsigned char *digest, char *passwd,
672654012fSReza Sabdar unsigned char *challenge);
682654012fSReza Sabdar static struct conn_list *ndmp_connect_list_find_id(int id);
692654012fSReza Sabdar
702654012fSReza Sabdar /* routines for connection info */
712654012fSReza Sabdar void ndmp_connect_list_get(ndmp_door_ctx_t *enc_ctx);
722654012fSReza Sabdar static void connection_get(struct conn_list *clp, ndmp_door_ctx_t *enc_ctx);
732654012fSReza Sabdar static void ndmp_connect_get_conn(struct conn_list *clp,
742654012fSReza Sabdar ndmp_door_ctx_t *enc_ctx);
752654012fSReza Sabdar static void ndmp_connect_get_v2(ndmp_connection_t *connection,
762654012fSReza Sabdar ndmp_door_ctx_t *enc_ctx);
772654012fSReza Sabdar static void ndmp_connect_get_scsi_v2(ndmpd_session_t *session,
782654012fSReza Sabdar ndmp_door_ctx_t *enc_ctx);
792654012fSReza Sabdar static void ndmp_connect_get_tape_v2(ndmpd_session_t *session,
802654012fSReza Sabdar ndmp_door_ctx_t *enc_ctx);
812654012fSReza Sabdar static void ndmp_connect_get_mover_v2(ndmpd_session_t *session,
822654012fSReza Sabdar ndmp_door_ctx_t *enc_ctx);
832654012fSReza Sabdar static void ndmp_connect_get_data_v2(ndmpd_session_t *session,
842654012fSReza Sabdar ndmp_door_ctx_t *enc_ctx);
852654012fSReza Sabdar static void ndmp_connect_get_v3(ndmp_connection_t *connection,
862654012fSReza Sabdar ndmp_door_ctx_t *enc_ctx);
872654012fSReza Sabdar static void ndmp_connect_get_mover_v3(ndmpd_session_t *session,
882654012fSReza Sabdar ndmp_door_ctx_t *enc_ctx);
892654012fSReza Sabdar static void ndmp_connect_get_data_v3(ndmpd_session_t *session,
902654012fSReza Sabdar ndmp_door_ctx_t *enc_ctx);
912654012fSReza Sabdar void ndmpd_get_devs(ndmp_door_ctx_t *enc_ctx);
922654012fSReza Sabdar
932654012fSReza Sabdar #ifndef LIST_FOREACH
942654012fSReza Sabdar #define LIST_FOREACH(var, head, field) \
952654012fSReza Sabdar for ((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
962654012fSReza Sabdar #endif /* LIST_FOREACH */
972654012fSReza Sabdar
982654012fSReza Sabdar /*
992654012fSReza Sabdar * List of active connections.
1002654012fSReza Sabdar */
1012654012fSReza Sabdar struct conn_list {
1022654012fSReza Sabdar LIST_ENTRY(conn_list) cl_q;
1032654012fSReza Sabdar int cl_id;
1042654012fSReza Sabdar ndmp_connection_t *cl_conn;
1052654012fSReza Sabdar };
1062654012fSReza Sabdar LIST_HEAD(cl_head, conn_list);
1072654012fSReza Sabdar
1082654012fSReza Sabdar /*
1092654012fSReza Sabdar * Head of the active connections.
1102654012fSReza Sabdar */
1112654012fSReza Sabdar static struct cl_head cl_head;
1122654012fSReza Sabdar
1132654012fSReza Sabdar mutex_t cl_mutex = DEFAULTMUTEX;
1142654012fSReza Sabdar
1152654012fSReza Sabdar
1162654012fSReza Sabdar /*
1172654012fSReza Sabdar * Set this variable to non-zero to print verbose information.
1182654012fSReza Sabdar */
1192654012fSReza Sabdar int ndmp_connect_print_verbose = 0;
1202654012fSReza Sabdar
1212654012fSReza Sabdar
1222654012fSReza Sabdar /*
1232654012fSReza Sabdar * ************************************************************************
1242654012fSReza Sabdar * NDMP V2 HANDLERS
1252654012fSReza Sabdar * ************************************************************************
1262654012fSReza Sabdar */
1272654012fSReza Sabdar
1282654012fSReza Sabdar /*
1292654012fSReza Sabdar * ndmpd_connect_open_v2
1302654012fSReza Sabdar *
1312654012fSReza Sabdar * This handler sets the protocol version to be used on the connection.
1322654012fSReza Sabdar *
1332654012fSReza Sabdar * Parameters:
1342654012fSReza Sabdar * connection (input) - connection handle.
1352654012fSReza Sabdar * body (input) - request message body.
1362654012fSReza Sabdar *
1372654012fSReza Sabdar * Returns:
1382654012fSReza Sabdar * void
1392654012fSReza Sabdar */
1402654012fSReza Sabdar
1412654012fSReza Sabdar void
ndmpd_connect_open_v2(ndmp_connection_t * connection,void * body)1422654012fSReza Sabdar ndmpd_connect_open_v2(ndmp_connection_t *connection, void *body)
1432654012fSReza Sabdar {
1442654012fSReza Sabdar ndmp_connect_open_request *request = (ndmp_connect_open_request *)body;
1452654012fSReza Sabdar ndmp_connect_open_reply reply;
1462654012fSReza Sabdar ndmpd_session_t *session;
1472654012fSReza Sabdar
1482654012fSReza Sabdar reply.error = NDMP_NO_ERR;
1492654012fSReza Sabdar
1502654012fSReza Sabdar if (!(session = (ndmpd_session_t *)ndmp_get_client_data(connection)))
1512654012fSReza Sabdar return;
1522654012fSReza Sabdar
1532654012fSReza Sabdar if (session->ns_mover.md_state != NDMP_MOVER_STATE_IDLE ||
1542654012fSReza Sabdar session->ns_data.dd_state != NDMP_DATA_STATE_IDLE)
1552654012fSReza Sabdar reply.error = NDMP_ILLEGAL_STATE_ERR;
1562654012fSReza Sabdar else if (request->protocol_version > ndmp_ver)
1572654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR;
1582654012fSReza Sabdar
1592654012fSReza Sabdar ndmp_send_reply(connection, (void *) &reply,
1602654012fSReza Sabdar "sending connect_open reply");
1612654012fSReza Sabdar
1622654012fSReza Sabdar /*
1632654012fSReza Sabdar * Set the protocol version.
1642654012fSReza Sabdar * Must wait until after sending the reply since the reply
1652654012fSReza Sabdar * must be sent using the same protocol version that was used
1662654012fSReza Sabdar * to process the request.
1672654012fSReza Sabdar */
1682654012fSReza Sabdar if (reply.error == NDMP_NO_ERR) {
1692654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "set ver to: %d",
1702654012fSReza Sabdar request->protocol_version);
1712654012fSReza Sabdar ndmp_set_version(connection, request->protocol_version);
1722654012fSReza Sabdar session->ns_protocol_version = request->protocol_version;
1732654012fSReza Sabdar }
1742654012fSReza Sabdar }
1752654012fSReza Sabdar
1762654012fSReza Sabdar
1772654012fSReza Sabdar /*
1782654012fSReza Sabdar * ndmpd_connect_client_auth_v2
1792654012fSReza Sabdar *
1802654012fSReza Sabdar * This handler authorizes the NDMP connection.
1812654012fSReza Sabdar *
1822654012fSReza Sabdar * Parameters:
1832654012fSReza Sabdar * connection (input) - connection handle.
1842654012fSReza Sabdar * msginfo (input) - request message.
1852654012fSReza Sabdar *
1862654012fSReza Sabdar * Returns:
1872654012fSReza Sabdar * void
1882654012fSReza Sabdar */
1892654012fSReza Sabdar void
ndmpd_connect_client_auth_v2(ndmp_connection_t * connection,void * body)1902654012fSReza Sabdar ndmpd_connect_client_auth_v2(ndmp_connection_t *connection, void *body)
1912654012fSReza Sabdar {
1922654012fSReza Sabdar ndmp_connect_client_auth_request *request;
1932654012fSReza Sabdar ndmp_connect_client_auth_reply reply;
1942654012fSReza Sabdar ndmp_auth_text *auth;
1952654012fSReza Sabdar ndmpd_session_t *session;
1962654012fSReza Sabdar ndmp_auth_md5 *md5;
1972654012fSReza Sabdar unsigned char md5_digest[16];
1982654012fSReza Sabdar char *passwd, *dec_passwd;
1992654012fSReza Sabdar char *uname;
2002654012fSReza Sabdar
2012654012fSReza Sabdar request = (ndmp_connect_client_auth_request *)body;
2022654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "auth_type:%s",
2032654012fSReza Sabdar request->auth_data.auth_type == NDMP_AUTH_NONE ? "None" :
2042654012fSReza Sabdar (request->auth_data.auth_type == NDMP_AUTH_TEXT ? "Text" :
2052654012fSReza Sabdar (request->auth_data.auth_type == NDMP_AUTH_MD5 ? "MD5" :
2062654012fSReza Sabdar "Invalid")));
2072654012fSReza Sabdar
2082654012fSReza Sabdar reply.error = NDMP_NO_ERR;
2092654012fSReza Sabdar
2102654012fSReza Sabdar switch (request->auth_data.auth_type) {
2112654012fSReza Sabdar case NDMP_AUTH_NONE:
2122654012fSReza Sabdar /*
2132654012fSReza Sabdar * Allow no authorization for development.
2142654012fSReza Sabdar * Comment the following for a non-secure production server.
2152654012fSReza Sabdar */
2162654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Authorization denied.");
2172654012fSReza Sabdar NDMP_LOG(LOG_ERR,
2182654012fSReza Sabdar "Authorization type should be md5 or cleartext.");
2192654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR;
2202654012fSReza Sabdar ndmpd_audit_connect(connection, EINVAL);
2212654012fSReza Sabdar break;
2222654012fSReza Sabdar
2232654012fSReza Sabdar case NDMP_AUTH_TEXT:
2242654012fSReza Sabdar /* Check authorization. */
2252654012fSReza Sabdar if ((uname = ndmpd_get_prop(NDMP_CLEARTEXT_USERNAME)) == NULL ||
2262654012fSReza Sabdar *uname == 0) {
2272654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Authorization denied.");
2282654012fSReza Sabdar NDMP_LOG(LOG_ERR, "User name is not set at server.");
2292654012fSReza Sabdar reply.error = NDMP_NOT_AUTHORIZED_ERR;
2302654012fSReza Sabdar ndmp_set_authorized(connection, FALSE);
2312654012fSReza Sabdar ndmp_send_reply(connection, (void *) &reply,
2322654012fSReza Sabdar "sending ndmp_connect_client_auth reply");
2332654012fSReza Sabdar ndmpd_audit_connect(connection,
2342654012fSReza Sabdar ADT_FAIL_PAM + PAM_AUTH_ERR);
2352654012fSReza Sabdar return;
2362654012fSReza Sabdar }
2372654012fSReza Sabdar auth = &request->auth_data.ndmp_auth_data_u.auth_text;
2382654012fSReza Sabdar if (strcmp(uname, auth->user) != 0) {
2392654012fSReza Sabdar NDMP_LOG(LOG_ERR,
2402654012fSReza Sabdar "Authorization denied. Not a valid user.");
2412654012fSReza Sabdar reply.error = NDMP_NOT_AUTHORIZED_ERR;
2422654012fSReza Sabdar ndmpd_audit_connect(connection,
2432654012fSReza Sabdar ADT_FAIL_PAM + PAM_AUTH_ERR);
2442654012fSReza Sabdar break;
2452654012fSReza Sabdar }
2462654012fSReza Sabdar passwd = ndmpd_get_prop(NDMP_CLEARTEXT_PASSWORD);
2472654012fSReza Sabdar if (!passwd || !*passwd) {
2482654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Authorization denied.");
2492654012fSReza Sabdar NDMP_LOG(LOG_ERR,
2502654012fSReza Sabdar "Cleartext password is not set at server.");
2512654012fSReza Sabdar reply.error = NDMP_NOT_AUTHORIZED_ERR;
2522654012fSReza Sabdar ndmp_set_authorized(connection, FALSE);
2532654012fSReza Sabdar ndmp_send_reply(connection, (void *) &reply,
2542654012fSReza Sabdar "sending ndmp_connect_client_auth reply");
2552654012fSReza Sabdar ndmpd_audit_connect(connection,
2562654012fSReza Sabdar ADT_FAIL_PAM + PAM_AUTH_ERR);
2572654012fSReza Sabdar return;
2582654012fSReza Sabdar } else {
2592654012fSReza Sabdar dec_passwd = ndmp_base64_decode(passwd);
2602654012fSReza Sabdar }
2612654012fSReza Sabdar if (!dec_passwd || !*dec_passwd ||
2622654012fSReza Sabdar strcmp(auth->password, dec_passwd) != 0) {
2632654012fSReza Sabdar NDMP_LOG(LOG_ERR,
2642654012fSReza Sabdar "Authorization denied. Invalid password.");
2652654012fSReza Sabdar reply.error = NDMP_NOT_AUTHORIZED_ERR;
2662654012fSReza Sabdar } else {
2672654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Authorization granted.");
2682654012fSReza Sabdar }
2692654012fSReza Sabdar ndmpd_audit_connect(connection, reply.error ?
2702654012fSReza Sabdar ADT_FAIL_PAM + PAM_AUTH_ERR : 0);
2712654012fSReza Sabdar
2722654012fSReza Sabdar free(dec_passwd);
2732654012fSReza Sabdar break;
2742654012fSReza Sabdar
2752654012fSReza Sabdar case NDMP_AUTH_MD5:
2762654012fSReza Sabdar /* Check authorization. */
2772654012fSReza Sabdar if ((uname = ndmpd_get_prop(NDMP_CRAM_MD5_USERNAME)) == NULL ||
2782654012fSReza Sabdar *uname == 0) {
2792654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Authorization denied.");
2802654012fSReza Sabdar NDMP_LOG(LOG_ERR, "User name is not set at server.");
2812654012fSReza Sabdar reply.error = NDMP_NOT_AUTHORIZED_ERR;
2822654012fSReza Sabdar ndmp_set_authorized(connection, FALSE);
2832654012fSReza Sabdar ndmp_send_reply(connection, (void *) &reply,
2842654012fSReza Sabdar "sending ndmp_connect_client_auth reply");
2852654012fSReza Sabdar ndmpd_audit_connect(connection,
2862654012fSReza Sabdar ADT_FAIL_PAM + PAM_AUTH_ERR);
2872654012fSReza Sabdar return;
2882654012fSReza Sabdar }
2892654012fSReza Sabdar md5 = &request->auth_data.ndmp_auth_data_u.auth_md5;
2902654012fSReza Sabdar passwd = ndmpd_get_prop(NDMP_CRAM_MD5_PASSWORD);
2912654012fSReza Sabdar if (!passwd || !*passwd) {
2922654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Authorization denied.");
2932654012fSReza Sabdar NDMP_LOG(LOG_ERR, "MD5 password is not set at server.");
2942654012fSReza Sabdar reply.error = NDMP_NOT_AUTHORIZED_ERR;
2952654012fSReza Sabdar ndmp_set_authorized(connection, FALSE);
2962654012fSReza Sabdar ndmp_send_reply(connection, (void *) &reply,
2972654012fSReza Sabdar "sending ndmp_connect_client_auth reply");
2982654012fSReza Sabdar ndmpd_audit_connect(connection,
2992654012fSReza Sabdar ADT_FAIL_PAM + PAM_AUTH_ERR);
3002654012fSReza Sabdar return;
3012654012fSReza Sabdar } else {
3022654012fSReza Sabdar dec_passwd = ndmp_base64_decode(passwd);
3032654012fSReza Sabdar }
3042654012fSReza Sabdar session = ndmp_get_client_data(connection);
3052654012fSReza Sabdar create_md5_digest(md5_digest, dec_passwd,
3062654012fSReza Sabdar session->ns_challenge);
3072654012fSReza Sabdar
3082654012fSReza Sabdar if (strcmp(uname, md5->user) != 0) {
3092654012fSReza Sabdar NDMP_LOG(LOG_ERR,
3102654012fSReza Sabdar "Authorization denied. Not a valid user.");
3112654012fSReza Sabdar reply.error = NDMP_NOT_AUTHORIZED_ERR;
3122654012fSReza Sabdar } else if (memcmp(md5_digest, md5->auth_digest,
3132654012fSReza Sabdar sizeof (md5_digest)) != 0) {
3142654012fSReza Sabdar NDMP_LOG(LOG_ERR,
3152654012fSReza Sabdar "Authorization denied. Invalid password.");
3162654012fSReza Sabdar reply.error = NDMP_NOT_AUTHORIZED_ERR;
3172654012fSReza Sabdar } else {
3182654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Authorization granted");
3192654012fSReza Sabdar }
3202654012fSReza Sabdar ndmpd_audit_connect(connection, reply.error ?
3212654012fSReza Sabdar ADT_FAIL_PAM + PAM_AUTH_ERR : 0);
3222654012fSReza Sabdar
3232654012fSReza Sabdar free(dec_passwd);
3242654012fSReza Sabdar break;
3252654012fSReza Sabdar
3262654012fSReza Sabdar default:
3272654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR;
3282654012fSReza Sabdar }
3292654012fSReza Sabdar
3302654012fSReza Sabdar if (reply.error == NDMP_NO_ERR)
3312654012fSReza Sabdar ndmp_set_authorized(connection, TRUE);
3322654012fSReza Sabdar else
3332654012fSReza Sabdar ndmp_set_authorized(connection, FALSE);
3342654012fSReza Sabdar
3352654012fSReza Sabdar ndmp_send_reply(connection, (void *) &reply,
3362654012fSReza Sabdar "sending ndmp_connect_client_auth reply");
3372654012fSReza Sabdar }
3382654012fSReza Sabdar
3392654012fSReza Sabdar
3402654012fSReza Sabdar /*
3412654012fSReza Sabdar * ndmpd_connect_server_auth_v2
3422654012fSReza Sabdar *
3432654012fSReza Sabdar * This handler authenticates the server to the client.
3442654012fSReza Sabdar *
3452654012fSReza Sabdar * Parameters:
3462654012fSReza Sabdar * connection (input) - connection handle.
3472654012fSReza Sabdar * msginfo (input) - request message.
3482654012fSReza Sabdar *
3492654012fSReza Sabdar * Returns:
3502654012fSReza Sabdar * void
3512654012fSReza Sabdar */
3522654012fSReza Sabdar void
ndmpd_connect_server_auth_v2(ndmp_connection_t * connection,void * body)3532654012fSReza Sabdar ndmpd_connect_server_auth_v2(ndmp_connection_t *connection, void *body)
3542654012fSReza Sabdar {
3552654012fSReza Sabdar ndmp_connect_server_auth_request *request;
3562654012fSReza Sabdar ndmp_connect_server_auth_reply reply;
3572654012fSReza Sabdar
3582654012fSReza Sabdar request = (ndmp_connect_server_auth_request *)body;
3592654012fSReza Sabdar
3602654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "auth_type:%s",
3612654012fSReza Sabdar request->client_attr.auth_type == NDMP_AUTH_NONE ? "None" :
3622654012fSReza Sabdar (request->client_attr.auth_type == NDMP_AUTH_TEXT ? "Text" :
3632654012fSReza Sabdar (request->client_attr.auth_type == NDMP_AUTH_MD5 ? "MD5" :
3642654012fSReza Sabdar "Invalid")));
3652654012fSReza Sabdar
3662654012fSReza Sabdar reply.error = NDMP_NO_ERR;
3672654012fSReza Sabdar reply.auth_result.auth_type = request->client_attr.auth_type;
3682654012fSReza Sabdar switch (request->client_attr.auth_type) {
3692654012fSReza Sabdar case NDMP_AUTH_NONE:
3702654012fSReza Sabdar break;
3712654012fSReza Sabdar
3722654012fSReza Sabdar case NDMP_AUTH_TEXT:
3732654012fSReza Sabdar reply.auth_result.ndmp_auth_data_u.auth_text.user = "ndmpd";
3742654012fSReza Sabdar reply.auth_result.ndmp_auth_data_u.auth_text.password =
3752654012fSReza Sabdar "ndmpsdk";
3762654012fSReza Sabdar break;
3772654012fSReza Sabdar
3782654012fSReza Sabdar case NDMP_AUTH_MD5:
3792654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR;
3802654012fSReza Sabdar break;
3812654012fSReza Sabdar
3822654012fSReza Sabdar default:
3832654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR;
3842654012fSReza Sabdar }
3852654012fSReza Sabdar
3862654012fSReza Sabdar ndmp_send_reply(connection, (void *) &reply,
3872654012fSReza Sabdar "sending ndmp_connect_auth reply");
3882654012fSReza Sabdar }
3892654012fSReza Sabdar
3902654012fSReza Sabdar
3912654012fSReza Sabdar /*
3922654012fSReza Sabdar * ndmpd_connect_close_v2
3932654012fSReza Sabdar *
3942654012fSReza Sabdar * This handler closes the connection.
3952654012fSReza Sabdar *
3962654012fSReza Sabdar * Parameters:
3972654012fSReza Sabdar * connection (input) - connection handle.
3982654012fSReza Sabdar * msginfo (input) - request message.
3992654012fSReza Sabdar *
4002654012fSReza Sabdar * Returns:
4012654012fSReza Sabdar * void
4022654012fSReza Sabdar */
4032654012fSReza Sabdar /*ARGSUSED*/
4042654012fSReza Sabdar void
ndmpd_connect_close_v2(ndmp_connection_t * connection,void * body)4052654012fSReza Sabdar ndmpd_connect_close_v2(ndmp_connection_t *connection, void *body)
4062654012fSReza Sabdar {
4072654012fSReza Sabdar ndmpd_session_t *session;
4082654012fSReza Sabdar
4092654012fSReza Sabdar if ((session = (ndmpd_session_t *)ndmp_get_client_data(connection))) {
4102654012fSReza Sabdar (void) ndmp_close(connection);
4112654012fSReza Sabdar session->ns_eof = TRUE;
4122654012fSReza Sabdar }
4132654012fSReza Sabdar }
4142654012fSReza Sabdar
4152654012fSReza Sabdar /*
4162654012fSReza Sabdar * ************************************************************************
4172654012fSReza Sabdar * NDMP V3 HANDLERS
4182654012fSReza Sabdar * ************************************************************************
4192654012fSReza Sabdar */
4202654012fSReza Sabdar
4212654012fSReza Sabdar /*
4222654012fSReza Sabdar * ndmpd_connect_client_auth_v3
4232654012fSReza Sabdar *
4242654012fSReza Sabdar * This handler authorizes the NDMP connection.
4252654012fSReza Sabdar *
4262654012fSReza Sabdar * Parameters:
4272654012fSReza Sabdar * connection (input) - connection handle.
4282654012fSReza Sabdar * msginfo (input) - request message.
4292654012fSReza Sabdar *
4302654012fSReza Sabdar * Returns:
4312654012fSReza Sabdar * void
4322654012fSReza Sabdar */
4332654012fSReza Sabdar void
ndmpd_connect_client_auth_v3(ndmp_connection_t * connection,void * body)4342654012fSReza Sabdar ndmpd_connect_client_auth_v3(ndmp_connection_t *connection, void *body)
4352654012fSReza Sabdar {
4362654012fSReza Sabdar ndmp_connect_client_auth_request_v3 *request;
4372654012fSReza Sabdar ndmp_connect_client_auth_reply_v3 reply;
4382654012fSReza Sabdar ndmp_auth_text_v3 *auth;
4392654012fSReza Sabdar ndmpd_session_t *session;
4402654012fSReza Sabdar ndmp_auth_md5_v3 *md5;
4412654012fSReza Sabdar struct in_addr addr;
4422654012fSReza Sabdar char *uname;
4432654012fSReza Sabdar char *type;
4442654012fSReza Sabdar
4452654012fSReza Sabdar request = (ndmp_connect_client_auth_request_v3 *)body;
4462654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "auth_type %s",
4472654012fSReza Sabdar request->auth_data.auth_type == NDMP_AUTH_NONE ? "None" :
4482654012fSReza Sabdar request->auth_data.auth_type == NDMP_AUTH_TEXT ? "Text" :
4492654012fSReza Sabdar request->auth_data.auth_type == NDMP_AUTH_MD5 ? "MD5" : "Invalid");
4502654012fSReza Sabdar
4512654012fSReza Sabdar reply.error = NDMP_NO_ERR;
4522654012fSReza Sabdar
4532654012fSReza Sabdar switch (request->auth_data.auth_type) {
4542654012fSReza Sabdar case NDMP_AUTH_NONE:
4552654012fSReza Sabdar type = "none";
4562654012fSReza Sabdar reply.error = NDMP_NOT_SUPPORTED_ERR;
4572654012fSReza Sabdar ndmpd_audit_connect(connection, ENOTSUP);
4582654012fSReza Sabdar break;
4592654012fSReza Sabdar
4602654012fSReza Sabdar case NDMP_AUTH_TEXT:
4612654012fSReza Sabdar /* Check authorization. */
4622654012fSReza Sabdar if ((uname = ndmpd_get_prop(NDMP_CLEARTEXT_USERNAME)) == NULL ||
4632654012fSReza Sabdar *uname == 0) {
4642654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Authorization denied.");
4652654012fSReza Sabdar NDMP_LOG(LOG_ERR, "User name is not set at server.");
4662654012fSReza Sabdar reply.error = NDMP_NOT_AUTHORIZED_ERR;
4672654012fSReza Sabdar ndmp_set_authorized(connection, FALSE);
4682654012fSReza Sabdar ndmp_send_reply(connection, (void *) &reply,
4692654012fSReza Sabdar "sending ndmp_connect_client_auth reply");
4702654012fSReza Sabdar ndmpd_audit_connect(connection,
4712654012fSReza Sabdar ADT_FAIL_PAM + PAM_AUTH_ERR);
4722654012fSReza Sabdar return;
4732654012fSReza Sabdar }
4742654012fSReza Sabdar type = "text";
4752654012fSReza Sabdar auth = &request->auth_data.ndmp_auth_data_v3_u.auth_text;
4762654012fSReza Sabdar reply.error = ndmpd_connect_auth_text(uname, auth->auth_id,
4772654012fSReza Sabdar auth->auth_password);
4782654012fSReza Sabdar ndmpd_audit_connect(connection, reply.error ?
4792654012fSReza Sabdar ADT_FAIL_PAM + PAM_AUTH_ERR : 0);
4802654012fSReza Sabdar break;
4812654012fSReza Sabdar
4822654012fSReza Sabdar case NDMP_AUTH_MD5:
4832654012fSReza Sabdar /* Check authorization. */
4842654012fSReza Sabdar if ((uname = ndmpd_get_prop(NDMP_CRAM_MD5_USERNAME)) == NULL ||
4852654012fSReza Sabdar *uname == 0) {
4862654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Authorization denied.");
4872654012fSReza Sabdar NDMP_LOG(LOG_ERR, "User name is not set at server.");
4882654012fSReza Sabdar reply.error = NDMP_NOT_AUTHORIZED_ERR;
4892654012fSReza Sabdar ndmp_set_authorized(connection, FALSE);
4902654012fSReza Sabdar ndmp_send_reply(connection, (void *) &reply,
4912654012fSReza Sabdar "sending ndmp_connect_client_auth reply");
4922654012fSReza Sabdar ndmpd_audit_connect(connection,
4932654012fSReza Sabdar ADT_FAIL_PAM + PAM_AUTH_ERR);
4942654012fSReza Sabdar return;
4952654012fSReza Sabdar }
4962654012fSReza Sabdar type = "md5";
4972654012fSReza Sabdar session = ndmp_get_client_data(connection);
4982654012fSReza Sabdar md5 = &request->auth_data.ndmp_auth_data_v3_u.auth_md5;
4992654012fSReza Sabdar reply.error = ndmpd_connect_auth_md5(uname, md5->auth_id,
5002654012fSReza Sabdar md5->auth_digest, session->ns_challenge);
5012654012fSReza Sabdar ndmpd_audit_connect(connection, reply.error ?
5022654012fSReza Sabdar ADT_FAIL_PAM + PAM_AUTH_ERR : 0);
5032654012fSReza Sabdar break;
5042654012fSReza Sabdar
5052654012fSReza Sabdar default:
5062654012fSReza Sabdar type = "unknown";
5072654012fSReza Sabdar reply.error = NDMP_ILLEGAL_ARGS_ERR;
5082654012fSReza Sabdar ndmpd_audit_connect(connection, EINVAL);
5092654012fSReza Sabdar }
5102654012fSReza Sabdar
5112654012fSReza Sabdar if (reply.error == NDMP_NO_ERR) {
5122654012fSReza Sabdar ndmp_set_authorized(connection, TRUE);
5132654012fSReza Sabdar } else {
5142654012fSReza Sabdar ndmp_set_authorized(connection, FALSE);
5152654012fSReza Sabdar if (tcp_get_peer(connection->conn_sock, &addr.s_addr,
5162654012fSReza Sabdar NULL) != -1) {
5172654012fSReza Sabdar NDMP_LOG(LOG_ERR,
5182654012fSReza Sabdar "Authorization(%s) denied for %s.", type,
5192654012fSReza Sabdar inet_ntoa(IN_ADDR(addr)));
5202654012fSReza Sabdar }
5212654012fSReza Sabdar }
5222654012fSReza Sabdar
5232654012fSReza Sabdar ndmp_send_reply(connection, (void *) &reply,
5242654012fSReza Sabdar "sending ndmp_connect_auth reply");
5252654012fSReza Sabdar }
5262654012fSReza Sabdar
5272654012fSReza Sabdar
5282654012fSReza Sabdar /*
5292654012fSReza Sabdar * ndmpd_connect_close_v3
5302654012fSReza Sabdar *
5312654012fSReza Sabdar * Close the connection to the DMA.
5322654012fSReza Sabdar * Send the SHUTDOWN message before closing the socket connection to the DMA.
5332654012fSReza Sabdar *
5342654012fSReza Sabdar * Parameters:
5352654012fSReza Sabdar * connection (input) - connection handle.
5362654012fSReza Sabdar * msginfo (input) - request message.
5372654012fSReza Sabdar *
5382654012fSReza Sabdar * Returns:
5392654012fSReza Sabdar * void
5402654012fSReza Sabdar */
5412654012fSReza Sabdar /*ARGSUSED*/
5422654012fSReza Sabdar void
ndmpd_connect_close_v3(ndmp_connection_t * connection,void * body)5432654012fSReza Sabdar ndmpd_connect_close_v3(ndmp_connection_t *connection, void *body)
5442654012fSReza Sabdar {
5452654012fSReza Sabdar ndmpd_session_t *session;
546*a23888a3SJan Kryl ndmp_lbr_params_t *nlp;
5472654012fSReza Sabdar ndmp_notify_connected_request req;
5482654012fSReza Sabdar
5492654012fSReza Sabdar if (!(session = (ndmpd_session_t *)ndmp_get_client_data(connection)))
5502654012fSReza Sabdar return;
551*a23888a3SJan Kryl if ((nlp = ndmp_get_nlp(session)) == NULL)
552*a23888a3SJan Kryl return;
5532654012fSReza Sabdar
5542654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ver: %u",
5552654012fSReza Sabdar session->ns_protocol_version);
5562654012fSReza Sabdar
5572654012fSReza Sabdar /* Send the SHUTDOWN message before closing the connection. */
5582654012fSReza Sabdar req.reason = NDMP_SHUTDOWN;
5592654012fSReza Sabdar req.protocol_version = session->ns_protocol_version;
5602654012fSReza Sabdar req.text_reason = "Connection closed by server.";
5612654012fSReza Sabdar
5622654012fSReza Sabdar if (ndmp_send_request(connection, NDMP_NOTIFY_CONNECTION_STATUS,
5632654012fSReza Sabdar NDMP_NO_ERR, (void *) &req, 0) < 0) {
5642654012fSReza Sabdar NDMP_LOG(LOG_NOTICE, "Sending connection shutdown notify");
5652654012fSReza Sabdar return;
5662654012fSReza Sabdar }
5672654012fSReza Sabdar
568*a23888a3SJan Kryl (void) mutex_lock(&nlp->nlp_mtx);
5692654012fSReza Sabdar ndmp_close(connection);
5702654012fSReza Sabdar session->ns_eof = TRUE;
571*a23888a3SJan Kryl (void) cond_broadcast(&nlp->nlp_cv);
572*a23888a3SJan Kryl (void) mutex_unlock(&nlp->nlp_mtx);
5732654012fSReza Sabdar }
5742654012fSReza Sabdar
5752654012fSReza Sabdar /*
5762654012fSReza Sabdar * ************************************************************************
5772654012fSReza Sabdar * NDMP V4 HANDLERS
5782654012fSReza Sabdar * ************************************************************************
5792654012fSReza Sabdar */
5802654012fSReza Sabdar
5812654012fSReza Sabdar /*
5822654012fSReza Sabdar * ************************************************************************
5832654012fSReza Sabdar * LOCALS
5842654012fSReza Sabdar * ************************************************************************
5852654012fSReza Sabdar */
5862654012fSReza Sabdar
5872654012fSReza Sabdar /*
5882654012fSReza Sabdar * create_md5_digest
5892654012fSReza Sabdar *
5902654012fSReza Sabdar * This function uses the MD5 message-digest algorithm described
5912654012fSReza Sabdar * in RFC1321 to authenticate the client using a shared secret (password).
5922654012fSReza Sabdar * The message used to compute the MD5 digest is a concatenation of password,
5932654012fSReza Sabdar * null padding, the 64 byte fixed length challenge and a repeat of the
5942654012fSReza Sabdar * password. The length of the null padding is chosen to result in a 128 byte
5952654012fSReza Sabdar * fixed length message. The lengh of the padding can be computed as
5962654012fSReza Sabdar * 64 - 2*(length of the password). The client digest is computed using the
5972654012fSReza Sabdar * server challenge from the NDMP_CONFIG_GET_AUTH_ATTR reply.
5982654012fSReza Sabdar *
5992654012fSReza Sabdar * Parameters:
6002654012fSReza Sabdar * digest (output) - 16 bytes MD5 digest
6012654012fSReza Sabdar * passwd (input) - user password
6022654012fSReza Sabdar * challenge (input) - 64 bytes server challenge
6032654012fSReza Sabdar *
6042654012fSReza Sabdar * Returns:
6052654012fSReza Sabdar * void
6062654012fSReza Sabdar */
6072654012fSReza Sabdar static void
create_md5_digest(unsigned char * digest,char * passwd,unsigned char * challenge)6082654012fSReza Sabdar create_md5_digest(unsigned char *digest, char *passwd, unsigned char *challenge)
6092654012fSReza Sabdar {
6102654012fSReza Sabdar char buf[130];
6112654012fSReza Sabdar char *p = &buf[0];
6122654012fSReza Sabdar int len, i;
6132654012fSReza Sabdar MD5_CTX md;
6142654012fSReza Sabdar char *pwd;
6152654012fSReza Sabdar
6162654012fSReza Sabdar *p = 0;
6172654012fSReza Sabdar pwd = passwd;
6182654012fSReza Sabdar if ((len = strlen(pwd)) > MD5_PASS_LIMIT)
6192654012fSReza Sabdar len = MD5_PASS_LIMIT;
6202654012fSReza Sabdar (void) memcpy(p, pwd, len);
6212654012fSReza Sabdar p += len;
6222654012fSReza Sabdar
6232654012fSReza Sabdar for (i = 0; i < MD5_CHALLENGE_SIZE - 2 * len; i++)
6242654012fSReza Sabdar *p++ = 0;
6252654012fSReza Sabdar
6262654012fSReza Sabdar (void) memcpy(p, challenge, MD5_CHALLENGE_SIZE);
6272654012fSReza Sabdar p += MD5_CHALLENGE_SIZE;
6282654012fSReza Sabdar (void) strlcpy(p, pwd, MD5_PASS_LIMIT);
6292654012fSReza Sabdar
6302654012fSReza Sabdar MD5Init(&md);
6312654012fSReza Sabdar MD5Update(&md, buf, 128);
6322654012fSReza Sabdar MD5Final(digest, &md);
6332654012fSReza Sabdar }
6342654012fSReza Sabdar
6352654012fSReza Sabdar /*
6362654012fSReza Sabdar * ndmp_connect_list_find
6372654012fSReza Sabdar *
6382654012fSReza Sabdar * Find the element in the active connection list.
6392654012fSReza Sabdar *
6402654012fSReza Sabdar * Parameters:
6412654012fSReza Sabdar * connection (input) - connection handler.
6422654012fSReza Sabdar *
6432654012fSReza Sabdar * Returns:
6442654012fSReza Sabdar * NULL - error
6452654012fSReza Sabdar * connection list element pointer
6462654012fSReza Sabdar */
6472654012fSReza Sabdar static struct conn_list *
ndmp_connect_list_find(ndmp_connection_t * connection)6482654012fSReza Sabdar ndmp_connect_list_find(ndmp_connection_t *connection)
6492654012fSReza Sabdar {
6502654012fSReza Sabdar struct conn_list *clp;
6512654012fSReza Sabdar
6522654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "connection: 0x%p",
6532654012fSReza Sabdar connection);
6542654012fSReza Sabdar
6552654012fSReza Sabdar LIST_FOREACH(clp, &cl_head, cl_q) {
6562654012fSReza Sabdar if (clp->cl_conn == connection) {
6572654012fSReza Sabdar (void) mutex_unlock(&cl_mutex);
6582654012fSReza Sabdar return (clp);
6592654012fSReza Sabdar }
6602654012fSReza Sabdar }
6612654012fSReza Sabdar return (NULL);
6622654012fSReza Sabdar }
6632654012fSReza Sabdar
6642654012fSReza Sabdar /*
6652654012fSReza Sabdar * ndmpconnect_list_add
6662654012fSReza Sabdar *
6672654012fSReza Sabdar * Add the new connection to the list of the active connections.
6682654012fSReza Sabdar *
6692654012fSReza Sabdar * Parameters:
6702654012fSReza Sabdar * connection (input) - connection handler.
6712654012fSReza Sabdar * id (input/output) - pointer to connection id.
6722654012fSReza Sabdar *
6732654012fSReza Sabdar * Returns:
6742654012fSReza Sabdar * 0 - success
6752654012fSReza Sabdar * -1 - error
6762654012fSReza Sabdar */
6772654012fSReza Sabdar int
ndmp_connect_list_add(ndmp_connection_t * connection,int * id)6782654012fSReza Sabdar ndmp_connect_list_add(ndmp_connection_t *connection, int *id)
6792654012fSReza Sabdar {
6802654012fSReza Sabdar struct conn_list *clp;
6812654012fSReza Sabdar
6822654012fSReza Sabdar if (connection == NULL) {
6832654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument");
6842654012fSReza Sabdar return (-1);
6852654012fSReza Sabdar }
6862654012fSReza Sabdar
6872654012fSReza Sabdar if ((clp = ndmp_malloc(sizeof (struct conn_list))) == NULL)
6882654012fSReza Sabdar return (-1);
6892654012fSReza Sabdar
6902654012fSReza Sabdar clp->cl_conn = connection;
6912654012fSReza Sabdar clp->cl_id = *id;
6922654012fSReza Sabdar
6932654012fSReza Sabdar (void) mutex_lock(&cl_mutex);
6942654012fSReza Sabdar LIST_INSERT_HEAD(&cl_head, clp, cl_q);
6952654012fSReza Sabdar (*id)++;
6962654012fSReza Sabdar (void) mutex_unlock(&cl_mutex);
6972654012fSReza Sabdar
6982654012fSReza Sabdar return (0);
6992654012fSReza Sabdar }
7002654012fSReza Sabdar
7012654012fSReza Sabdar /*
7022654012fSReza Sabdar * ndmp_connect_list_del
7032654012fSReza Sabdar *
7042654012fSReza Sabdar * Delete the specified connection from the list.
7052654012fSReza Sabdar *
7062654012fSReza Sabdar * Parameters:
7072654012fSReza Sabdar * connection (input) - connection handler.
7082654012fSReza Sabdar *
7092654012fSReza Sabdar * Returns:
7102654012fSReza Sabdar * 0 - success
7112654012fSReza Sabdar * -1 - error
7122654012fSReza Sabdar */
7132654012fSReza Sabdar int
ndmp_connect_list_del(ndmp_connection_t * connection)7142654012fSReza Sabdar ndmp_connect_list_del(ndmp_connection_t *connection)
7152654012fSReza Sabdar {
7162654012fSReza Sabdar struct conn_list *clp;
7172654012fSReza Sabdar
7182654012fSReza Sabdar (void) mutex_lock(&cl_mutex);
7192654012fSReza Sabdar if (!(clp = ndmp_connect_list_find(connection))) {
7202654012fSReza Sabdar (void) mutex_unlock(&cl_mutex);
7212654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "connection not found");
7222654012fSReza Sabdar return (-1);
7232654012fSReza Sabdar }
7242654012fSReza Sabdar
7252654012fSReza Sabdar LIST_REMOVE(clp, cl_q);
7262654012fSReza Sabdar (void) mutex_unlock(&cl_mutex);
7272654012fSReza Sabdar free(clp);
7282654012fSReza Sabdar
7292654012fSReza Sabdar return (0);
7302654012fSReza Sabdar }
7312654012fSReza Sabdar
7322654012fSReza Sabdar
7332654012fSReza Sabdar /*
7342654012fSReza Sabdar * ndmpconnect_list_find_id
7352654012fSReza Sabdar *
7362654012fSReza Sabdar * Find the element specified by its id in the list of active connections.
7372654012fSReza Sabdar *
7382654012fSReza Sabdar * Parameters:
7392654012fSReza Sabdar * id (input) - connection id.
7402654012fSReza Sabdar *
7412654012fSReza Sabdar * Returns:
7422654012fSReza Sabdar * NULL - error
7432654012fSReza Sabdar * connection list element pointer
7442654012fSReza Sabdar */
7452654012fSReza Sabdar static struct conn_list *
ndmp_connect_list_find_id(int id)7462654012fSReza Sabdar ndmp_connect_list_find_id(int id)
7472654012fSReza Sabdar {
7482654012fSReza Sabdar struct conn_list *clp;
7492654012fSReza Sabdar
7502654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "id: %d", id);
7512654012fSReza Sabdar
7522654012fSReza Sabdar (void) mutex_lock(&cl_mutex);
7532654012fSReza Sabdar LIST_FOREACH(clp, &cl_head, cl_q) {
7542654012fSReza Sabdar if (clp->cl_id == id) {
7552654012fSReza Sabdar (void) mutex_unlock(&cl_mutex);
7562654012fSReza Sabdar return (clp);
7572654012fSReza Sabdar }
7582654012fSReza Sabdar }
7592654012fSReza Sabdar
7602654012fSReza Sabdar (void) mutex_unlock(&cl_mutex);
7612654012fSReza Sabdar return (NULL);
7622654012fSReza Sabdar }
7632654012fSReza Sabdar
7642654012fSReza Sabdar /*
7652654012fSReza Sabdar * Get common fields of the active connection.
7662654012fSReza Sabdar */
7672654012fSReza Sabdar static void
ndmp_connect_get_conn(struct conn_list * clp,ndmp_door_ctx_t * enc_ctx)7682654012fSReza Sabdar ndmp_connect_get_conn(struct conn_list *clp, ndmp_door_ctx_t *enc_ctx)
7692654012fSReza Sabdar {
7702654012fSReza Sabdar int port;
7712654012fSReza Sabdar struct in_addr addr;
7722654012fSReza Sabdar char cl_addr[NDMP_CL_ADDR_LEN];
7732654012fSReza Sabdar ndmpd_session_t *session;
7742654012fSReza Sabdar
7752654012fSReza Sabdar if (!(session = (ndmpd_session_t *)ndmp_get_client_data(clp->cl_conn)))
7762654012fSReza Sabdar return;
7772654012fSReza Sabdar
7782654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, clp->cl_id);
7792654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_protocol_version);
7802654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, clp->cl_conn->conn_authorized);
7812654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_eof);
7822654012fSReza Sabdar if (tcp_get_peer(clp->cl_conn->conn_sock, &(addr.s_addr), &port) != -1)
7832654012fSReza Sabdar (void) snprintf(cl_addr, NDMP_CL_ADDR_LEN, "%s:%d",
7842654012fSReza Sabdar (char *)inet_ntoa(addr), port);
7852654012fSReza Sabdar else
7862654012fSReza Sabdar cl_addr[0] = '\0';
7872654012fSReza Sabdar ndmp_door_put_string(enc_ctx, cl_addr);
7882654012fSReza Sabdar }
7892654012fSReza Sabdar
7902654012fSReza Sabdar /*
7912654012fSReza Sabdar * Get the connection SCSI info.
7922654012fSReza Sabdar */
7932654012fSReza Sabdar static void
ndmp_connect_get_scsi_v2(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)7942654012fSReza Sabdar ndmp_connect_get_scsi_v2(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
7952654012fSReza Sabdar {
7962654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_scsi.sd_is_open);
7972654012fSReza Sabdar ndmp_door_put_string(enc_ctx, session->ns_scsi.sd_adapter_name);
7982654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_scsi.sd_valid_target_set);
7992654012fSReza Sabdar if (session->ns_scsi.sd_valid_target_set) {
8002654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_scsi.sd_sid);
8012654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_scsi.sd_lun);
8022654012fSReza Sabdar }
8032654012fSReza Sabdar }
8042654012fSReza Sabdar
8052654012fSReza Sabdar /*
8062654012fSReza Sabdar * Get the connection tape info.
8072654012fSReza Sabdar */
8082654012fSReza Sabdar static void
ndmp_connect_get_tape_v2(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)8092654012fSReza Sabdar ndmp_connect_get_tape_v2(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
8102654012fSReza Sabdar {
8112654012fSReza Sabdar char dev_name[NDMP_TAPE_DEV_NAME];
8122654012fSReza Sabdar
8132654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_tape.td_fd);
8142654012fSReza Sabdar if (session->ns_tape.td_fd != -1) {
8152654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, session->ns_tape.td_record_count);
8162654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_tape.td_mode);
8172654012fSReza Sabdar (void) snprintf(dev_name, NDMP_TAPE_DEV_NAME, "%st%02x%x",
8182654012fSReza Sabdar session->ns_tape.td_adapter_name, session->ns_tape.td_sid,
8192654012fSReza Sabdar session->ns_tape.td_lun);
8202654012fSReza Sabdar ndmp_door_put_string(enc_ctx, dev_name);
8212654012fSReza Sabdar ndmp_door_put_string(enc_ctx, session->ns_tape.td_adapter_name);
8222654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_tape.td_sid);
8232654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_tape.td_lun);
8242654012fSReza Sabdar }
8252654012fSReza Sabdar }
8262654012fSReza Sabdar
8272654012fSReza Sabdar /*
8282654012fSReza Sabdar * Get the connection mover info.
8292654012fSReza Sabdar */
8302654012fSReza Sabdar static void
ndmp_connect_get_mover_v2(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)8312654012fSReza Sabdar ndmp_connect_get_mover_v2(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
8322654012fSReza Sabdar {
8332654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_mover.md_state);
8342654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_mover.md_mode);
8352654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_mover.md_pause_reason);
8362654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_mover.md_halt_reason);
8372654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, session->ns_mover.md_record_size);
8382654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, session->ns_mover.md_record_num);
8392654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, session->ns_mover.md_position);
8402654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, session->ns_mover.md_window_offset);
8412654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, session->ns_mover.md_window_length);
8422654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_mover.md_sock);
8432654012fSReza Sabdar }
8442654012fSReza Sabdar
8452654012fSReza Sabdar /*
8462654012fSReza Sabdar * Get the connection common data info.
8472654012fSReza Sabdar */
8482654012fSReza Sabdar static void
ndmp_connect_get_data_common(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)8492654012fSReza Sabdar ndmp_connect_get_data_common(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
8502654012fSReza Sabdar {
8512654012fSReza Sabdar int i;
8522654012fSReza Sabdar ndmp_pval *ep;
8532654012fSReza Sabdar int len;
8542654012fSReza Sabdar
8552654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_data.dd_operation);
8562654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_data.dd_state);
8572654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_data.dd_halt_reason);
8582654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_data.dd_sock);
8592654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_data.dd_mover.addr_type);
8602654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_data.dd_abort);
8612654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, session->ns_data.dd_read_offset);
8622654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, session->ns_data.dd_read_length);
8632654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, session->ns_data.dd_data_size);
8642654012fSReza Sabdar /* verify data.env has as much data as in session->ns_data.dd_env_len */
8652654012fSReza Sabdar len = 0;
8662654012fSReza Sabdar ep = session->ns_data.dd_env;
8672654012fSReza Sabdar for (i = 0; ep && i < session->ns_data.dd_env_len; i++, ep++)
8682654012fSReza Sabdar len++;
8692654012fSReza Sabdar
8702654012fSReza Sabdar /* put the len */
8712654012fSReza Sabdar (void) mutex_lock(&session->ns_lock);
8722654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, len);
8732654012fSReza Sabdar ep = session->ns_data.dd_env;
8742654012fSReza Sabdar for (i = 0; i < len; i++, ep++) {
8752654012fSReza Sabdar ndmp_door_put_string(enc_ctx, ep->name);
8762654012fSReza Sabdar ndmp_door_put_string(enc_ctx, ep->value);
8772654012fSReza Sabdar }
8782654012fSReza Sabdar (void) mutex_unlock(&session->ns_lock);
8792654012fSReza Sabdar }
8802654012fSReza Sabdar
8812654012fSReza Sabdar /*
8822654012fSReza Sabdar * Get the connection data info.
8832654012fSReza Sabdar */
8842654012fSReza Sabdar static void
ndmp_connect_get_data_v2(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)8852654012fSReza Sabdar ndmp_connect_get_data_v2(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
8862654012fSReza Sabdar {
8872654012fSReza Sabdar int i;
8882654012fSReza Sabdar ndmp_name *np;
8892654012fSReza Sabdar char tcp_addr[NDMP_TCP_ADDR_SIZE];
8902654012fSReza Sabdar
8912654012fSReza Sabdar ndmp_connect_get_data_common(session, enc_ctx);
8922654012fSReza Sabdar
8932654012fSReza Sabdar switch (session->ns_data.dd_mover.addr_type) {
8942654012fSReza Sabdar case NDMP_ADDR_LOCAL:
8952654012fSReza Sabdar (void) snprintf(tcp_addr, NDMP_TCP_ADDR_SIZE, "%s", "Local");
8962654012fSReza Sabdar ndmp_door_put_string(enc_ctx, tcp_addr);
8972654012fSReza Sabdar break;
8982654012fSReza Sabdar case NDMP_ADDR_TCP:
8992654012fSReza Sabdar (void) snprintf(tcp_addr, NDMP_TCP_ADDR_SIZE, "%s:%d",
9002654012fSReza Sabdar (char *)inet_ntoa(IN_ADDR(
9012654012fSReza Sabdar session->ns_data.dd_mover.ndmp_mover_addr_u.addr.ip_addr)),
9022654012fSReza Sabdar session->ns_data.dd_mover.ndmp_mover_addr_u.addr.port);
9032654012fSReza Sabdar ndmp_door_put_string(enc_ctx, tcp_addr);
9042654012fSReza Sabdar break;
9052654012fSReza Sabdar default:
9062654012fSReza Sabdar (void) snprintf(tcp_addr, NDMP_TCP_ADDR_SIZE, "%s", "Unknown");
9072654012fSReza Sabdar ndmp_door_put_string(enc_ctx, tcp_addr);
9082654012fSReza Sabdar }
9092654012fSReza Sabdar
9102654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, session->ns_data.dd_nlist_len);
9112654012fSReza Sabdar np = session->ns_data.dd_nlist;
9122654012fSReza Sabdar for (i = 0; np && i < (int)session->ns_data.dd_nlist_len; i++, np++) {
9132654012fSReza Sabdar ndmp_door_put_string(enc_ctx, np->name);
9142654012fSReza Sabdar ndmp_door_put_string(enc_ctx, np->dest);
9152654012fSReza Sabdar }
9162654012fSReza Sabdar }
9172654012fSReza Sabdar
9182654012fSReza Sabdar /*
9192654012fSReza Sabdar * Get V2 connection info.
9202654012fSReza Sabdar */
9212654012fSReza Sabdar static void
ndmp_connect_get_v2(ndmp_connection_t * connection,ndmp_door_ctx_t * enc_ctx)9222654012fSReza Sabdar ndmp_connect_get_v2(ndmp_connection_t *connection, ndmp_door_ctx_t *enc_ctx)
9232654012fSReza Sabdar {
9242654012fSReza Sabdar ndmpd_session_t *session;
9252654012fSReza Sabdar
9262654012fSReza Sabdar if ((session = (ndmpd_session_t *)ndmp_get_client_data(connection))) {
9272654012fSReza Sabdar ndmp_connect_get_scsi_v2(session, enc_ctx);
9282654012fSReza Sabdar ndmp_connect_get_tape_v2(session, enc_ctx);
9292654012fSReza Sabdar ndmp_connect_get_mover_v2(session, enc_ctx);
9302654012fSReza Sabdar ndmp_connect_get_data_v2(session, enc_ctx);
9312654012fSReza Sabdar }
9322654012fSReza Sabdar }
9332654012fSReza Sabdar
9342654012fSReza Sabdar /*
9352654012fSReza Sabdar * Get the V3 connection mover info.
9362654012fSReza Sabdar */
9372654012fSReza Sabdar static void
ndmp_connect_get_mover_v3(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)9382654012fSReza Sabdar ndmp_connect_get_mover_v3(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
9392654012fSReza Sabdar {
9402654012fSReza Sabdar char tcp_addr[NDMP_TCP_ADDR_SIZE];
9412654012fSReza Sabdar
9422654012fSReza Sabdar /* get all the V2 mover data first */
9432654012fSReza Sabdar ndmp_connect_get_mover_v2(session, enc_ctx);
9442654012fSReza Sabdar
9452654012fSReza Sabdar /* get the V3 mover data now */
9462654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_mover.md_listen_sock);
9472654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_mover.md_data_addr.addr_type);
9482654012fSReza Sabdar tcp_addr[0] = '\0';
9492654012fSReza Sabdar (void) snprintf(tcp_addr, NDMP_TCP_ADDR_SIZE, "%s:%d",
9502654012fSReza Sabdar (char *)
9512654012fSReza Sabdar inet_ntoa(IN_ADDR(session->ns_mover.md_data_addr.tcp_ip_v3)),
9522654012fSReza Sabdar (int)session->ns_mover.md_data_addr.tcp_port_v3);
9532654012fSReza Sabdar ndmp_door_put_string(enc_ctx, tcp_addr);
9542654012fSReza Sabdar }
9552654012fSReza Sabdar
9562654012fSReza Sabdar /*
9572654012fSReza Sabdar * Get the connection data info.
9582654012fSReza Sabdar */
9592654012fSReza Sabdar static void
ndmp_connect_get_data_v3(ndmpd_session_t * session,ndmp_door_ctx_t * enc_ctx)9602654012fSReza Sabdar ndmp_connect_get_data_v3(ndmpd_session_t *session, ndmp_door_ctx_t *enc_ctx)
9612654012fSReza Sabdar {
9622654012fSReza Sabdar ulong_t i;
9632654012fSReza Sabdar mem_ndmp_name_v3_t *np;
9642654012fSReza Sabdar char tcp_addr[NDMP_TCP_ADDR_SIZE];
9652654012fSReza Sabdar
9662654012fSReza Sabdar ndmp_connect_get_data_common(session, enc_ctx);
9672654012fSReza Sabdar
9682654012fSReza Sabdar (void) snprintf(tcp_addr, NDMP_TCP_ADDR_SIZE, "%s:%d",
9692654012fSReza Sabdar (char *)inet_ntoa(IN_ADDR(session->ns_data.dd_data_addr.tcp_ip_v3)),
9702654012fSReza Sabdar (int)session->ns_data.dd_data_addr.tcp_port_v3);
9712654012fSReza Sabdar ndmp_door_put_string(enc_ctx, tcp_addr);
9722654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, session->ns_data.dd_listen_sock);
9732654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx,
9742654012fSReza Sabdar session->ns_data.dd_module.dm_stats.ms_bytes_processed);
9752654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, session->ns_data.dd_nlist_len);
9762654012fSReza Sabdar np = session->ns_data.dd_nlist_v3;
9772654012fSReza Sabdar for (i = 0; np && i < (int)session->ns_data.dd_nlist_len; i++, np++) {
9782654012fSReza Sabdar ndmp_door_put_string(enc_ctx, np->nm3_opath);
9792654012fSReza Sabdar ndmp_door_put_string(enc_ctx, np->nm3_dpath);
9802654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, np->nm3_node);
9812654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, np->nm3_fh_info);
9822654012fSReza Sabdar }
9832654012fSReza Sabdar }
9842654012fSReza Sabdar
9852654012fSReza Sabdar /*
9862654012fSReza Sabdar * Get V3 connection info.
9872654012fSReza Sabdar */
9882654012fSReza Sabdar static void
ndmp_connect_get_v3(ndmp_connection_t * connection,ndmp_door_ctx_t * enc_ctx)9892654012fSReza Sabdar ndmp_connect_get_v3(ndmp_connection_t *connection, ndmp_door_ctx_t *enc_ctx)
9902654012fSReza Sabdar {
9912654012fSReza Sabdar ndmpd_session_t *session;
9922654012fSReza Sabdar
9932654012fSReza Sabdar if ((session = (ndmpd_session_t *)ndmp_get_client_data(connection))) {
9942654012fSReza Sabdar ndmp_connect_get_scsi_v2(session, enc_ctx);
9952654012fSReza Sabdar ndmp_connect_get_tape_v2(session, enc_ctx);
9962654012fSReza Sabdar ndmp_connect_get_mover_v3(session, enc_ctx);
9972654012fSReza Sabdar ndmp_connect_get_data_v3(session, enc_ctx);
9982654012fSReza Sabdar }
9992654012fSReza Sabdar }
10002654012fSReza Sabdar
10012654012fSReza Sabdar /*
10022654012fSReza Sabdar * Get the list of all active sessions to the clients. For each version,
10032654012fSReza Sabdar * call the appropriate get function.
10042654012fSReza Sabdar */
10052654012fSReza Sabdar static void
connection_get(struct conn_list * clp,ndmp_door_ctx_t * enc_ctx)10062654012fSReza Sabdar connection_get(struct conn_list *clp, ndmp_door_ctx_t *enc_ctx)
10072654012fSReza Sabdar {
10082654012fSReza Sabdar ndmpd_session_t *session;
10092654012fSReza Sabdar
10102654012fSReza Sabdar session = (ndmpd_session_t *)ndmp_get_client_data(clp->cl_conn);
10112654012fSReza Sabdar if (!session) {
10122654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, NDMP_SESSION_NODATA);
10132654012fSReza Sabdar return;
10142654012fSReza Sabdar }
10152654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, NDMP_SESSION_DATA);
10162654012fSReza Sabdar
10172654012fSReza Sabdar switch (session->ns_protocol_version) {
10182654012fSReza Sabdar case NDMPV2:
10192654012fSReza Sabdar ndmp_connect_get_conn(clp, enc_ctx);
10202654012fSReza Sabdar ndmp_connect_get_v2(clp->cl_conn, enc_ctx);
10212654012fSReza Sabdar break;
10222654012fSReza Sabdar case NDMPV3:
10232654012fSReza Sabdar case NDMPV4:
10242654012fSReza Sabdar ndmp_connect_get_conn(clp, enc_ctx);
10252654012fSReza Sabdar ndmp_connect_get_v3(clp->cl_conn, enc_ctx);
10262654012fSReza Sabdar break;
10272654012fSReza Sabdar default:
10282654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
10292654012fSReza Sabdar "Invalid session (0x%p) version 0x%x", session,
10302654012fSReza Sabdar session->ns_protocol_version);
10312654012fSReza Sabdar }
10322654012fSReza Sabdar }
10332654012fSReza Sabdar
10342654012fSReza Sabdar /*
10352654012fSReza Sabdar * ndmpd_connect_kill
10362654012fSReza Sabdar *
10372654012fSReza Sabdar * Kill the connection based on its version.
10382654012fSReza Sabdar *
10392654012fSReza Sabdar * Parameters:
10402654012fSReza Sabdar * connection (input) - connection handler.
10412654012fSReza Sabdar *
10422654012fSReza Sabdar * Returns:
10432654012fSReza Sabdar * 0 - success
10442654012fSReza Sabdar * -1 - error
10452654012fSReza Sabdar */
10462654012fSReza Sabdar int
ndmpd_connect_kill(ndmp_connection_t * connection)10472654012fSReza Sabdar ndmpd_connect_kill(ndmp_connection_t *connection)
10482654012fSReza Sabdar {
10492654012fSReza Sabdar ndmpd_session_t *session;
10502654012fSReza Sabdar
10512654012fSReza Sabdar if (!(session = (ndmpd_session_t *)ndmp_get_client_data(connection)))
10522654012fSReza Sabdar return (-1);
10532654012fSReza Sabdar
10542654012fSReza Sabdar switch (session->ns_protocol_version) {
10552654012fSReza Sabdar case NDMPV2:
10562654012fSReza Sabdar ndmpd_connect_close_v2(connection, (void *)NULL);
10572654012fSReza Sabdar break;
10582654012fSReza Sabdar case NDMPV3:
10592654012fSReza Sabdar case NDMPV4:
10602654012fSReza Sabdar ndmpd_connect_close_v3(connection, (void *)NULL);
10612654012fSReza Sabdar break;
10622654012fSReza Sabdar default:
10632654012fSReza Sabdar NDMP_LOG(LOG_DEBUG,
10642654012fSReza Sabdar "Invalid session (0x%p) version 0x%x", session,
10652654012fSReza Sabdar session->ns_protocol_version);
10662654012fSReza Sabdar }
10672654012fSReza Sabdar
10682654012fSReza Sabdar return (0);
10692654012fSReza Sabdar }
10702654012fSReza Sabdar
10712654012fSReza Sabdar /*
10722654012fSReza Sabdar * Get the list of all active sessions to the clients.
10732654012fSReza Sabdar */
10742654012fSReza Sabdar void
ndmp_connect_list_get(ndmp_door_ctx_t * enc_ctx)10752654012fSReza Sabdar ndmp_connect_list_get(ndmp_door_ctx_t *enc_ctx)
10762654012fSReza Sabdar {
10772654012fSReza Sabdar int n;
10782654012fSReza Sabdar struct conn_list *clp;
10792654012fSReza Sabdar
10802654012fSReza Sabdar n = 0;
10812654012fSReza Sabdar (void) mutex_lock(&cl_mutex);
10822654012fSReza Sabdar LIST_FOREACH(clp, &cl_head, cl_q) {
10832654012fSReza Sabdar n++;
10842654012fSReza Sabdar }
10852654012fSReza Sabdar /* write number of connections */
10862654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, n);
10872654012fSReza Sabdar n = 0;
10882654012fSReza Sabdar LIST_FOREACH(clp, &cl_head, cl_q) {
10892654012fSReza Sabdar connection_get(clp, enc_ctx);
10902654012fSReza Sabdar n++;
10912654012fSReza Sabdar }
10922654012fSReza Sabdar (void) mutex_unlock(&cl_mutex);
10932654012fSReza Sabdar }
10942654012fSReza Sabdar
10952654012fSReza Sabdar /*
10962654012fSReza Sabdar * ndmpd_connect_kill_id
10972654012fSReza Sabdar *
10982654012fSReza Sabdar * Find a connection by its id and kill it.
10992654012fSReza Sabdar *
11002654012fSReza Sabdar * Parameters:
11012654012fSReza Sabdar * id (input) - connection id.
11022654012fSReza Sabdar *
11032654012fSReza Sabdar * Returns:
11042654012fSReza Sabdar * 0 - success
11052654012fSReza Sabdar * -1 - error
11062654012fSReza Sabdar */
11072654012fSReza Sabdar int
ndmpd_connect_kill_id(int id)11082654012fSReza Sabdar ndmpd_connect_kill_id(int id)
11092654012fSReza Sabdar {
11102654012fSReza Sabdar struct conn_list *clp;
11112654012fSReza Sabdar
11122654012fSReza Sabdar if (!(clp = ndmp_connect_list_find_id(id)))
11132654012fSReza Sabdar return (-1);
11142654012fSReza Sabdar
11152654012fSReza Sabdar return (ndmpd_connect_kill(clp->cl_conn));
11162654012fSReza Sabdar }
11172654012fSReza Sabdar
11182654012fSReza Sabdar /* Get the devices info */
11192654012fSReza Sabdar void
ndmpd_get_devs(ndmp_door_ctx_t * enc_ctx)11202654012fSReza Sabdar ndmpd_get_devs(ndmp_door_ctx_t *enc_ctx)
11212654012fSReza Sabdar {
11222654012fSReza Sabdar int i, n;
11232654012fSReza Sabdar sasd_drive_t *sd;
11242654012fSReza Sabdar scsi_link_t *slink;
11252654012fSReza Sabdar
11262654012fSReza Sabdar if ((n = sasd_dev_count()) == 0) {
11272654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, n);
11282654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "No device attached.");
11292654012fSReza Sabdar return;
11302654012fSReza Sabdar }
11312654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, n);
11322654012fSReza Sabdar
11332654012fSReza Sabdar for (i = 0; i < n; i++) {
11342654012fSReza Sabdar sd = sasd_drive(i);
11352654012fSReza Sabdar slink = sasd_dev_slink(i);
11362654012fSReza Sabdar
11372654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, slink->sl_type);
11382654012fSReza Sabdar ndmp_door_put_string(enc_ctx, sd->sd_name);
11392654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, slink->sl_lun);
11402654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, slink->sl_sid);
11412654012fSReza Sabdar ndmp_door_put_string(enc_ctx, sd->sd_vendor);
11422654012fSReza Sabdar ndmp_door_put_string(enc_ctx, sd->sd_id);
11432654012fSReza Sabdar ndmp_door_put_string(enc_ctx, sd->sd_rev);
11447bc22e45SReza Sabdar ndmp_door_put_string(enc_ctx, sd->sd_serial);
11457bc22e45SReza Sabdar ndmp_door_put_string(enc_ctx, sd->sd_wwn);
11462654012fSReza Sabdar }
11472654012fSReza Sabdar }
11482654012fSReza Sabdar
11492654012fSReza Sabdar /*
11502654012fSReza Sabdar * ndmpd_connect_auth_text
11512654012fSReza Sabdar *
11522654012fSReza Sabdar * Checks text authorization.
11532654012fSReza Sabdar *
11542654012fSReza Sabdar * Parameters:
11552654012fSReza Sabdar * auth_id (input) - user name
11562654012fSReza Sabdar * auth_password(input) - password
11572654012fSReza Sabdar *
11582654012fSReza Sabdar * Returns:
11592654012fSReza Sabdar * NDMP_NO_ERR: on success
11602654012fSReza Sabdar * Other NDMP_ error: invalid user name and password
11612654012fSReza Sabdar */
11622654012fSReza Sabdar int
ndmpd_connect_auth_text(char * uname,char * auth_id,char * auth_password)11632654012fSReza Sabdar ndmpd_connect_auth_text(char *uname, char *auth_id, char *auth_password)
11642654012fSReza Sabdar {
11652654012fSReza Sabdar char *passwd, *dec_passwd;
11662654012fSReza Sabdar int rv;
11672654012fSReza Sabdar
11682654012fSReza Sabdar if (strcmp(uname, auth_id) != 0) {
11692654012fSReza Sabdar rv = NDMP_NOT_AUTHORIZED_ERR;
11702654012fSReza Sabdar } else {
11712654012fSReza Sabdar passwd = ndmpd_get_prop(NDMP_CLEARTEXT_PASSWORD);
11722654012fSReza Sabdar if (!passwd || !*passwd) {
11732654012fSReza Sabdar rv = NDMP_NOT_AUTHORIZED_ERR;
11742654012fSReza Sabdar } else {
11752654012fSReza Sabdar dec_passwd = ndmp_base64_decode(passwd);
11762654012fSReza Sabdar if (dec_passwd == NULL || *dec_passwd == 0)
11772654012fSReza Sabdar rv = NDMP_NOT_AUTHORIZED_ERR;
11782654012fSReza Sabdar else if (strcmp(auth_password, dec_passwd) != 0)
11792654012fSReza Sabdar rv = NDMP_NOT_AUTHORIZED_ERR;
11802654012fSReza Sabdar else
11812654012fSReza Sabdar rv = NDMP_NO_ERR;
11822654012fSReza Sabdar
11832654012fSReza Sabdar free(dec_passwd);
11842654012fSReza Sabdar }
11852654012fSReza Sabdar }
11862654012fSReza Sabdar
11872654012fSReza Sabdar if (rv == NDMP_NO_ERR) {
11882654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Authorization granted.");
11892654012fSReza Sabdar } else {
11902654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Authorization denied.");
11912654012fSReza Sabdar }
11922654012fSReza Sabdar
11932654012fSReza Sabdar return (rv);
11942654012fSReza Sabdar }
11952654012fSReza Sabdar
11962654012fSReza Sabdar
11972654012fSReza Sabdar /*
11982654012fSReza Sabdar * ndmpd_connect_auth_md5
11992654012fSReza Sabdar *
12002654012fSReza Sabdar * Checks MD5 authorization.
12012654012fSReza Sabdar *
12022654012fSReza Sabdar * Parameters:
12032654012fSReza Sabdar * auth_id (input) - user name
12042654012fSReza Sabdar * auth_digest(input) - MD5 digest
12052654012fSReza Sabdar * This is a 16 bytes digest info which is a MD5 transform of 128 bytes
12062654012fSReza Sabdar * message (password + padding + server challenge + password). Server
12072654012fSReza Sabdar * challenge is a 64 bytes random string per NDMP session sent out to the
12082654012fSReza Sabdar * client on demand (See NDMP_CONFIG_GET_AUTH_ATTR command).
12092654012fSReza Sabdar *
12102654012fSReza Sabdar * Returns:
12112654012fSReza Sabdar * NDMP_NO_ERR: on success
12122654012fSReza Sabdar * Other NDMP_ error: invalid user name and password
12132654012fSReza Sabdar */
12142654012fSReza Sabdar int
ndmpd_connect_auth_md5(char * uname,char * auth_id,char * auth_digest,unsigned char * auth_challenge)12152654012fSReza Sabdar ndmpd_connect_auth_md5(char *uname, char *auth_id, char *auth_digest,
12162654012fSReza Sabdar unsigned char *auth_challenge)
12172654012fSReza Sabdar {
12182654012fSReza Sabdar char *passwd, *dec_passwd;
12192654012fSReza Sabdar unsigned char digest[16];
12202654012fSReza Sabdar int rv;
12212654012fSReza Sabdar
12222654012fSReza Sabdar if (strcmp(uname, auth_id) != 0) {
12232654012fSReza Sabdar rv = NDMP_NOT_AUTHORIZED_ERR;
12242654012fSReza Sabdar } else {
12252654012fSReza Sabdar passwd = ndmpd_get_prop(NDMP_CRAM_MD5_PASSWORD);
12262654012fSReza Sabdar if (passwd == NULL || *passwd == 0) {
12272654012fSReza Sabdar rv = NDMP_NOT_AUTHORIZED_ERR;
12282654012fSReza Sabdar } else {
12292654012fSReza Sabdar dec_passwd = ndmp_base64_decode(passwd);
12302654012fSReza Sabdar
12312654012fSReza Sabdar if (dec_passwd == NULL || *dec_passwd == 0) {
12322654012fSReza Sabdar rv = NDMP_NOT_AUTHORIZED_ERR;
12332654012fSReza Sabdar } else {
12342654012fSReza Sabdar create_md5_digest(digest, dec_passwd,
12352654012fSReza Sabdar auth_challenge);
12362654012fSReza Sabdar if (memcmp(digest, auth_digest,
12372654012fSReza Sabdar sizeof (digest)) != 0) {
12382654012fSReza Sabdar rv = NDMP_NOT_AUTHORIZED_ERR;
12392654012fSReza Sabdar } else {
12402654012fSReza Sabdar rv = NDMP_NO_ERR;
12412654012fSReza Sabdar }
12422654012fSReza Sabdar }
12432654012fSReza Sabdar free(dec_passwd);
12442654012fSReza Sabdar }
12452654012fSReza Sabdar }
12462654012fSReza Sabdar
12472654012fSReza Sabdar if (rv == NDMP_NO_ERR) {
12482654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Authorization granted.");
12492654012fSReza Sabdar } else {
12502654012fSReza Sabdar NDMP_LOG(LOG_ERR, "Authorization denied.");
12512654012fSReza Sabdar }
12522654012fSReza Sabdar
12532654012fSReza Sabdar return (rv);
12542654012fSReza Sabdar }
1255