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 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 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 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 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 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 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 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 * 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 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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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