1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <arpa/inet.h> 27 #include <sys/socket.h> 28 #include <sys/types.h> 29 #include <stdarg.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <strings.h> 33 #include <unistd.h> 34 #include <syslog.h> 35 #include <errno.h> 36 37 #include <fcntl.h> 38 #include <stdio.h> 39 #include <time.h> 40 #include <libdevinfo.h> 41 42 #include <sys/scsi/adapters/iscsi_if.h> 43 #include <sys/scsi/adapters/iscsi_protocol.h> 44 #include <ima.h> 45 #include "iscsiadm.h" 46 #include "sun_ima.h" 47 48 #define LIBRARY_PROPERTY_SUPPORTED_IMA_VERSION 1 49 #define LIBRARY_PROPERTY_IMPLEMENTATION_VERSION L"1.0.0" 50 #define LIBRARY_PROPERTY_VENDOR L"Sun Microsystems, Inc." 51 #define DEFAULT_NODE_NAME_FORMAT "iqn.2003-13.com.ima.%s" 52 #define PLUGIN_OWNER 1 53 #define MAX_CHAP_SECRET_LEN 16 54 55 /* LINTED E_STATIC_UNUSED */ 56 static IMA_INT32 number_of_plugins = -1; 57 /* LINTED E_STATIC_UNUSED */ 58 static IMA_NODE_NAME sharedNodeName; 59 /* LINTED E_STATIC_UNUSED */ 60 static IMA_NODE_ALIAS sharedNodeAlias; 61 /* LINTED E_STATIC_UNUSED */ 62 static IMA_PLUGIN_PROPERTIES PluginProperties; 63 64 /* LINTED E_STATIC_UNUSED */ 65 static IMA_OID pluginOid; 66 static IMA_OID lhbaObjectId; 67 /* LINTED E_STATIC_UNUSED */ 68 static boolean_t pluginInit = B_FALSE; 69 70 /* Forward declaration */ 71 #define BOOL_PARAM 1 72 #define MIN_MAX_PARAM 2 73 #define PARAM_OP_OK 0 74 #define PARAM_OP_FAILED 1 75 76 static int open_driver(int *fd); 77 static IMA_STATUS getISCSINodeParameter(int paramType, 78 IMA_OID *oid, 79 void *pProps, 80 uint32_t paramIndex); 81 static IMA_STATUS setISCSINodeParameter(int paramType, 82 IMA_OID *oid, 83 void *pProps, 84 uint32_t paramIndex); 85 static IMA_STATUS getDigest(IMA_OID oid, int ioctlCmd, 86 SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm); 87 static IMA_STATUS setAuthMethods(IMA_OID oid, IMA_UINT *pMethodCount, 88 const IMA_AUTHMETHOD *pMethodList); 89 static IMA_STATUS getAuthMethods(IMA_OID oid, IMA_UINT *pMethodCount, 90 IMA_AUTHMETHOD *pMethodList); 91 IMA_STATUS getNegotiatedDigest(int digestType, 92 SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm, 93 SUN_IMA_CONN_PROPERTIES *connProps); 94 95 /* OK */ 96 #define DISC_ADDR_OK 0 97 /* Incorrect IP address */ 98 #define DISC_ADDR_INTEGRITY_ERROR 1 99 /* Error converting text IP address to numeric binary form */ 100 #define DISC_ADDR_IP_CONV_ERROR 2 101 static int prepare_discovery_entry(SUN_IMA_TARGET_ADDRESS discoveryAddress, 102 entry_t *entry); 103 static int prepare_discovery_entry_IMA(IMA_TARGET_ADDRESS discoveryAddress, 104 entry_t *entry); 105 106 /* LINTED E_STATIC_UNUSED */ 107 static IMA_STATUS configure_discovery_method(IMA_BOOL enable, 108 iSCSIDiscoveryMethod_t method); 109 110 static IMA_STATUS get_target_oid_list(uint32_t targetListType, 111 IMA_OID_LIST **ppList); 112 113 static IMA_STATUS get_target_lun_oid_list(IMA_OID * targetOid, 114 iscsi_lun_list_t **ppLunList); 115 116 static int get_lun_devlink(di_devlink_t link, void *osDeviceName); 117 118 static IMA_STATUS getConnOidList( 119 IMA_OID *oid, 120 iscsi_conn_list_t **ppConnList); 121 122 static IMA_STATUS getConnProps( 123 iscsi_if_conn_t *pConn, 124 iscsi_conn_props_t **ppConnProps); 125 126 /* LINTED E_STATIC_UNUSED */ 127 static void libSwprintf(wchar_t *wcs, const wchar_t *lpszFormat, ...) 128 { 129 va_list args; 130 va_start(args, lpszFormat); 131 (void) vswprintf(wcs, 255, lpszFormat, args); 132 va_end(args); 133 } 134 135 136 char * 137 _strlwr(char *s) 138 { 139 char *t = s; 140 while (t != NULL && *t) { 141 if (*t >= 'A' && *t <= 'Z') 142 *t += 32; 143 t++; 144 } 145 return (s); 146 } 147 148 /* LINTED E_STATIC_UNUSED */ 149 static void GetBuildTime(IMA_DATETIME* pdatetime) 150 { 151 #if defined(BUILD_DATE) 152 if (strptime(BUILD_DATE, "%Y/%m/%d %T %Z", pdatetime) == NULL) { 153 (void) memset(pdatetime, 0, sizeof (IMA_DATETIME)); 154 } 155 #else 156 (void) memset(pdatetime, 0, sizeof (IMA_DATETIME)); 157 #endif 158 } 159 160 /* 161 * Non-IMA defined function. 162 */ 163 IMA_API IMA_STATUS SUN_IMA_GetDiscoveryAddressPropertiesList( 164 SUN_IMA_DISC_ADDR_PROP_LIST **ppList 165 ) 166 { 167 char discovery_addr_str[256]; 168 int fd; 169 int i; 170 int discovery_addr_list_size; 171 int status; 172 int out_cnt; 173 iscsi_addr_list_t *ialp; 174 /* LINTED E_FUNC_SET_NOT_USED */ 175 IMA_IP_ADDRESS *ipAddr; 176 177 if ((status = open_driver(&fd))) { 178 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 179 } 180 181 ialp = (iscsi_addr_list_t *)calloc(1, sizeof (iscsi_addr_list_t)); 182 if (ialp == NULL) { 183 (void) close(fd); 184 return (IMA_ERROR_INSUFFICIENT_MEMORY); 185 } 186 187 ialp->al_vers = ISCSI_INTERFACE_VERSION; 188 ialp->al_in_cnt = ialp->al_out_cnt = 1; 189 190 /* 191 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl 192 * We have allocated space for one entry, if more than one 193 * address is going to be returned, we will re-issue the ioctl 194 */ 195 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, ialp) != 0) { 196 (void) close(fd); 197 syslog(LOG_USER|LOG_DEBUG, 198 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno: %d", 199 errno); 200 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 201 } 202 203 if (ialp->al_out_cnt > 1) { 204 /* 205 * we need to allocate more space, save off the out_cnt 206 * and free ialp 207 */ 208 out_cnt = ialp->al_out_cnt; 209 free(ialp); 210 211 discovery_addr_list_size = sizeof (iscsi_addr_list_t); 212 discovery_addr_list_size += (sizeof (iscsi_addr_t) * 213 out_cnt - 1); 214 ialp = (iscsi_addr_list_t *)calloc(1, discovery_addr_list_size); 215 if (ialp == NULL) { 216 (void) close(fd); 217 return (IMA_ERROR_INSUFFICIENT_MEMORY); 218 } 219 ialp->al_vers = ISCSI_INTERFACE_VERSION; 220 ialp->al_in_cnt = out_cnt; 221 222 /* 223 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl again to obtain all 224 * the discovery addresses. 225 */ 226 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, ialp) != 0) { 227 #define ERROR_STR "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno :%d" 228 free(ialp); 229 (void) close(fd); 230 syslog(LOG_USER|LOG_DEBUG, 231 ERROR_STR, errno); 232 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 233 #undef ERROR_STR 234 235 } 236 } 237 238 *ppList = (SUN_IMA_DISC_ADDR_PROP_LIST *)calloc(1, 239 sizeof (SUN_IMA_DISC_ADDR_PROP_LIST) + 240 ialp->al_out_cnt * sizeof (IMA_DISCOVERY_ADDRESS_PROPERTIES)); 241 if (*ppList == NULL) { 242 free(ialp); 243 (void) close(fd); 244 return (IMA_ERROR_INSUFFICIENT_MEMORY); 245 } 246 (*ppList)->discAddrCount = ialp->al_out_cnt; 247 248 for (i = 0; i < ialp->al_out_cnt; i++) { 249 if (ialp->al_addrs[i].a_addr.i_insize == 250 sizeof (struct in_addr)) { 251 252 (*ppList)->props[i].discoveryAddress.hostnameIpAddress. 253 id.ipAddress.ipv4Address = IMA_TRUE; 254 255 } else if (ialp->al_addrs[i].a_addr.i_insize == 256 sizeof (struct in6_addr)) { 257 258 (*ppList)->props[i].discoveryAddress.hostnameIpAddress. 259 id.ipAddress.ipv4Address = IMA_FALSE; 260 261 } else { 262 (void) strlcpy(discovery_addr_str, "unknown", 263 sizeof (discovery_addr_str)); 264 } 265 266 ipAddr = &(*ppList)->props[i].discoveryAddress. 267 hostnameIpAddress.id.ipAddress; 268 269 bcopy(&ialp->al_addrs[i].a_addr.i_addr, 270 (*ppList)->props[i].discoveryAddress.hostnameIpAddress.id. 271 ipAddress.ipAddress, 272 sizeof (ipAddr->ipAddress)); 273 274 (*ppList)->props[i].discoveryAddress.portNumber = 275 ialp->al_addrs[i].a_port; 276 } 277 278 free(ialp); 279 (void) close(fd); 280 return (IMA_STATUS_SUCCESS); 281 } 282 283 IMA_API IMA_STATUS SUN_IMA_GetStaticTargetProperties( 284 IMA_OID staticTargetOid, 285 SUN_IMA_STATIC_TARGET_PROPERTIES *pProps 286 ) 287 { 288 int fd; 289 int status; 290 iscsi_static_property_t prop; 291 /* LINTED */ 292 IMA_IP_ADDRESS *ipAddr; 293 294 if ((status = open_driver(&fd))) { 295 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 296 } 297 298 (void) memset(&prop, 0, sizeof (iscsi_static_property_t)); 299 prop.p_vers = ISCSI_INTERFACE_VERSION; 300 prop.p_oid = (uint32_t)staticTargetOid.objectSequenceNumber; 301 if (ioctl(fd, ISCSI_STATIC_GET, &prop) != 0) { 302 status = errno; 303 (void) close(fd); 304 syslog(LOG_USER|LOG_DEBUG, 305 "ISCSI_STATIC_GET ioctl failed, errno: %d", status); 306 if (status == ENOENT) { 307 return (IMA_ERROR_OBJECT_NOT_FOUND); 308 } else { 309 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 310 } 311 } 312 (void) close(fd); 313 314 (void) mbstowcs(pProps->staticTarget.targetName, (char *)prop.p_name, 315 sizeof (pProps->staticTarget.targetName)/sizeof (IMA_WCHAR)); 316 317 if (prop.p_addr_list.al_addrs[0].a_addr.i_insize == 318 sizeof (struct in_addr)) { 319 /* IPv4 */ 320 pProps->staticTarget.targetAddress.imaStruct.hostnameIpAddress. 321 id.ipAddress.ipv4Address = IMA_TRUE; 322 } else if (prop.p_addr_list.al_addrs[0].a_addr.i_insize == 323 sizeof (struct in6_addr)) { 324 /* IPv6 */ 325 pProps->staticTarget.targetAddress.imaStruct.hostnameIpAddress. 326 id.ipAddress.ipv4Address = IMA_FALSE; 327 } else { 328 /* Should not happen */ 329 syslog(LOG_USER|LOG_DEBUG, 330 "ISCSI_STATIC_GET returned bad address"); 331 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 332 } 333 334 ipAddr = &pProps->staticTarget.targetAddress.imaStruct. 335 hostnameIpAddress.id.ipAddress; 336 337 bcopy(&prop.p_addr_list.al_addrs[0].a_addr.i_addr, 338 pProps->staticTarget.targetAddress.imaStruct.hostnameIpAddress.id. 339 ipAddress.ipAddress, sizeof (ipAddr->ipAddress)); 340 341 pProps->staticTarget.targetAddress.imaStruct.portNumber = 342 prop.p_addr_list.al_addrs[0].a_port; 343 344 345 if (prop.p_addr_list.al_tpgt == (uint32_t)ISCSI_DEFAULT_TPGT) { 346 pProps->staticTarget.targetAddress.defaultTpgt = IMA_TRUE; 347 pProps->staticTarget.targetAddress.tpgt = 0; 348 } else { 349 pProps->staticTarget.targetAddress.defaultTpgt = IMA_FALSE; 350 pProps->staticTarget.targetAddress.tpgt = 351 prop.p_addr_list.al_tpgt; 352 } 353 354 return (IMA_STATUS_SUCCESS); 355 } 356 357 /*ARGSUSED*/ 358 IMA_API IMA_STATUS SUN_IMA_AddStaticTarget( 359 IMA_OID lhbaOid, 360 const SUN_IMA_STATIC_DISCOVERY_TARGET staticConfig, 361 IMA_OID *pTargetOid 362 ) 363 { 364 iscsi_target_entry_t target; 365 int fd; 366 int target_in_addr_size; 367 int status; 368 union { 369 struct in_addr u_in4; 370 struct in6_addr u_in6; 371 } target_in; 372 373 /* 374 * staticConfig.address may come in with port number at its trailer. 375 * Parse it to separate the IP address and port number. 376 * Also translate the hostname to IP address if needed. 377 */ 378 379 if (staticConfig.targetAddress.imaStruct.hostnameIpAddress.id.ipAddress. 380 ipv4Address == IMA_FALSE) { 381 382 bcopy(staticConfig.targetAddress.imaStruct.hostnameIpAddress. 383 id.ipAddress.ipAddress, &target_in.u_in6, 384 sizeof (target_in.u_in6)); 385 386 target_in_addr_size = sizeof (struct in6_addr); 387 } else { 388 389 bcopy(staticConfig.targetAddress.imaStruct.hostnameIpAddress. 390 id.ipAddress.ipAddress, &target_in.u_in4, 391 sizeof (target_in.u_in4)); 392 393 target_in_addr_size = sizeof (struct in_addr); 394 } 395 396 (void) memset(&target, 0, sizeof (iscsi_target_entry_t)); 397 target.te_entry.e_vers = ISCSI_INTERFACE_VERSION; 398 target.te_entry.e_oid = ISCSI_OID_NOTSET; 399 400 (void) wcstombs((char *)target.te_name, staticConfig.targetName, 401 ISCSI_MAX_NAME_LEN); 402 403 target.te_entry.e_insize = target_in_addr_size; 404 if (target.te_entry.e_insize == sizeof (struct in_addr)) { 405 target.te_entry.e_u.u_in4.s_addr = target_in.u_in4.s_addr; 406 } else if (target.te_entry.e_insize == sizeof (struct in6_addr)) { 407 bcopy(target_in.u_in6.s6_addr, 408 target.te_entry.e_u.u_in6.s6_addr, 409 sizeof (struct in6_addr)); 410 } else { 411 return (IMA_ERROR_INVALID_PARAMETER); 412 } 413 414 target.te_entry.e_port = 415 staticConfig.targetAddress.imaStruct.portNumber; 416 417 if (staticConfig.targetAddress.defaultTpgt == IMA_TRUE) { 418 target.te_entry.e_tpgt = ISCSI_DEFAULT_TPGT; 419 } else { 420 target.te_entry.e_tpgt = staticConfig.targetAddress.tpgt; 421 } 422 423 if ((status = open_driver(&fd))) { 424 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 425 } 426 427 if (ioctl(fd, ISCSI_STATIC_SET, &target)) { 428 /* 429 * Encountered problem setting the IP address and port for 430 * the target just added. 431 */ 432 syslog(LOG_USER|LOG_DEBUG, 433 "ISCSI_STATIC_SET ioctl failed, errno: %d", errno); 434 (void) close(fd); 435 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 436 } 437 438 pTargetOid->objectType = IMA_OBJECT_TYPE_TARGET; 439 pTargetOid->ownerId = 1; 440 pTargetOid->objectSequenceNumber = target.te_entry.e_oid; 441 442 (void) close(fd); 443 return (IMA_STATUS_SUCCESS); 444 } 445 446 IMA_API IMA_STATUS SUN_IMA_GetTargetProperties( 447 IMA_OID targetId, 448 SUN_IMA_TARGET_PROPERTIES *pProps 449 ) 450 { 451 int fd; 452 int status; 453 iscsi_property_t prop; 454 455 if ((status = open_driver(&fd))) { 456 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 457 } 458 459 (void) memset(&prop, 0, sizeof (iscsi_property_t)); 460 prop.p_vers = ISCSI_INTERFACE_VERSION; 461 prop.p_oid = (uint32_t)targetId.objectSequenceNumber; 462 463 if (ioctl(fd, ISCSI_TARGET_PROPS_GET, &prop) != 0) { 464 syslog(LOG_USER|LOG_DEBUG, 465 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno); 466 (void) close(fd); 467 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 468 } 469 470 (void) mbstowcs(pProps->imaProps.name, 471 (char *)prop.p_name, IMA_NODE_NAME_LEN); 472 (void) memset(pProps->imaProps.alias, 0, 473 (sizeof (IMA_WCHAR) * SUN_IMA_NODE_ALIAS_LEN)); 474 if (prop.p_alias_len > 0) { 475 (void) mbstowcs(pProps->imaProps.alias, (char *)prop.p_alias, 476 SUN_IMA_NODE_ALIAS_LEN); 477 } 478 479 /* Initialize the discovery method to unknown method. */ 480 pProps->imaProps.discoveryMethodFlags = 481 IMA_TARGET_DISCOVERY_METHOD_UNKNOWN; 482 if (!((prop.p_discovery & iSCSIDiscoveryMethodStatic) ^ 483 iSCSIDiscoveryMethodStatic)) { 484 pProps->imaProps.discoveryMethodFlags |= 485 IMA_TARGET_DISCOVERY_METHOD_STATIC; 486 } 487 488 if (!((prop.p_discovery & iSCSIDiscoveryMethodSLP) ^ 489 iSCSIDiscoveryMethodSLP)) { 490 pProps->imaProps.discoveryMethodFlags |= 491 IMA_TARGET_DISCOVERY_METHOD_SLP; 492 } 493 494 if (!((prop.p_discovery & iSCSIDiscoveryMethodISNS) ^ 495 iSCSIDiscoveryMethodISNS)) { 496 pProps->imaProps.discoveryMethodFlags |= 497 iSCSIDiscoveryMethodISNS; 498 } 499 500 if (!((prop.p_discovery & iSCSIDiscoveryMethodSendTargets) ^ 501 iSCSIDiscoveryMethodSendTargets)) { 502 pProps->imaProps.discoveryMethodFlags |= 503 iSCSIDiscoveryMethodSendTargets; 504 } 505 506 if (prop.p_tpgt_conf == ISCSI_DEFAULT_TPGT) { 507 pProps->defaultTpgtConf = IMA_TRUE; 508 pProps->tpgtConf = 0; 509 } else { 510 pProps->defaultTpgtConf = IMA_FALSE; 511 pProps->tpgtConf = prop.p_tpgt_conf; 512 } 513 514 if (prop.p_tpgt_nego == ISCSI_DEFAULT_TPGT) { 515 pProps->defaultTpgtNego = IMA_TRUE; 516 pProps->tpgtNego = 0; 517 } else { 518 pProps->defaultTpgtNego = IMA_FALSE; 519 pProps->tpgtNego = prop.p_tpgt_nego; 520 } 521 522 bcopy(prop.p_isid, pProps->isid, ISCSI_ISID_LEN); 523 524 (void) close(fd); 525 return (IMA_STATUS_SUCCESS); 526 } 527 528 /* 529 * This function only sets CHAP params since we only support CHAP for now. 530 */ 531 IMA_STATUS SUN_IMA_SetTargetAuthParams( 532 IMA_OID targetOid, 533 IMA_AUTHMETHOD method, 534 const IMA_INITIATOR_AUTHPARMS *pParms 535 ) 536 { 537 int fd; 538 iscsi_chap_props_t chap_p; 539 540 if (method != IMA_AUTHMETHOD_CHAP) 541 return (IMA_ERROR_INVALID_PARAMETER); 542 543 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 544 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 545 ISCSI_DRIVER_DEVCTL, errno); 546 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 547 } 548 549 (void) memset(&chap_p, 0, sizeof (iscsi_chap_props_t)); 550 chap_p.c_vers = ISCSI_INTERFACE_VERSION; 551 chap_p.c_oid = (uint32_t)targetOid.objectSequenceNumber; 552 553 chap_p.c_user_len = 554 pParms->chapParms.nameLength; 555 (void) memcpy(chap_p.c_user, 556 pParms->chapParms.name, chap_p.c_user_len); 557 558 chap_p.c_secret_len = 559 pParms->chapParms.challengeSecretLength; 560 (void) memcpy(chap_p.c_secret, 561 pParms->chapParms.challengeSecret, 562 chap_p.c_secret_len); 563 564 if (ioctl(fd, ISCSI_CHAP_SET, &chap_p) != 0) { 565 syslog(LOG_USER|LOG_DEBUG, 566 "ISCSI_CHAP_SET ioctl failed, errno: %d", errno); 567 (void) close(fd); 568 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 569 } 570 571 return (IMA_STATUS_SUCCESS); 572 } 573 574 IMA_STATUS SUN_IMA_GetTargetAuthMethods( 575 IMA_OID lhbaOid, 576 IMA_OID targetOid, 577 IMA_UINT *pMethodCount, 578 IMA_AUTHMETHOD *pMethodList 579 ) 580 { 581 if (getAuthMethods(targetOid, pMethodCount, pMethodList) 582 != IMA_STATUS_SUCCESS) { 583 return (getAuthMethods(lhbaOid, pMethodCount, pMethodList)); 584 } 585 return (IMA_STATUS_SUCCESS); 586 } 587 588 IMA_STATUS SUN_IMA_SetInitiatorRadiusConfig( 589 IMA_OID lhbaOid, 590 SUN_IMA_RADIUS_CONFIG *config 591 ) 592 { 593 int af; 594 int fd; 595 int status; 596 iscsi_radius_props_t radius; 597 union { 598 struct in_addr u_in4; 599 struct in6_addr u_in6; 600 } radius_in; 601 602 if ((status = open_driver(&fd))) { 603 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 604 } 605 606 (void) memset(&radius, 0, sizeof (iscsi_radius_props_t)); 607 radius.r_vers = ISCSI_INTERFACE_VERSION; 608 radius.r_oid = (uint32_t)lhbaOid.objectSequenceNumber; 609 /* Get first because other data fields may already exist */ 610 if (ioctl(fd, ISCSI_RADIUS_GET, &radius) != 0) { 611 /* EMPTY */ 612 /* It's fine if other data fields are not there. */ 613 } 614 615 if (config->isIpv6 == IMA_TRUE) { 616 af = AF_INET6; 617 } else { 618 af = AF_INET; 619 } 620 621 if (inet_pton(af, config->hostnameIpAddress, &radius_in.u_in4) != 1) { 622 return (IMA_ERROR_INVALID_PARAMETER); 623 } 624 625 switch (af) { 626 case AF_INET: 627 radius.r_addr.u_in4.s_addr = radius_in.u_in4.s_addr; 628 radius.r_insize = sizeof (struct in_addr); 629 break; 630 case AF_INET6: 631 (void) memcpy(radius.r_addr.u_in6.s6_addr, 632 radius_in.u_in6.s6_addr, 16); 633 radius.r_insize = sizeof (struct in6_addr); 634 break; 635 } 636 radius.r_port = config->port; 637 radius.r_radius_config_valid = B_TRUE; 638 /* Allow resetting the RADIUS shared secret to NULL */ 639 if (config->sharedSecretValid == IMA_TRUE) { 640 radius.r_shared_secret_len = config->sharedSecretLength; 641 (void) memset(&radius.r_shared_secret[0], 0, 642 MAX_RAD_SHARED_SECRET_LEN); 643 (void) memcpy(&radius.r_shared_secret[0], config->sharedSecret, 644 config->sharedSecretLength); 645 } 646 647 if (ioctl(fd, ISCSI_RADIUS_SET, &radius) != 0) { 648 syslog(LOG_USER|LOG_DEBUG, 649 "ISCSI_RADIUS_SET ioctl failed, errno: %d", errno); 650 (void) close(fd); 651 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 652 } 653 654 (void) close(fd); 655 return (IMA_STATUS_SUCCESS); 656 } 657 658 IMA_STATUS SUN_IMA_GetInitiatorRadiusConfig( 659 IMA_OID lhbaOid, 660 SUN_IMA_RADIUS_CONFIG *config 661 ) 662 { 663 int af; 664 int fd; 665 int status; 666 iscsi_radius_props_t radius; 667 668 if ((status = open_driver(&fd))) { 669 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 670 } 671 672 (void) memset(&radius, 0, sizeof (iscsi_radius_props_t)); 673 radius.r_vers = ISCSI_INTERFACE_VERSION; 674 radius.r_oid = (uint32_t)lhbaOid.objectSequenceNumber; 675 676 if (ioctl(fd, ISCSI_RADIUS_GET, &radius) != 0) { 677 (void) close(fd); 678 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 679 } 680 681 (void) memset(config, 0, sizeof (SUN_IMA_RADIUS_CONFIG)); 682 if (radius.r_insize == sizeof (struct in_addr)) { 683 /* IPv4 */ 684 af = AF_INET; 685 } else if (radius.r_insize == sizeof (struct in6_addr)) { 686 /* IPv6 */ 687 af = AF_INET6; 688 } else { 689 /* 690 * It's legitimate that the existing RADIUS record does not 691 * have configuration data. 692 */ 693 config->hostnameIpAddress[0] = '\0'; 694 config->port = 0; 695 (void) close(fd); 696 return (IMA_STATUS_SUCCESS); 697 } 698 (void) inet_ntop(af, (void *)&radius.r_addr.u_in4, 699 config->hostnameIpAddress, 256); 700 config->port = radius.r_port; 701 (void) memcpy(config->sharedSecret, &radius.r_shared_secret[0], 702 radius.r_shared_secret_len); 703 config->sharedSecretLength = radius.r_shared_secret_len; 704 config->sharedSecretValid = B_TRUE; 705 706 (void) close(fd); 707 return (IMA_STATUS_SUCCESS); 708 } 709 710 IMA_STATUS SUN_IMA_SetInitiatorRadiusAccess( 711 IMA_OID lhbaOid, 712 IMA_BOOL radiusAccess 713 ) 714 { 715 int fd; 716 int status; 717 iscsi_radius_props_t radius; 718 719 if ((status = open_driver(&fd))) { 720 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 721 } 722 723 (void) memset(&radius, 0, sizeof (iscsi_radius_props_t)); 724 radius.r_vers = ISCSI_INTERFACE_VERSION; 725 radius.r_oid = (uint32_t)lhbaOid.objectSequenceNumber; 726 /* Get first because other data fields may already exist */ 727 if (ioctl(fd, ISCSI_RADIUS_GET, &radius) != 0) { 728 if (radiusAccess == IMA_TRUE) { 729 /* 730 * Cannot enable RADIUS if no RADIUS configuration 731 * can be found. 732 */ 733 syslog(LOG_USER|LOG_DEBUG, 734 "RADIUS config data not found - " 735 "cannot enable RADIUS, errno: %d", errno); 736 (void) close(fd); 737 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 738 } else { 739 /* EMPTY */ 740 /* Otherwise it's fine to disable RADIUS */ 741 } 742 } 743 744 if ((radius.r_insize != sizeof (struct in_addr)) && 745 (radius.r_insize != sizeof (struct in6_addr))) { 746 /* 747 * Cannot enable RADIUS if no RADIUS configuration 748 * can be found. 749 */ 750 if (radiusAccess == IMA_TRUE) { 751 syslog(LOG_USER|LOG_DEBUG, 752 "RADIUS config data not found - " 753 "cannot enable RADIUS"); 754 (void) close(fd); 755 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 756 } 757 } 758 759 radius.r_radius_access = (radiusAccess == IMA_TRUE) ? 760 B_TRUE : B_FALSE; 761 762 if (ioctl(fd, ISCSI_RADIUS_SET, &radius) != 0) { 763 syslog(LOG_USER|LOG_DEBUG, 764 "ISCSI_RADIUS_SET ioctl failed, errno: %d", errno); 765 (void) close(fd); 766 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 767 } 768 769 (void) close(fd); 770 return (IMA_STATUS_SUCCESS); 771 } 772 773 IMA_STATUS SUN_IMA_GetInitiatorRadiusAccess( 774 IMA_OID lhbaOid, 775 IMA_BOOL *radiusAccess 776 ) 777 { 778 int fd; 779 int status; 780 iscsi_radius_props_t radius; 781 782 if ((status = open_driver(&fd))) { 783 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 784 } 785 786 (void) memset(&radius, 0, sizeof (iscsi_radius_props_t)); 787 radius.r_vers = ISCSI_INTERFACE_VERSION; 788 radius.r_oid = (uint32_t)lhbaOid.objectSequenceNumber; 789 790 if (ioctl(fd, ISCSI_RADIUS_GET, &radius) != 0) { 791 (void) close(fd); 792 if (errno == ENOENT) { 793 return (IMA_ERROR_OBJECT_NOT_FOUND); 794 } else { 795 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 796 } 797 } 798 799 *radiusAccess = (radius.r_radius_access == B_TRUE) ? 800 IMA_TRUE : IMA_FALSE; 801 802 (void) close(fd); 803 return (IMA_STATUS_SUCCESS); 804 } 805 806 IMA_STATUS SUN_IMA_SendTargets( 807 IMA_NODE_NAME nodeName, 808 IMA_TARGET_ADDRESS address, 809 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES **ppList 810 ) 811 { 812 char *colonPos; 813 char discAddrStr[256]; 814 char nodeNameStr[ISCSI_MAX_NAME_LEN]; 815 int fd; 816 int ctr; 817 int stl_sz; 818 int status; 819 iscsi_sendtgts_list_t *stl_hdr = NULL; 820 IMA_BOOL retry = IMA_TRUE; 821 /* LINTED */ 822 IMA_IP_ADDRESS *ipAddr; 823 824 #define SENDTGTS_DEFAULT_NUM_TARGETS 10 825 826 stl_sz = sizeof (*stl_hdr) + ((SENDTGTS_DEFAULT_NUM_TARGETS - 1) * 827 sizeof (iscsi_sendtgts_entry_t)); 828 stl_hdr = (iscsi_sendtgts_list_t *)calloc(1, stl_sz); 829 if (stl_hdr == NULL) { 830 return (IMA_ERROR_INSUFFICIENT_MEMORY); 831 } 832 stl_hdr->stl_entry.e_vers = ISCSI_INTERFACE_VERSION; 833 stl_hdr->stl_in_cnt = SENDTGTS_DEFAULT_NUM_TARGETS; 834 835 (void) wcstombs(nodeNameStr, nodeName, ISCSI_MAX_NAME_LEN); 836 837 colonPos = strchr(discAddrStr, ':'); 838 if (colonPos == NULL) { 839 /* IPv4 */ 840 stl_hdr->stl_entry.e_insize = sizeof (struct in_addr); 841 } else { 842 /* IPv6 */ 843 stl_hdr->stl_entry.e_insize = sizeof (struct in6_addr); 844 } 845 846 ipAddr = &address.hostnameIpAddress.id.ipAddress; 847 848 bcopy(address.hostnameIpAddress.id.ipAddress.ipAddress, 849 &stl_hdr->stl_entry.e_u, sizeof (ipAddr->ipAddress)); 850 851 stl_hdr->stl_entry.e_port = address.portNumber; 852 853 if ((status = open_driver(&fd))) { 854 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 855 } 856 857 retry_sendtgts: 858 /* 859 * Issue ioctl to obtain the SendTargets list 860 */ 861 if (ioctl(fd, ISCSI_SENDTGTS_GET, stl_hdr) != 0) { 862 syslog(LOG_USER|LOG_DEBUG, 863 "ISCSI_SENDTGTS_GET ioctl failed, errno: %d", errno); 864 (void) close(fd); 865 free(stl_hdr); 866 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 867 } 868 869 /* check if all targets received */ 870 if (stl_hdr->stl_in_cnt < stl_hdr->stl_out_cnt) { 871 if (retry == IMA_TRUE) { 872 stl_sz = sizeof (*stl_hdr) + 873 ((stl_hdr->stl_out_cnt - 1) * 874 sizeof (iscsi_sendtgts_entry_t)); 875 stl_hdr = (iscsi_sendtgts_list_t *) 876 realloc(stl_hdr, stl_sz); 877 if (stl_hdr == NULL) { 878 (void) close(fd); 879 return (IMA_ERROR_INSUFFICIENT_MEMORY); 880 } 881 stl_hdr->stl_in_cnt = stl_hdr->stl_out_cnt; 882 retry = IMA_FALSE; 883 goto retry_sendtgts; 884 } else { 885 /* 886 * don't retry after 2 attempts. The target list 887 * shouldn't continue to growing. Justs continue 888 * on and display what was found. 889 */ 890 syslog(LOG_USER|LOG_DEBUG, 891 "ISCSI_SENDTGTS_GET overflow: " 892 "failed to obtain all targets"); 893 stl_hdr->stl_out_cnt = stl_hdr->stl_in_cnt; 894 } 895 } 896 897 (void) close(fd); 898 899 /* allocate for caller return buffer */ 900 *ppList = (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *)calloc(1, 901 sizeof (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES) + 902 stl_hdr->stl_out_cnt * sizeof (SUN_IMA_DISC_ADDRESS_KEY)); 903 if (*ppList == NULL) { 904 free(stl_hdr); 905 return (IMA_ERROR_INSUFFICIENT_MEMORY); 906 } 907 908 (*ppList)->keyCount = stl_hdr->stl_out_cnt; 909 910 for (ctr = 0; ctr < stl_hdr->stl_out_cnt; ctr++) { 911 (void) mbstowcs((*ppList)->keys[ctr].name, 912 (char *)stl_hdr->stl_list[ctr].ste_name, 913 IMA_NODE_NAME_LEN); 914 915 (*ppList)->keys[ctr].tpgt = stl_hdr->stl_list[ctr].ste_tpgt; 916 917 (*ppList)->keys[ctr].address.portNumber = 918 stl_hdr->stl_list[ctr].ste_ipaddr.a_port; 919 920 if (stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize == 921 sizeof (struct in_addr)) { 922 (*ppList)->keys[ctr].address.ipAddress.ipv4Address = 923 IMA_TRUE; 924 } else if (stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize == 925 sizeof (struct in6_addr)) { 926 (*ppList)->keys[ctr].address.ipAddress.ipv4Address = 927 IMA_FALSE; 928 } else { 929 free(stl_hdr); 930 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 931 } 932 933 (void) memcpy(&(*ppList)->keys[ctr].address.ipAddress.ipAddress, 934 &(stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_addr), 935 stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize); 936 } 937 free(stl_hdr); 938 939 return (IMA_STATUS_SUCCESS); 940 } 941 942 IMA_STATUS SUN_IMA_SetTargetBidirAuthFlag( 943 IMA_OID targetOid, 944 IMA_BOOL *bidirAuthFlag 945 ) 946 { 947 int fd; 948 int status; 949 iscsi_auth_props_t auth; 950 951 if ((status = open_driver(&fd))) { 952 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 953 } 954 955 (void) memset(&auth, 0, sizeof (iscsi_auth_props_t)); 956 auth.a_vers = ISCSI_INTERFACE_VERSION; 957 auth.a_oid = (uint32_t)targetOid.objectSequenceNumber; 958 /* Get first because other data fields may already exist */ 959 if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) { 960 /* EMPTY */ 961 /* It is fine if there is no other data fields. */ 962 } 963 auth.a_bi_auth = (*bidirAuthFlag == IMA_TRUE) ? B_TRUE : B_FALSE; 964 if (ioctl(fd, ISCSI_AUTH_SET, &auth) != 0) { 965 syslog(LOG_USER|LOG_DEBUG, 966 "ISCSI_AUTH_SET ioctl failed, errno: %d", errno); 967 (void) close(fd); 968 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 969 } 970 971 (void) close(fd); 972 return (IMA_STATUS_SUCCESS); 973 } 974 975 IMA_STATUS SUN_IMA_GetTargetBidirAuthFlag( 976 IMA_OID targetOid, 977 IMA_BOOL *bidirAuthFlag 978 ) 979 { 980 int fd; 981 int status; 982 iscsi_auth_props_t auth; 983 984 if ((status = open_driver(&fd))) { 985 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 986 } 987 988 (void) memset(&auth, 0, sizeof (iscsi_auth_props_t)); 989 auth.a_vers = ISCSI_INTERFACE_VERSION; 990 auth.a_oid = (uint32_t)targetOid.objectSequenceNumber; 991 992 if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) { 993 (void) close(fd); 994 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 995 } 996 997 *bidirAuthFlag = (auth.a_bi_auth == B_TRUE) ? 998 IMA_TRUE : IMA_FALSE; 999 1000 (void) close(fd); 1001 return (IMA_STATUS_SUCCESS); 1002 } 1003 1004 IMA_STATUS SUN_IMA_CreateTargetOid( 1005 IMA_NODE_NAME targetName, 1006 IMA_OID *targetOid 1007 ) 1008 { 1009 int fd; 1010 int status; 1011 iscsi_oid_t oid; 1012 1013 if ((status = open_driver(&fd))) { 1014 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 1015 } 1016 1017 (void) memset(&oid, 0, sizeof (iscsi_oid_t)); 1018 (void) wcstombs((char *)oid.o_name, targetName, ISCSI_MAX_NAME_LEN); 1019 oid.o_tpgt = ISCSI_DEFAULT_TPGT; 1020 oid.o_vers = ISCSI_INTERFACE_VERSION; 1021 if (ioctl(fd, ISCSI_CREATE_OID, &oid) == -1) { 1022 syslog(LOG_USER|LOG_DEBUG, 1023 "ISCSI_CREATE_OID ioctl failed, errno: %d", errno); 1024 (void) close(fd); 1025 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1026 } 1027 1028 targetOid->objectType = IMA_OBJECT_TYPE_TARGET; 1029 targetOid->ownerId = 1; 1030 targetOid->objectSequenceNumber = oid.o_oid; 1031 1032 (void) close(fd); 1033 return (IMA_STATUS_SUCCESS); 1034 } 1035 1036 IMA_STATUS SUN_IMA_RemoveTargetParam( 1037 IMA_OID targetOid 1038 ) 1039 { 1040 entry_t entry; 1041 int fd; 1042 int status; 1043 iscsi_auth_props_t auth_p; 1044 iscsi_chap_props_t chap_p; 1045 1046 if ((status = open_driver(&fd))) { 1047 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 1048 } 1049 1050 (void) memset(&entry, 0, sizeof (entry_t)); 1051 entry.e_vers = ISCSI_INTERFACE_VERSION; 1052 entry.e_oid = (uint32_t)targetOid.objectSequenceNumber; 1053 if (ioctl(fd, ISCSI_TARGET_PARAM_CLEAR, &entry)) { 1054 /* 1055 * It could be that the target exists but the associated 1056 * target_param does not, and that is legitimate. 1057 */ 1058 syslog(LOG_USER|LOG_DEBUG, 1059 "ISCSI_TARGET_PARAM_CLEAR ioctl failed, errno: %d", errno); 1060 } 1061 1062 /* Issue ISCSI_CHAP_CLEAR ioctl */ 1063 (void) memset(&chap_p, 0, sizeof (iscsi_chap_props_t)); 1064 chap_p.c_vers = ISCSI_INTERFACE_VERSION; 1065 chap_p.c_oid = (uint32_t)targetOid.objectSequenceNumber; 1066 if (ioctl(fd, ISCSI_CHAP_CLEAR, &chap_p) != 0) { 1067 /* 1068 * It could be that the CHAP of this target has never 1069 * been set. 1070 */ 1071 syslog(LOG_USER|LOG_DEBUG, 1072 "ISCSI_CHAP_CLEAR ioctl failed, errno: %d", errno); 1073 } 1074 1075 /* 1076 * Issue ISCSI_AUTH_CLEAR ioctl, in which the authentication information 1077 * is removed and the target that is not discovered by initiator 1078 * is removed from the memory. So this ioctl should be called at last 1079 */ 1080 (void) memset(&auth_p, 0, sizeof (iscsi_auth_props_t)); 1081 auth_p.a_vers = ISCSI_INTERFACE_VERSION; 1082 auth_p.a_oid = (uint32_t)targetOid.objectSequenceNumber; 1083 if (ioctl(fd, ISCSI_AUTH_CLEAR, &auth_p) != 0) { 1084 /* 1085 * It could be that the auth data of this target has 1086 * never been set. 1087 */ 1088 syslog(LOG_USER|LOG_DEBUG, 1089 "ISCSI_AUTH_CLEAR ioctl failed, errno: %d", errno); 1090 } 1091 1092 (void) close(fd); 1093 return (IMA_STATUS_SUCCESS); 1094 } 1095 1096 IMA_API IMA_STATUS SUN_IMA_SetHeaderDigest( 1097 IMA_OID oid, 1098 IMA_UINT algorithmCount, 1099 const SUN_IMA_DIGEST_ALGORITHM *algorithmList 1100 ) 1101 { 1102 IMA_MIN_MAX_VALUE mv; 1103 uint32_t digest_algorithm; 1104 1105 /* We only support one preference of digest algorithm. */ 1106 if (algorithmCount > 1) { 1107 syslog(LOG_USER|LOG_DEBUG, 1108 "More than one digest algorithm specified."); 1109 return (IMA_ERROR_NOT_SUPPORTED); 1110 } 1111 switch (algorithmList[0]) { 1112 case SUN_IMA_DIGEST_NONE: 1113 digest_algorithm = ISCSI_DIGEST_NONE; 1114 break; 1115 case SUN_IMA_DIGEST_CRC32: 1116 digest_algorithm = ISCSI_DIGEST_CRC32C; 1117 break; 1118 default: 1119 digest_algorithm = ISCSI_DIGEST_NONE; 1120 break; 1121 } 1122 mv.currentValue = digest_algorithm; 1123 return (setISCSINodeParameter(MIN_MAX_PARAM, &oid, &mv, 1124 ISCSI_LOGIN_PARAM_HEADER_DIGEST)); 1125 } 1126 1127 IMA_API IMA_STATUS SUN_IMA_SetDataDigest( 1128 IMA_OID oid, 1129 IMA_UINT algorithmCount, 1130 const SUN_IMA_DIGEST_ALGORITHM *algorithmList 1131 ) 1132 { 1133 IMA_MIN_MAX_VALUE mv; 1134 uint32_t digest_algorithm; 1135 1136 /* We only support one preference of digest algorithm. */ 1137 if (algorithmCount > 1) { 1138 syslog(LOG_USER|LOG_DEBUG, 1139 "More than one digest algorithm specified."); 1140 return (IMA_ERROR_NOT_SUPPORTED); 1141 } 1142 switch (algorithmList[0]) { 1143 case SUN_IMA_DIGEST_NONE: 1144 digest_algorithm = ISCSI_DIGEST_NONE; 1145 break; 1146 case SUN_IMA_DIGEST_CRC32: 1147 digest_algorithm = ISCSI_DIGEST_CRC32C; 1148 break; 1149 default: 1150 digest_algorithm = ISCSI_DIGEST_NONE; 1151 break; 1152 } 1153 mv.currentValue = digest_algorithm; 1154 return (setISCSINodeParameter(MIN_MAX_PARAM, &oid, &mv, 1155 ISCSI_LOGIN_PARAM_DATA_DIGEST)); 1156 } 1157 1158 IMA_API IMA_STATUS SUN_IMA_GetHeaderDigest( 1159 IMA_OID oid, 1160 SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm 1161 ) 1162 { 1163 return (getDigest(oid, ISCSI_LOGIN_PARAM_HEADER_DIGEST, algorithm)); 1164 } 1165 1166 IMA_API IMA_STATUS SUN_IMA_GetDataDigest( 1167 IMA_OID oid, 1168 SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm 1169 ) 1170 { 1171 return (getDigest(oid, ISCSI_LOGIN_PARAM_DATA_DIGEST, algorithm)); 1172 } 1173 1174 IMA_STATUS SUN_IMA_GetLuProperties( 1175 IMA_OID luId, 1176 SUN_IMA_LU_PROPERTIES *pProps 1177 ) 1178 { 1179 IMA_STATUS status; 1180 iscsi_lun_list_t *pLunList; 1181 int j; 1182 IMA_BOOL lunMatch = IMA_FALSE; 1183 int fd; 1184 int openStatus; 1185 iscsi_lun_props_t lun; 1186 di_devlink_handle_t hdl; 1187 1188 if (luId.objectType != IMA_OBJECT_TYPE_LU) { 1189 return (IMA_ERROR_INCORRECT_OBJECT_TYPE); 1190 } 1191 1192 /* 1193 * get list of lun oids for all targets 1194 */ 1195 status = get_target_lun_oid_list(NULL, &pLunList); 1196 if (!IMA_SUCCESS(status)) { 1197 return (status); 1198 } 1199 for (j = 0; j < pLunList->ll_out_cnt; j++) { 1200 /* 1201 * for each lun, check if match is found 1202 */ 1203 if (pLunList->ll_luns[j].l_oid == luId.objectSequenceNumber) { 1204 /* 1205 * match found, break out of lun loop 1206 */ 1207 lunMatch = IMA_TRUE; 1208 break; 1209 } 1210 } 1211 1212 if (lunMatch == IMA_TRUE) { 1213 (void) memset(&lun, 0, sizeof (iscsi_lun_props_t)); 1214 lun.lp_vers = ISCSI_INTERFACE_VERSION; 1215 lun.lp_tgt_oid = pLunList->ll_luns[j].l_tgt_oid; 1216 lun.lp_oid = pLunList->ll_luns[j].l_oid; 1217 } 1218 1219 free(pLunList); 1220 1221 if (lunMatch == IMA_FALSE) { 1222 return (IMA_ERROR_OBJECT_NOT_FOUND); 1223 } 1224 1225 /* 1226 * get lun properties 1227 */ 1228 if ((openStatus = open_driver(&fd))) { 1229 return (SUN_IMA_ERROR_SYSTEM_ERROR | openStatus); 1230 } 1231 1232 if (ioctl(fd, ISCSI_LUN_PROPS_GET, &lun)) { 1233 syslog(LOG_USER|LOG_DEBUG, 1234 "ISCSI_LUN_PROPS_GET ioctl failed, errno: %d", errno); 1235 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1236 } 1237 1238 (void) close(fd); 1239 1240 /* 1241 * set property values 1242 */ 1243 pProps->imaProps.associatedTargetOid.objectType = 1244 IMA_OBJECT_TYPE_TARGET; 1245 pProps->imaProps.associatedTargetOid.ownerId = 1; 1246 pProps->imaProps.associatedTargetOid.objectSequenceNumber = lun.lp_oid; 1247 pProps->imaProps.targetLun = (IMA_UINT64)lun.lp_num; 1248 (void) strncpy(pProps->vendorId, lun.lp_vid, SUN_IMA_LU_VENDOR_ID_LEN); 1249 (void) strncpy(pProps->productId, lun.lp_pid, 1250 SUN_IMA_LU_PRODUCT_ID_LEN); 1251 /* 1252 * lun.lp_status is defined as 1253 * LunValid = 0 1254 * LunDoesNotExist = 1 1255 * IMA_LU_PROPS.exposedtoOS is defined as an IMA_BOOL 1256 * IMA_TRUE = 1 1257 * IMA_FALSE = 0 1258 */ 1259 pProps->imaProps.exposedToOs = !lun.lp_status; 1260 if (gmtime_r(&lun.lp_time_online, &pProps->imaProps.timeExposedToOs) 1261 == NULL) { 1262 (void) memset(&pProps->imaProps.timeExposedToOs, 0, 1263 sizeof (pProps->imaProps.timeExposedToOs)); 1264 } 1265 1266 if (lun.lp_status == LunValid) { 1267 1268 /* add minor device delimiter */ 1269 (void) strcat(lun.lp_pathname, ":"); 1270 1271 if ((strstr(lun.lp_pathname, "sd@") != NULL) || 1272 (strstr(lun.lp_pathname, "ssd@") != NULL) || 1273 (strstr(lun.lp_pathname, "disk@") != NULL)) { 1274 /* 1275 * modify returned pathname to obtain the 2nd slice 1276 * of the raw disk 1277 */ 1278 (void) strcat(lun.lp_pathname, "c,raw"); 1279 } 1280 1281 /* 1282 * Pathname returned by driver is the physical device path. 1283 * This name needs to be converted to the OS device name. 1284 */ 1285 if (hdl = di_devlink_init(lun.lp_pathname, DI_MAKE_LINK)) { 1286 pProps->imaProps.osDeviceName[0] = L'\0'; 1287 (void) di_devlink_walk(hdl, NULL, lun.lp_pathname, 1288 DI_PRIMARY_LINK, 1289 (void *)pProps->imaProps.osDeviceName, 1290 get_lun_devlink); 1291 if (pProps->imaProps.osDeviceName[0] != L'\0') { 1292 /* OS device name synchronously made */ 1293 pProps->imaProps.osDeviceNameValid = IMA_TRUE; 1294 } else { 1295 pProps->imaProps.osDeviceNameValid = IMA_FALSE; 1296 } 1297 1298 (void) di_devlink_fini(&hdl); 1299 1300 } else { 1301 pProps->imaProps.osDeviceNameValid = IMA_FALSE; 1302 } 1303 1304 } else { 1305 pProps->imaProps.osDeviceNameValid = IMA_FALSE; 1306 } 1307 1308 pProps->imaProps.osParallelIdsValid = IMA_FALSE; 1309 1310 return (IMA_STATUS_SUCCESS); 1311 } 1312 1313 #define IMA_DISK_DEVICE_NAME_PREFIX "/dev/rdsk/" 1314 #define IMA_TAPE_DEVICE_NAME_PREFIX "/dev/rmt/" 1315 1316 static int 1317 get_lun_devlink(di_devlink_t link, void *osDeviceName) 1318 { 1319 if ((strncmp(IMA_DISK_DEVICE_NAME_PREFIX, di_devlink_path(link), 1320 strlen(IMA_DISK_DEVICE_NAME_PREFIX)) == 0) || 1321 (strncmp(IMA_TAPE_DEVICE_NAME_PREFIX, di_devlink_path(link), 1322 strlen(IMA_TAPE_DEVICE_NAME_PREFIX)) == 0)) { 1323 (void) mbstowcs((wchar_t *)osDeviceName, di_devlink_path(link), 1324 MAXPATHLEN); 1325 return (DI_WALK_TERMINATE); 1326 } 1327 1328 return (DI_WALK_CONTINUE); 1329 } 1330 1331 /* 1332 * SUN_IMA_GetConnectionOidList - 1333 * 1334 * Non-IMA defined function. 1335 */ 1336 IMA_API IMA_STATUS SUN_IMA_GetConnOidList( 1337 IMA_OID *oid, 1338 IMA_OID_LIST **ppList 1339 ) 1340 { 1341 IMA_STATUS imaStatus; 1342 IMA_OID_LIST *imaOidList; 1343 iscsi_conn_list_t *iscsiConnList = NULL; 1344 int i; 1345 size_t allocLen; 1346 1347 if ((lhbaObjectId.objectType == oid->objectType) && 1348 (lhbaObjectId.ownerId == oid->ownerId) && 1349 (lhbaObjectId.objectSequenceNumber == oid->objectSequenceNumber)) { 1350 imaStatus = getConnOidList(NULL, &iscsiConnList); 1351 } else { 1352 if (oid->objectType == IMA_OBJECT_TYPE_TARGET) { 1353 imaStatus = getConnOidList(oid, &iscsiConnList); 1354 } else { 1355 return (IMA_ERROR_INCORRECT_OBJECT_TYPE); 1356 } 1357 } 1358 if (imaStatus != IMA_STATUS_SUCCESS) { 1359 return (imaStatus); 1360 } 1361 1362 /* 1363 * Based on the results a SUN_IMA_CONN_LIST structure is allocated. 1364 */ 1365 allocLen = iscsiConnList->cl_out_cnt * sizeof (IMA_OID); 1366 allocLen += sizeof (IMA_OID_LIST) - sizeof (IMA_OID); 1367 imaOidList = (IMA_OID_LIST *)calloc(1, allocLen); 1368 1369 if (imaOidList == NULL) { 1370 free(iscsiConnList); 1371 return (IMA_ERROR_INSUFFICIENT_MEMORY); 1372 } 1373 1374 /* The data is transfered from iscsiConnList to imaConnList. */ 1375 imaOidList->oidCount = iscsiConnList->cl_out_cnt; 1376 for (i = 0; i < iscsiConnList->cl_out_cnt; i++) { 1377 imaOidList->oids[i].objectType = SUN_IMA_OBJECT_TYPE_CONN; 1378 imaOidList->oids[i].ownerId = 1; 1379 imaOidList->oids[i].objectSequenceNumber = 1380 iscsiConnList->cl_list[i].c_oid; 1381 } 1382 /* The pointer to the SUN_IMA_CONN_LIST structure is returned. */ 1383 *ppList = imaOidList; 1384 1385 free(iscsiConnList); 1386 return (IMA_STATUS_SUCCESS); 1387 } 1388 1389 /* 1390 * SUN_IMA_GetConnProperties - 1391 * 1392 * Non-IMA defined function. 1393 */ 1394 IMA_API IMA_STATUS SUN_IMA_GetConnProperties( 1395 IMA_OID *connOid, 1396 SUN_IMA_CONN_PROPERTIES **pProps 1397 ) 1398 { 1399 iscsi_conn_list_t *pConnList; 1400 iscsi_conn_props_t *pConnProps; 1401 /* LINTED */ 1402 struct sockaddr_in6 *addrIn6; 1403 /* LINTED */ 1404 struct sockaddr_in *addrIn; 1405 SUN_IMA_CONN_PROPERTIES *pImaConnProps; 1406 IMA_STATUS imaStatus; 1407 int i; 1408 1409 /* If there is any error *pProps should be set to NULL */ 1410 *pProps = NULL; 1411 1412 pImaConnProps = (SUN_IMA_CONN_PROPERTIES *)calloc(1, 1413 sizeof (SUN_IMA_CONN_PROPERTIES)); 1414 1415 if (pImaConnProps == NULL) { 1416 return (IMA_ERROR_INSUFFICIENT_MEMORY); 1417 } 1418 1419 imaStatus = getConnOidList(NULL, &pConnList); 1420 1421 if (imaStatus != IMA_STATUS_SUCCESS) { 1422 free(pImaConnProps); 1423 return (imaStatus); 1424 } 1425 1426 /* 1427 * Walk the list returned to find our connection. 1428 */ 1429 for (i = 0; i < pConnList->cl_out_cnt; i++) { 1430 1431 if (pConnList->cl_list[i].c_oid == 1432 (uint32_t)connOid->objectSequenceNumber) { 1433 1434 /* This is our connection. */ 1435 imaStatus = getConnProps(&pConnList->cl_list[i], 1436 &pConnProps); 1437 1438 if (imaStatus != IMA_STATUS_SUCCESS) { 1439 free(pConnList); 1440 free(pImaConnProps); 1441 return (imaStatus); 1442 } 1443 pImaConnProps->connectionID = pConnProps->cp_cid; 1444 1445 /* 1446 * Local Propeties 1447 */ 1448 if (pConnProps->cp_local.soa4.sin_family == AF_INET) { 1449 1450 pImaConnProps->local.ipAddress.ipv4Address = 1451 IMA_TRUE; 1452 pImaConnProps->local.portNumber = 1453 pConnProps->cp_local.soa4.sin_port; 1454 addrIn = &(pConnProps->cp_local.soa4); 1455 bcopy(&pConnProps->cp_local.soa4.sin_addr, 1456 pImaConnProps->local.ipAddress.ipAddress, 1457 sizeof (addrIn->sin_addr)); 1458 1459 } else { 1460 pImaConnProps->local.ipAddress.ipv4Address = 1461 IMA_FALSE; 1462 pImaConnProps->local.portNumber = 1463 pConnProps->cp_local.soa6.sin6_port; 1464 addrIn6 = &(pConnProps->cp_local.soa6); 1465 bcopy(&pConnProps->cp_local.soa6.sin6_addr, 1466 pImaConnProps->local.ipAddress.ipAddress, 1467 sizeof (addrIn6->sin6_addr)); 1468 1469 } 1470 1471 /* 1472 * Peer Propeties 1473 */ 1474 if (pConnProps->cp_peer.soa4.sin_family == AF_INET) { 1475 1476 pImaConnProps->peer.ipAddress.ipv4Address = 1477 IMA_TRUE; 1478 pImaConnProps->peer.portNumber = 1479 pConnProps->cp_peer.soa4.sin_port; 1480 addrIn = &(pConnProps->cp_local.soa4); 1481 bcopy(&pConnProps->cp_peer.soa4.sin_addr, 1482 pImaConnProps->peer.ipAddress.ipAddress, 1483 sizeof (addrIn->sin_addr)); 1484 1485 } else { 1486 pImaConnProps->peer.ipAddress.ipv4Address = 1487 IMA_FALSE; 1488 pImaConnProps->peer.portNumber = 1489 pConnProps->cp_peer.soa6.sin6_port; 1490 1491 addrIn6 = &pConnProps->cp_local.soa6; 1492 bcopy(&pConnProps->cp_peer.soa6.sin6_addr, 1493 pImaConnProps->peer.ipAddress.ipAddress, 1494 sizeof (addrIn6->sin6_addr)); 1495 } 1496 1497 1498 pImaConnProps->valuesValid = 1499 pConnProps->cp_params_valid; 1500 pImaConnProps->defaultTime2Retain = 1501 pConnProps->cp_params.default_time_to_retain; 1502 pImaConnProps->defaultTime2Wait = 1503 pConnProps->cp_params.default_time_to_wait; 1504 pImaConnProps->errorRecoveryLevel = 1505 pConnProps->cp_params.error_recovery_level; 1506 pImaConnProps->firstBurstLength = 1507 pConnProps->cp_params.first_burst_length; 1508 pImaConnProps->maxBurstLength = 1509 pConnProps->cp_params.max_burst_length; 1510 pImaConnProps->maxConnections = 1511 pConnProps->cp_params.max_connections; 1512 pImaConnProps->maxOutstandingR2T = 1513 pConnProps->cp_params.max_outstanding_r2t; 1514 pImaConnProps->maxRecvDataSegmentLength = 1515 pConnProps->cp_params.max_recv_data_seg_len; 1516 1517 pImaConnProps->dataPduInOrder = 1518 pConnProps->cp_params.data_pdu_in_order; 1519 pImaConnProps->dataSequenceInOrder = 1520 pConnProps->cp_params.data_sequence_in_order; 1521 pImaConnProps->immediateData = 1522 pConnProps->cp_params.immediate_data; 1523 pImaConnProps->initialR2T = 1524 pConnProps->cp_params.initial_r2t; 1525 1526 pImaConnProps->headerDigest = 1527 pConnProps->cp_params.header_digest; 1528 pImaConnProps->dataDigest = 1529 pConnProps->cp_params.data_digest; 1530 1531 free(pConnProps); 1532 break; 1533 } 1534 } 1535 free(pConnList); 1536 *pProps = pImaConnProps; 1537 return (IMA_STATUS_SUCCESS); 1538 } 1539 1540 1541 /* 1542 * SUN_IMA_GetConfigSessions - 1543 * 1544 * Non-IMA defined function. 1545 */ 1546 IMA_API IMA_STATUS SUN_IMA_GetConfigSessions( 1547 IMA_OID targetOid, 1548 SUN_IMA_CONFIG_SESSIONS **pConfigSessions 1549 ) 1550 { 1551 int fd; 1552 int status; 1553 iscsi_config_sess_t *ics; 1554 int size, idx; 1555 1556 /* Allocate and setup initial buffer */ 1557 size = sizeof (*ics); 1558 ics = (iscsi_config_sess_t *)calloc(1, size); 1559 if (ics == NULL) { 1560 return (IMA_ERROR_INSUFFICIENT_MEMORY); 1561 } 1562 ics->ics_ver = ISCSI_INTERFACE_VERSION; 1563 ics->ics_oid = targetOid.objectSequenceNumber; 1564 ics->ics_in = 1; 1565 1566 /* Open driver devctl for ioctl */ 1567 if ((status = open_driver(&fd))) { 1568 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 1569 } 1570 1571 /* Issue ioctl request */ 1572 if (ioctl(fd, ISCSI_GET_CONFIG_SESSIONS, ics) != 0) { 1573 syslog(LOG_USER|LOG_DEBUG, 1574 "ISCSI_GET_CONFIG_SESSIONS ioctl failed, errno: %d", 1575 errno); 1576 (void) close(fd); 1577 free(ics); 1578 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1579 } 1580 1581 /* Check if we need to collect more information */ 1582 idx = ics->ics_out; 1583 if (idx > 1) { 1584 1585 /* Free old buffer and reallocate re-sized buffer */ 1586 free(ics); 1587 size = ISCSI_SESSION_CONFIG_SIZE(idx); 1588 ics = (iscsi_config_sess_t *)calloc(1, size); 1589 if (ics == NULL) { 1590 return (IMA_ERROR_INSUFFICIENT_MEMORY); 1591 } 1592 ics->ics_ver = ISCSI_INTERFACE_VERSION; 1593 ics->ics_oid = targetOid.objectSequenceNumber; 1594 ics->ics_in = idx; 1595 1596 /* Issue ioctl request */ 1597 if (ioctl(fd, ISCSI_GET_CONFIG_SESSIONS, ics) != 0) { 1598 syslog(LOG_USER|LOG_DEBUG, 1599 "ISCSI_GET_CONFIG_SESSIONS ioctl failed, errno: %d", 1600 errno); 1601 (void) close(fd); 1602 free(ics); 1603 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1604 } 1605 } 1606 (void) close(fd); 1607 1608 /* Allocate output buffer */ 1609 size = sizeof (SUN_IMA_CONFIG_SESSIONS) + 1610 ((ics->ics_out - 1) * sizeof (IMA_ADDRESS_KEY)); 1611 *pConfigSessions = (SUN_IMA_CONFIG_SESSIONS *)calloc(1, size); 1612 if ((*pConfigSessions) == NULL) { 1613 return (IMA_ERROR_INSUFFICIENT_MEMORY); 1614 } 1615 1616 /* Copy output information */ 1617 (*pConfigSessions)->bound = 1618 (ics->ics_bound == B_TRUE ? IMA_TRUE : IMA_FALSE); 1619 (*pConfigSessions)->in = ics->ics_in; 1620 (*pConfigSessions)->out = ics->ics_out; 1621 for (idx = 0; idx < ics->ics_in; idx++) { 1622 if (ics->ics_bindings[idx].i_insize == 1623 sizeof (struct in_addr)) { 1624 (*pConfigSessions)->bindings[idx].ipAddress. 1625 ipv4Address = IMA_TRUE; 1626 bcopy(&ics->ics_bindings[idx].i_addr.in4, 1627 (*pConfigSessions)->bindings[idx].ipAddress. 1628 ipAddress, sizeof (struct in_addr)); 1629 } else { 1630 (*pConfigSessions)->bindings[idx].ipAddress. 1631 ipv4Address = IMA_FALSE; 1632 bcopy(&ics->ics_bindings[idx].i_addr.in6, 1633 (*pConfigSessions)->bindings[idx].ipAddress. 1634 ipAddress, sizeof (struct in6_addr)); 1635 } 1636 } 1637 1638 free(ics); 1639 return (IMA_STATUS_SUCCESS); 1640 } 1641 1642 /* 1643 * SUN_IMA_SetConfigSessions - 1644 * 1645 * Non-IMA defined function. 1646 */ 1647 IMA_API IMA_STATUS SUN_IMA_SetConfigSessions( 1648 IMA_OID targetOid, 1649 SUN_IMA_CONFIG_SESSIONS *pConfigSessions 1650 ) 1651 { 1652 int fd; 1653 int status; 1654 iscsi_config_sess_t *ics; 1655 int idx, size; 1656 1657 /* verify allowed range of sessions */ 1658 if ((pConfigSessions->in < ISCSI_MIN_CONFIG_SESSIONS) || 1659 (pConfigSessions->in > ISCSI_MAX_CONFIG_SESSIONS)) { 1660 return (IMA_ERROR_INVALID_PARAMETER); 1661 } 1662 1663 /* allocate record config_sess size */ 1664 size = ISCSI_SESSION_CONFIG_SIZE(pConfigSessions->in); 1665 ics = (iscsi_config_sess_t *)malloc(size); 1666 1667 /* setup config_sess information */ 1668 (void) memset(ics, 0, sizeof (iscsi_config_sess_t)); 1669 ics->ics_ver = ISCSI_INTERFACE_VERSION; 1670 ics->ics_oid = targetOid.objectSequenceNumber; 1671 ics->ics_bound = 1672 (pConfigSessions->bound == IMA_TRUE ? B_TRUE : B_FALSE); 1673 ics->ics_in = pConfigSessions->in; 1674 for (idx = 0; idx < ics->ics_in; idx++) { 1675 if (pConfigSessions->bindings[idx].ipAddress. 1676 ipv4Address == IMA_TRUE) { 1677 ics->ics_bindings[idx].i_insize = 1678 sizeof (struct in_addr); 1679 bcopy(pConfigSessions->bindings[idx]. 1680 ipAddress.ipAddress, 1681 &ics->ics_bindings[idx].i_addr.in4, 1682 sizeof (struct in_addr)); 1683 } else { 1684 ics->ics_bindings[idx].i_insize = 1685 sizeof (struct in6_addr); 1686 bcopy(pConfigSessions->bindings[idx]. 1687 ipAddress.ipAddress, 1688 &ics->ics_bindings[idx].i_addr.in6, 1689 sizeof (struct in6_addr)); 1690 } 1691 } 1692 1693 /* open driver */ 1694 if ((status = open_driver(&fd))) { 1695 free(ics); 1696 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 1697 } 1698 1699 /* issue ioctl request */ 1700 if (ioctl(fd, ISCSI_SET_CONFIG_SESSIONS, ics) != 0) { 1701 syslog(LOG_USER|LOG_DEBUG, 1702 "ISCSI_SET_CONFIG_SESSIONS ioctl failed, errno: %d", 1703 errno); 1704 (void) close(fd); 1705 free(ics); 1706 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1707 } 1708 (void) close(fd); 1709 free(ics); 1710 return (IMA_STATUS_SUCCESS); 1711 } 1712 1713 /* A helper function to obtain iSCSI node parameters. */ 1714 static IMA_STATUS 1715 getISCSINodeParameter( 1716 int paramType, 1717 IMA_OID *oid, 1718 void *pProps, 1719 uint32_t paramIndex 1720 ) 1721 { 1722 int fd; 1723 int status; 1724 iscsi_param_get_t pg; 1725 1726 if ((status = open_driver(&fd))) { 1727 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 1728 } 1729 1730 (void) memset(&pg, 0, sizeof (iscsi_param_get_t)); 1731 pg.g_vers = ISCSI_INTERFACE_VERSION; 1732 pg.g_oid = (uint32_t)oid->objectSequenceNumber; 1733 pg.g_param = paramIndex; 1734 pg.g_param_type = ISCSI_SESS_PARAM; 1735 1736 if (ioctl(fd, ISCSI_PARAM_GET, &pg) != 0) { 1737 syslog(LOG_USER|LOG_DEBUG, 1738 "ISCSI_PARAM_GET ioctl failed, errno: %d", errno); 1739 (void) close(fd); 1740 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1741 } 1742 1743 switch (paramType) { 1744 IMA_BOOL_VALUE *bp; 1745 IMA_MIN_MAX_VALUE *mp; 1746 1747 case MIN_MAX_PARAM: 1748 mp = (IMA_MIN_MAX_VALUE *)pProps; 1749 1750 mp->currentValueValid = 1751 (pg.g_value.v_valid == B_TRUE) ? 1752 IMA_TRUE : IMA_FALSE; 1753 mp->currentValue = pg.g_value.v_integer.i_current; 1754 mp->defaultValue = pg.g_value.v_integer.i_default; 1755 mp->minimumValue = pg.g_value.v_integer.i_min; 1756 mp->maximumValue = pg.g_value.v_integer.i_max; 1757 mp->incrementValue = pg.g_value.v_integer.i_incr; 1758 break; 1759 1760 case BOOL_PARAM: 1761 bp = (IMA_BOOL_VALUE *)pProps; 1762 bp->currentValueValid = 1763 (pg.g_value.v_valid == B_TRUE) ? 1764 IMA_TRUE : IMA_FALSE; 1765 bp->currentValue = pg.g_value.v_bool.b_current; 1766 bp->defaultValue = pg.g_value.v_bool.b_default; 1767 break; 1768 1769 default: 1770 break; 1771 } 1772 1773 /* Issue ISCSI_PARAM_GET ioctl again to obtain connection parameters. */ 1774 pg.g_param_type = ISCSI_CONN_PARAM; 1775 if (ioctl(fd, ISCSI_PARAM_GET, &pg) != 0) { 1776 syslog(LOG_USER|LOG_DEBUG, 1777 "ISCSI_PARAM_GET ioctl failed, errno: %d", errno); 1778 (void) close(fd); 1779 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1780 } 1781 1782 (void) close(fd); 1783 return (IMA_STATUS_SUCCESS); 1784 } 1785 1786 /* A helper function to set iSCSI node parameters. */ 1787 static IMA_STATUS 1788 setISCSINodeParameter( 1789 int paramType, 1790 IMA_OID *oid, 1791 void *pProp, 1792 uint32_t paramIndex 1793 ) 1794 { 1795 int fd; 1796 int status; 1797 iscsi_param_set_t ps; 1798 1799 if ((status = open_driver(&fd))) { 1800 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 1801 } 1802 1803 (void) memset(&ps, 0, sizeof (iscsi_param_set_t)); 1804 ps.s_vers = ISCSI_INTERFACE_VERSION; 1805 ps.s_oid = (uint32_t)oid->objectSequenceNumber; 1806 ps.s_param = paramIndex; 1807 1808 switch (paramType) { 1809 IMA_BOOL_VALUE *bp; 1810 IMA_MIN_MAX_VALUE *mp; 1811 1812 case MIN_MAX_PARAM: 1813 mp = (IMA_MIN_MAX_VALUE *)pProp; 1814 ps.s_value.v_integer = mp->currentValue; 1815 break; 1816 case BOOL_PARAM: 1817 bp = (IMA_BOOL_VALUE *)pProp; 1818 ps.s_value.v_bool = 1819 (bp->currentValue == IMA_TRUE) ? 1820 B_TRUE : B_FALSE; 1821 break; 1822 1823 default: 1824 break; 1825 } 1826 if (ioctl(fd, ISCSI_PARAM_SET, &ps)) { 1827 (void) close(fd); 1828 syslog(LOG_USER|LOG_DEBUG, 1829 "ISCSI_PARAM_SET ioctl failed, errno: %d", errno); 1830 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1831 } 1832 1833 (void) close(fd); 1834 return (IMA_STATUS_SUCCESS); 1835 } 1836 1837 static int 1838 prepare_discovery_entry( 1839 SUN_IMA_TARGET_ADDRESS discoveryAddress, 1840 entry_t *entry 1841 ) 1842 { 1843 return (prepare_discovery_entry_IMA(discoveryAddress.imaStruct, entry)); 1844 } 1845 1846 static int 1847 prepare_discovery_entry_IMA( 1848 IMA_TARGET_ADDRESS discoveryAddress, 1849 entry_t *entry 1850 ) 1851 { 1852 (void) memset(entry, 0, sizeof (entry_t)); 1853 entry->e_vers = ISCSI_INTERFACE_VERSION; 1854 entry->e_oid = ISCSI_OID_NOTSET; 1855 1856 if (discoveryAddress.hostnameIpAddress.id.ipAddress. 1857 ipv4Address == IMA_FALSE) { 1858 1859 bcopy(discoveryAddress.hostnameIpAddress.id.ipAddress. 1860 ipAddress, entry->e_u.u_in6.s6_addr, 1861 sizeof (entry->e_u.u_in6.s6_addr)); 1862 1863 entry->e_insize = sizeof (struct in6_addr); 1864 } else { 1865 1866 bcopy(discoveryAddress.hostnameIpAddress.id.ipAddress. 1867 ipAddress, &entry->e_u.u_in4.s_addr, 1868 sizeof (entry->e_u.u_in4.s_addr)); 1869 1870 entry->e_insize = sizeof (struct in_addr); 1871 } 1872 1873 entry->e_port = discoveryAddress.portNumber; 1874 entry->e_tpgt = 0; 1875 return (DISC_ADDR_OK); 1876 } 1877 1878 static IMA_STATUS configure_discovery_method( 1879 IMA_BOOL enable, 1880 iSCSIDiscoveryMethod_t method 1881 ) 1882 { 1883 int fd, status; 1884 1885 if ((status = open_driver(&fd))) { 1886 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 1887 } 1888 1889 if (enable == IMA_FALSE) { 1890 if (ioctl(fd, ISCSI_DISCOVERY_CLEAR, &method)) { 1891 status = errno; 1892 (void) close(fd); 1893 syslog(LOG_USER|LOG_DEBUG, 1894 "ISCSI_DISCOVERY_CLEAR ioctl failed, errno: %d", 1895 status); 1896 if (status == EBUSY) { 1897 return (IMA_ERROR_LU_IN_USE); 1898 } else { 1899 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1900 } 1901 } 1902 1903 (void) close(fd); 1904 return (IMA_STATUS_SUCCESS); 1905 } else { 1906 /* Set the discovery method */ 1907 if (ioctl(fd, ISCSI_DISCOVERY_SET, &method)) { 1908 status = errno; 1909 (void) close(fd); 1910 syslog(LOG_USER|LOG_DEBUG, 1911 "ISCSI_DISCOVERY_SET ioctl failed, errno: %d", 1912 status); 1913 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1914 } 1915 1916 (void) close(fd); 1917 return (IMA_STATUS_SUCCESS); 1918 } 1919 } 1920 1921 /* LINTED E_STATIC_UNUSED */ 1922 static IMA_BOOL authMethodMatch( 1923 IMA_AUTHMETHOD matchingMethod, 1924 IMA_AUTHMETHOD *methodList, 1925 IMA_UINT maxEntries 1926 ) 1927 { 1928 IMA_UINT i; 1929 1930 for (i = 0; i < maxEntries; i++) { 1931 if (methodList[i] == matchingMethod) { 1932 return (IMA_TRUE); 1933 } 1934 } 1935 1936 return (IMA_FALSE); 1937 } 1938 1939 static IMA_STATUS get_target_oid_list( 1940 uint32_t targetListType, 1941 IMA_OID_LIST **ppList) 1942 { 1943 int fd; 1944 int i; 1945 int target_list_size; 1946 int status; 1947 int out_cnt; 1948 iscsi_target_list_t *idlp; 1949 1950 if ((status = open_driver(&fd))) { 1951 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 1952 } 1953 1954 idlp = (iscsi_target_list_t *)calloc(1, sizeof (iscsi_target_list_t)); 1955 if (idlp == NULL) { 1956 (void) close(fd); 1957 return (IMA_ERROR_INSUFFICIENT_MEMORY); 1958 } 1959 idlp->tl_vers = ISCSI_INTERFACE_VERSION; 1960 idlp->tl_in_cnt = idlp->tl_out_cnt = 1; 1961 idlp->tl_tgt_list_type = targetListType; 1962 1963 /* 1964 * Issue ioctl. Space has been allocted for one entry. 1965 * If more than one entry should be returned, we will re-issue the 1966 * entry with the right amount of space allocted 1967 */ 1968 if (ioctl(fd, ISCSI_TARGET_OID_LIST_GET, idlp) != 0) { 1969 (void) close(fd); 1970 syslog(LOG_USER|LOG_DEBUG, 1971 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d", 1972 targetListType, errno); 1973 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1974 } 1975 if (idlp->tl_out_cnt > 1) { 1976 out_cnt = idlp->tl_out_cnt; 1977 free(idlp); 1978 1979 target_list_size = sizeof (iscsi_target_list_t); 1980 target_list_size += (sizeof (uint32_t) * out_cnt - 1); 1981 idlp = (iscsi_target_list_t *)calloc(1, target_list_size); 1982 if (idlp == NULL) { 1983 (void) close(fd); 1984 return (IMA_ERROR_INSUFFICIENT_MEMORY); 1985 } 1986 idlp->tl_vers = ISCSI_INTERFACE_VERSION; 1987 idlp->tl_in_cnt = out_cnt; 1988 idlp->tl_tgt_list_type = targetListType; 1989 1990 /* Issue the same ioctl again to obtain all the OIDs. */ 1991 if (ioctl(fd, ISCSI_TARGET_OID_LIST_GET, idlp) != 0) { 1992 #define ERROR_STR "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno :%d" 1993 free(idlp); 1994 (void) close(fd); 1995 syslog(LOG_USER|LOG_DEBUG, 1996 ERROR_STR, targetListType, errno); 1997 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1998 #undef ERROR_STR 1999 2000 } 2001 } 2002 2003 *ppList = (IMA_OID_LIST *)calloc(1, sizeof (IMA_OID_LIST) + 2004 idlp->tl_out_cnt * sizeof (IMA_OID)); 2005 (*ppList)->oidCount = idlp->tl_out_cnt; 2006 for (i = 0; i < idlp->tl_out_cnt; i++) { 2007 (*ppList)->oids[i].objectType = IMA_OBJECT_TYPE_TARGET; 2008 (*ppList)->oids[i].ownerId = 1; 2009 (*ppList)->oids[i].objectSequenceNumber = idlp->tl_oid_list[i]; 2010 } 2011 2012 free(idlp); 2013 (void) close(fd); 2014 return (IMA_STATUS_SUCCESS); 2015 } 2016 2017 static IMA_STATUS get_target_lun_oid_list( 2018 IMA_OID * targetOid, 2019 iscsi_lun_list_t **ppLunList) 2020 { 2021 int fd; 2022 iscsi_lun_list_t *illp, *illp_saved; 2023 int lun_list_size; 2024 int status; 2025 2026 if ((status = open_driver(&fd))) { 2027 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 2028 } 2029 2030 illp = (iscsi_lun_list_t *)calloc(1, sizeof (iscsi_lun_list_t)); 2031 if (illp == NULL) { 2032 (void) close(fd); 2033 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2034 } 2035 illp->ll_vers = ISCSI_INTERFACE_VERSION; 2036 if (targetOid == NULL) { 2037 /* get lun oid list for all targets */ 2038 illp->ll_all_tgts = B_TRUE; 2039 } else { 2040 /* get lun oid list for single target */ 2041 illp->ll_all_tgts = B_FALSE; 2042 illp->ll_tgt_oid = (uint32_t)targetOid->objectSequenceNumber; 2043 } 2044 illp->ll_in_cnt = illp->ll_out_cnt = 1; 2045 2046 /* 2047 * Issue ioctl to retrieve the target luns. Space has been allocted 2048 * for one entry. If more than one entry should be returned, we 2049 * will re-issue the entry with the right amount of space allocted 2050 */ 2051 if (ioctl(fd, ISCSI_LUN_OID_LIST_GET, illp) != 0) { 2052 (void) close(fd); 2053 syslog(LOG_USER|LOG_DEBUG, 2054 "ISCSI_LUN_LIST_GET ioctl failed, errno: %d", errno); 2055 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2056 } 2057 2058 if (illp->ll_out_cnt > 1) { 2059 illp_saved = illp; 2060 lun_list_size = sizeof (iscsi_lun_list_t); 2061 lun_list_size += (sizeof (iscsi_if_lun_t) * 2062 (illp->ll_out_cnt - 1)); 2063 illp = (iscsi_lun_list_t *)calloc(1, lun_list_size); 2064 if (illp == NULL) { 2065 (void) close(fd); 2066 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2067 } 2068 illp->ll_vers = ISCSI_INTERFACE_VERSION; 2069 illp->ll_all_tgts = illp_saved->ll_all_tgts; 2070 illp->ll_tgt_oid = illp_saved->ll_tgt_oid; 2071 illp->ll_in_cnt = illp_saved->ll_out_cnt; 2072 2073 free(illp_saved); 2074 2075 /* Issue the same ioctl again to get all the target LUN list */ 2076 if (ioctl(fd, ISCSI_LUN_OID_LIST_GET, illp) != 0) { 2077 free(illp); 2078 (void) close(fd); 2079 syslog(LOG_USER|LOG_DEBUG, 2080 "ISCSI_LUN_LIST_GET ioctl failed, errno: %d", 2081 errno); 2082 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2083 2084 } 2085 } 2086 *ppLunList = illp; 2087 2088 2089 (void) close(fd); 2090 return (IMA_STATUS_SUCCESS); 2091 } 2092 2093 /* A helper function to obtain digest algorithms. */ 2094 static IMA_STATUS 2095 getDigest( 2096 IMA_OID oid, 2097 int ioctlCmd, 2098 SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm 2099 ) 2100 { 2101 IMA_MIN_MAX_VALUE pProps; 2102 IMA_STATUS status; 2103 2104 if ((status = getISCSINodeParameter(MIN_MAX_PARAM, &oid, &pProps, 2105 ioctlCmd)) != IMA_STATUS_SUCCESS) { 2106 return (status); 2107 } 2108 2109 switch (pProps.defaultValue) { 2110 case ISCSI_DIGEST_NONE: 2111 algorithm->defaultAlgorithms[0] = ISCSI_DIGEST_NONE; 2112 algorithm->defaultAlgorithmCount = 1; 2113 break; 2114 case ISCSI_DIGEST_CRC32C: 2115 algorithm->defaultAlgorithms[0] = ISCSI_DIGEST_CRC32C; 2116 algorithm->defaultAlgorithmCount = 1; 2117 break; 2118 2119 case ISCSI_DIGEST_CRC32C_NONE: 2120 algorithm->defaultAlgorithms[0] = ISCSI_DIGEST_CRC32C; 2121 algorithm->defaultAlgorithms[1] = ISCSI_DIGEST_NONE; 2122 algorithm->defaultAlgorithmCount = 2; 2123 break; 2124 case ISCSI_DIGEST_NONE_CRC32C: 2125 algorithm->defaultAlgorithms[0] = ISCSI_DIGEST_NONE; 2126 algorithm->defaultAlgorithms[1] = ISCSI_DIGEST_CRC32C; 2127 algorithm->defaultAlgorithmCount = 2; 2128 break; 2129 default: 2130 /* Error */ 2131 syslog(LOG_USER|LOG_DEBUG, 2132 "Invalid default digest: %d", pProps.defaultValue); 2133 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2134 } 2135 2136 /* The configured value */ 2137 if (pProps.currentValueValid == IMA_TRUE) { 2138 algorithm->currentValid = IMA_TRUE; 2139 2140 switch (pProps.currentValue) { 2141 case ISCSI_DIGEST_NONE: 2142 algorithm->currentAlgorithms[0] = 2143 ISCSI_DIGEST_NONE; 2144 algorithm->currentAlgorithmCount = 1; 2145 break; 2146 case ISCSI_DIGEST_CRC32C: 2147 algorithm->currentAlgorithms[0] = 2148 ISCSI_DIGEST_CRC32C; 2149 algorithm->currentAlgorithmCount = 1; 2150 break; 2151 2152 case ISCSI_DIGEST_CRC32C_NONE: 2153 algorithm->currentAlgorithms[0] = 2154 ISCSI_DIGEST_CRC32C; 2155 algorithm->currentAlgorithms[1] = 2156 ISCSI_DIGEST_NONE; 2157 algorithm->currentAlgorithmCount = 2; 2158 break; 2159 case ISCSI_DIGEST_NONE_CRC32C: 2160 algorithm->currentAlgorithms[0] = 2161 ISCSI_DIGEST_NONE; 2162 algorithm->currentAlgorithms[1] = 2163 ISCSI_DIGEST_CRC32C; 2164 algorithm->currentAlgorithmCount = 2; 2165 break; 2166 default: 2167 /* Error */ 2168 syslog(LOG_USER|LOG_DEBUG, 2169 "Invalid configured digest: %d", 2170 pProps.defaultValue); 2171 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2172 } 2173 2174 } else { 2175 algorithm->currentValid = IMA_FALSE; 2176 } 2177 2178 return (IMA_STATUS_SUCCESS); 2179 } 2180 2181 /* 2182 * getConnOidList - 2183 */ 2184 static IMA_STATUS getConnOidList( 2185 IMA_OID *sessOid, 2186 iscsi_conn_list_t **ppConnList 2187 ) 2188 { 2189 iscsi_conn_list_t *iscsiConnList = NULL; 2190 size_t allocLen; 2191 int fd; 2192 int status; 2193 int out_cnt; 2194 2195 /* Preset it to NULL to prepare for the case of failure */ 2196 *ppConnList = NULL; 2197 2198 /* We try to open the driver now. */ 2199 if ((status = open_driver(&fd))) { 2200 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 2201 } 2202 2203 iscsiConnList = (iscsi_conn_list_t *)calloc(1, 2204 sizeof (iscsi_conn_list_t)); 2205 if (iscsiConnList == NULL) { 2206 (void) close(fd); 2207 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2208 } 2209 iscsiConnList->cl_vers = ISCSI_INTERFACE_VERSION; 2210 iscsiConnList->cl_in_cnt = iscsiConnList->cl_out_cnt = 1; 2211 if (sessOid == NULL) { 2212 iscsiConnList->cl_all_sess = B_TRUE; 2213 } else { 2214 iscsiConnList->cl_all_sess = B_FALSE; 2215 iscsiConnList->cl_sess_oid = 2216 (uint32_t)sessOid->objectSequenceNumber; 2217 } 2218 /* 2219 * Issue ioctl to retrieve the connection OIDs. Space has been 2220 * allocated for one entry. If more than one entry should be 2221 * returned, we will re-issue the entry with the right amount of 2222 * space allocted 2223 */ 2224 if (ioctl(fd, ISCSI_CONN_OID_LIST_GET, iscsiConnList) != 0) { 2225 syslog(LOG_USER|LOG_DEBUG, 2226 "ISCSI_CONN_OID_LIST_GET ioctl failed, errno: %d", errno); 2227 *ppConnList = NULL; 2228 (void) close(fd); 2229 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2230 } 2231 if (iscsiConnList->cl_out_cnt > 1) { 2232 out_cnt = iscsiConnList->cl_out_cnt; 2233 free(iscsiConnList); 2234 2235 allocLen = sizeof (iscsi_conn_list_t); 2236 allocLen += (sizeof (iscsi_if_conn_t) * out_cnt - 1); 2237 iscsiConnList = (iscsi_conn_list_t *)calloc(1, allocLen); 2238 if (iscsiConnList == NULL) { 2239 *ppConnList = NULL; 2240 (void) close(fd); 2241 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2242 } 2243 iscsiConnList->cl_vers = ISCSI_INTERFACE_VERSION; 2244 iscsiConnList->cl_in_cnt = out_cnt; 2245 if (sessOid == NULL) { 2246 iscsiConnList->cl_all_sess = B_TRUE; 2247 } else { 2248 iscsiConnList->cl_all_sess = B_FALSE; 2249 iscsiConnList->cl_sess_oid = 2250 (uint32_t)sessOid->objectSequenceNumber; 2251 } 2252 /* Issue the same ioctl again to obtain all the OIDs */ 2253 if (ioctl(fd, ISCSI_CONN_OID_LIST_GET, iscsiConnList) != 0) { 2254 2255 syslog(LOG_USER|LOG_DEBUG, 2256 "ISCSI_CONN_OID_LIST_GET ioctl failed, errno: %d", 2257 errno); 2258 *ppConnList = NULL; 2259 free(iscsiConnList); 2260 (void) close(fd); 2261 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2262 2263 } 2264 2265 if (out_cnt < iscsiConnList->cl_out_cnt) { 2266 /* 2267 * The connection list grew between the first and second 2268 * ioctls. 2269 */ 2270 syslog(LOG_USER|LOG_DEBUG, 2271 "The connection list has grown. There could be " 2272 "more connections than listed."); 2273 } 2274 } 2275 2276 2277 (void) close(fd); 2278 *ppConnList = iscsiConnList; 2279 return (IMA_STATUS_SUCCESS); 2280 } 2281 2282 /* 2283 * getConnProps - 2284 */ 2285 static IMA_STATUS getConnProps( 2286 iscsi_if_conn_t *pConn, 2287 iscsi_conn_props_t **ppConnProps 2288 ) 2289 { 2290 iscsi_conn_props_t *iscsiConnProps; 2291 int fd; 2292 int status; 2293 2294 /* We try to open the driver. */ 2295 if ((status = open_driver(&fd))) { 2296 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 2297 } 2298 2299 iscsiConnProps = (iscsi_conn_props_t *)calloc(1, 2300 sizeof (*iscsiConnProps)); 2301 2302 if (iscsiConnProps == NULL) { 2303 (void) close(fd); 2304 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2305 } 2306 2307 iscsiConnProps->cp_vers = ISCSI_INTERFACE_VERSION; 2308 iscsiConnProps->cp_oid = pConn->c_oid; 2309 iscsiConnProps->cp_cid = pConn->c_cid; 2310 iscsiConnProps->cp_sess_oid = pConn->c_sess_oid; 2311 2312 /* The IOCTL is submitted. */ 2313 if (ioctl(fd, ISCSI_CONN_PROPS_GET, iscsiConnProps) != 0) { 2314 /* IOCTL failed */ 2315 syslog(LOG_USER|LOG_DEBUG, 2316 "ISCSI_AUTH_CLEAR ioctl failed, errno: %d", errno); 2317 free(iscsiConnProps); 2318 (void) close(fd); 2319 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2320 } 2321 (void) close(fd); 2322 *ppConnProps = iscsiConnProps; 2323 return (IMA_STATUS_SUCCESS); 2324 } 2325 2326 /* A helper function to set authentication method. */ 2327 static IMA_STATUS 2328 setAuthMethods( 2329 IMA_OID oid, 2330 IMA_UINT *pMethodCount, 2331 const IMA_AUTHMETHOD *pMethodList 2332 ) 2333 { 2334 int fd; 2335 int i; 2336 int status; 2337 iscsi_auth_props_t auth; 2338 2339 if ((status = open_driver(&fd))) { 2340 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 2341 } 2342 (void) memset(&auth, 0, sizeof (iscsi_auth_props_t)); 2343 auth.a_vers = ISCSI_INTERFACE_VERSION; 2344 auth.a_oid = (uint32_t)oid.objectSequenceNumber; 2345 2346 /* 2347 * Get the current auth fields so they don't need to be reset 2348 * here. 2349 */ 2350 if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) { 2351 /* EMPTY */ 2352 /* Initializing auth structure with current settings */ 2353 } 2354 auth.a_auth_method = authMethodNone; 2355 2356 for (i = 0; i < *pMethodCount; i++) { 2357 switch (pMethodList[i]) { 2358 case IMA_AUTHMETHOD_CHAP: 2359 auth.a_auth_method |= authMethodCHAP; 2360 break; 2361 default: 2362 break; 2363 } 2364 } 2365 2366 if (ioctl(fd, ISCSI_AUTH_SET, &auth) != 0) { 2367 syslog(LOG_USER|LOG_DEBUG, 2368 "ISCSI_AUTH_SET failed, errno: %d", errno); 2369 (void) close(fd); 2370 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2371 } 2372 2373 (void) close(fd); 2374 return (IMA_STATUS_SUCCESS); 2375 } 2376 2377 /* A helper function to set authentication method. */ 2378 static IMA_STATUS getAuthMethods( 2379 IMA_OID oid, 2380 IMA_UINT *pMethodCount, 2381 IMA_AUTHMETHOD *pMethodList 2382 ) 2383 { 2384 int fd; 2385 int status; 2386 iscsi_auth_props_t auth; 2387 2388 if ((status = open_driver(&fd))) { 2389 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 2390 } 2391 2392 (void) memset(&auth, 0, sizeof (iscsi_auth_props_t)); 2393 auth.a_vers = ISCSI_INTERFACE_VERSION; 2394 auth.a_oid = (uint32_t)oid.objectSequenceNumber; 2395 2396 if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) { 2397 syslog(LOG_USER|LOG_DEBUG, 2398 "ISCSI_AUTH_GET failed, errno: %d", errno); 2399 (void) close(fd); 2400 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2401 } 2402 2403 if (auth.a_auth_method == authMethodNone) { 2404 pMethodList[0] = IMA_AUTHMETHOD_NONE; 2405 *pMethodCount = 1; 2406 } else { 2407 int i = 0; 2408 if (!((auth.a_auth_method & authMethodCHAP)^authMethodCHAP)) { 2409 pMethodList[i++] = IMA_AUTHMETHOD_CHAP; 2410 } 2411 *pMethodCount = i; 2412 } 2413 2414 (void) close(fd); 2415 return (IMA_STATUS_SUCCESS); 2416 } 2417 2418 /* Helper function to open driver */ 2419 int open_driver( 2420 int *fd 2421 ) 2422 { 2423 int ret = 0; 2424 if ((*fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 2425 ret = errno; 2426 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 2427 ISCSI_DRIVER_DEVCTL, ret); 2428 } 2429 return (ret); 2430 } 2431 2432 /* 2433 * Iscsi driver does not support OID for discovery address. Create 2434 * a modified version of IMA_RemoveDiscoveryAddress that takes 2435 * discoveryAddress (instead of an OID) as input argument. 2436 */ 2437 IMA_API IMA_STATUS SUN_IMA_RemoveDiscoveryAddress( 2438 SUN_IMA_TARGET_ADDRESS discoveryAddress 2439 ) 2440 { 2441 entry_t entry; 2442 int fd; 2443 int status, i, addr_list_size, insize; 2444 iscsi_addr_list_t *idlp, al_info; 2445 iscsi_addr_t *matched_addr = NULL; 2446 2447 if ((status = open_driver(&fd))) { 2448 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 2449 } 2450 2451 if (prepare_discovery_entry(discoveryAddress, &entry) != 2452 DISC_ADDR_OK) { 2453 (void) close(fd); 2454 return (IMA_ERROR_INVALID_PARAMETER); 2455 } 2456 2457 (void) memset(&al_info, 0, sizeof (al_info)); 2458 al_info.al_vers = ISCSI_INTERFACE_VERSION; 2459 al_info.al_in_cnt = 0; 2460 /* 2461 * Issue ioctl to get the number of discovery address. 2462 */ 2463 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) { 2464 syslog(LOG_USER|LOG_DEBUG, 2465 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d", 2466 ISCSI_DISCOVERY_ADDR_LIST_GET, errno); 2467 (void) close(fd); 2468 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2469 } 2470 2471 if (al_info.al_out_cnt == 0) { 2472 (void) close(fd); 2473 return (IMA_ERROR_OBJECT_NOT_FOUND); 2474 } 2475 2476 addr_list_size = sizeof (iscsi_addr_list_t); 2477 if (al_info.al_out_cnt > 1) { 2478 addr_list_size += (sizeof (iscsi_addr_t) * 2479 (al_info.al_out_cnt - 1)); 2480 } 2481 2482 idlp = (iscsi_addr_list_t *)calloc(1, addr_list_size); 2483 if (idlp == NULL) { 2484 (void) close(fd); 2485 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2486 } 2487 2488 idlp->al_vers = ISCSI_INTERFACE_VERSION; 2489 idlp->al_in_cnt = al_info.al_out_cnt; 2490 2491 /* issue the same ioctl to get all the discovery addresses */ 2492 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, idlp) != 0) { 2493 syslog(LOG_USER|LOG_DEBUG, 2494 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d", 2495 ISCSI_DISCOVERY_ADDR_LIST_GET, errno); 2496 free(idlp); 2497 (void) close(fd); 2498 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2499 } 2500 2501 /* 2502 * find the matched discovery address 2503 */ 2504 for (i = 0; i < idlp->al_out_cnt; i++) { 2505 insize = idlp->al_addrs[i].a_addr.i_insize; 2506 if (insize != entry.e_insize) { 2507 continue; 2508 } 2509 if (insize == sizeof (struct in_addr)) { 2510 if (idlp->al_addrs[i].a_addr.i_addr.in4.s_addr == 2511 entry.e_u.u_in4.s_addr) { 2512 matched_addr = &(idlp->al_addrs[i]); 2513 break; 2514 } 2515 } 2516 if (insize == sizeof (struct in6_addr)) { 2517 if (bcmp(entry.e_u.u_in6.s6_addr, 2518 idlp->al_addrs[i].a_addr.i_addr.in6.s6_addr, 2519 insize) == 0) { 2520 matched_addr = &(idlp->al_addrs[i]); 2521 break; 2522 } 2523 } 2524 } 2525 2526 free(idlp); 2527 2528 if (matched_addr == NULL) { 2529 (void) close(fd); 2530 return (IMA_ERROR_OBJECT_NOT_FOUND); 2531 } 2532 2533 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_CLEAR, &entry)) { 2534 status = errno; 2535 (void) close(fd); 2536 syslog(LOG_USER|LOG_DEBUG, 2537 "ISCSI_DISCOVERY_ADDR_CLEAR ioctl failed, errno: %d", 2538 errno); 2539 if (status == EBUSY) { 2540 return (IMA_ERROR_LU_IN_USE); 2541 } else { 2542 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2543 } 2544 } 2545 2546 (void) close(fd); 2547 return (IMA_STATUS_SUCCESS); 2548 } 2549 2550 IMA_STATUS SUN_IMA_SetTargetAuthMethods( 2551 IMA_OID targetOid, 2552 IMA_UINT *methodCount, 2553 const IMA_AUTHMETHOD *pMethodList 2554 ) 2555 { 2556 return (setAuthMethods(targetOid, methodCount, pMethodList)); 2557 } 2558 2559 IMA_STATUS getNegotiatedDigest( 2560 int digestType, 2561 SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm, 2562 SUN_IMA_CONN_PROPERTIES *connProps) { 2563 2564 IMA_UINT digest; 2565 2566 if (connProps->valuesValid == IMA_TRUE) { 2567 algorithm->negotiatedValid = IMA_TRUE; 2568 2569 if (digestType == ISCSI_LOGIN_PARAM_HEADER_DIGEST) { 2570 digest = connProps->headerDigest; 2571 } else { 2572 digest = connProps->dataDigest; 2573 } 2574 2575 switch (digest) { 2576 case ISCSI_DIGEST_NONE: 2577 algorithm->negotiatedAlgorithms[0] = 2578 ISCSI_DIGEST_NONE; 2579 algorithm->negotiatedAlgorithmCount = 1; 2580 break; 2581 case ISCSI_DIGEST_CRC32C: 2582 algorithm->negotiatedAlgorithms[0] = 2583 ISCSI_DIGEST_CRC32C; 2584 algorithm->negotiatedAlgorithmCount = 1; 2585 break; 2586 2587 case ISCSI_DIGEST_CRC32C_NONE: 2588 algorithm->negotiatedAlgorithms[0] = 2589 ISCSI_DIGEST_CRC32C; 2590 algorithm->negotiatedAlgorithms[1] = 2591 ISCSI_DIGEST_NONE; 2592 algorithm->negotiatedAlgorithmCount = 2; 2593 break; 2594 case ISCSI_DIGEST_NONE_CRC32C: 2595 algorithm->negotiatedAlgorithms[0] = 2596 ISCSI_DIGEST_NONE; 2597 algorithm->negotiatedAlgorithms[1] = 2598 ISCSI_DIGEST_CRC32C; 2599 algorithm->negotiatedAlgorithmCount = 2; 2600 break; 2601 default: 2602 syslog(LOG_USER|LOG_DEBUG, 2603 "Invalid negotiated digest: %d", 2604 digest); 2605 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2606 } 2607 } else { 2608 algorithm->negotiatedValid = IMA_FALSE; 2609 } 2610 return (IMA_STATUS_SUCCESS); 2611 } 2612 2613 /* 2614 * Non-IMA defined function. 2615 */ 2616 IMA_API IMA_STATUS SUN_IMA_GetISNSServerAddressPropertiesList( 2617 SUN_IMA_DISC_ADDR_PROP_LIST **ppList 2618 ) 2619 { 2620 char isns_server_addr_str[256]; 2621 int fd; 2622 int i; 2623 int isns_server_addr_list_size; 2624 int status; 2625 int out_cnt; 2626 iscsi_addr_list_t *ialp; 2627 /* LINTED */ 2628 IMA_IP_ADDRESS *ipAddr; 2629 2630 if ((status = open_driver(&fd))) { 2631 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 2632 } 2633 2634 ialp = (iscsi_addr_list_t *)calloc(1, sizeof (iscsi_addr_list_t)); 2635 if (ialp == NULL) { 2636 (void) close(fd); 2637 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2638 } 2639 ialp->al_vers = ISCSI_INTERFACE_VERSION; 2640 ialp->al_in_cnt = ialp->al_out_cnt = 1; 2641 2642 /* 2643 * Issue ioctl to retrieve the isns server addresses. Space has been 2644 * allocted for one entry. If more than one entry should be returned, 2645 * we will re-issue the entry with the right amount of space allocted 2646 */ 2647 if (ioctl(fd, ISCSI_ISNS_SERVER_ADDR_LIST_GET, ialp) != 0) { 2648 (void) close(fd); 2649 syslog(LOG_USER|LOG_DEBUG, 2650 "ISCSI_ISNS_SERVER_ADDR_LIST_GET ioctl failed, errno: %d", 2651 errno); 2652 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2653 } 2654 2655 isns_server_addr_list_size = sizeof (iscsi_addr_list_t); 2656 if (ialp->al_out_cnt > 1) { 2657 out_cnt = ialp->al_out_cnt; 2658 free(ialp); 2659 2660 isns_server_addr_list_size += (sizeof (iscsi_addr_t) * 2661 out_cnt - 1); 2662 ialp = (iscsi_addr_list_t *)calloc(1, 2663 isns_server_addr_list_size); 2664 if (ialp == NULL) { 2665 (void) close(fd); 2666 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2667 } 2668 ialp->al_vers = ISCSI_INTERFACE_VERSION; 2669 ialp->al_in_cnt = out_cnt; 2670 2671 /* 2672 * Issue ISCSI_ISNS_SERVER_ADDR_LIST_GET ioctl again to obtain 2673 * the list of all the iSNS server addresses 2674 */ 2675 if (ioctl(fd, ISCSI_ISNS_SERVER_ADDR_LIST_GET, ialp) != 0) { 2676 free(ialp); 2677 (void) close(fd); 2678 syslog(LOG_USER|LOG_DEBUG, 2679 "ISCSI_ISNS_SERVER_ADDR_LIST_GET ioctl failed, " 2680 "errno: %d", errno); 2681 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2682 2683 } 2684 } 2685 2686 *ppList = (SUN_IMA_DISC_ADDR_PROP_LIST *)calloc(1, 2687 sizeof (SUN_IMA_DISC_ADDR_PROP_LIST) + 2688 ialp->al_out_cnt * sizeof (IMA_DISCOVERY_ADDRESS_PROPERTIES)); 2689 if (*ppList == NULL) { 2690 free(ialp); 2691 (void) close(fd); 2692 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2693 } 2694 (*ppList)->discAddrCount = ialp->al_out_cnt; 2695 2696 for (i = 0; i < ialp->al_out_cnt; i++) { 2697 if (ialp->al_addrs[i].a_addr.i_insize == 2698 sizeof (struct in_addr)) { 2699 (*ppList)->props[i].discoveryAddress.hostnameIpAddress. 2700 id.ipAddress.ipv4Address = IMA_TRUE; 2701 } else if (ialp->al_addrs[i].a_addr.i_insize == 2702 sizeof (struct in6_addr)) { 2703 (*ppList)->props[i].discoveryAddress.hostnameIpAddress. 2704 id.ipAddress.ipv4Address = IMA_FALSE; 2705 } else { 2706 (void) strlcpy(isns_server_addr_str, "unknown", 2707 sizeof (isns_server_addr_str)); 2708 } 2709 2710 ipAddr = &(*ppList)->props[i].discoveryAddress. 2711 hostnameIpAddress.id.ipAddress; 2712 bcopy(&ialp->al_addrs[i].a_addr.i_addr, 2713 (*ppList)->props[i].discoveryAddress.hostnameIpAddress.id. 2714 ipAddress.ipAddress, 2715 sizeof (ipAddr->ipAddress)); 2716 (*ppList)->props[i].discoveryAddress.portNumber = 2717 ialp->al_addrs[i].a_port; 2718 } 2719 2720 free(ialp); 2721 (void) close(fd); 2722 return (IMA_STATUS_SUCCESS); 2723 } 2724 2725 /*ARGSUSED*/ 2726 /* 2727 * Remove iSNS Server Address 2728 */ 2729 IMA_API IMA_STATUS SUN_IMA_RemoveISNSServerAddress( 2730 SUN_IMA_TARGET_ADDRESS isnsServerAddress 2731 ) 2732 { 2733 entry_t entry; 2734 int fd, status; 2735 2736 if ((status = open_driver(&fd))) { 2737 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 2738 } 2739 2740 if (prepare_discovery_entry(isnsServerAddress, &entry) != 2741 DISC_ADDR_OK) { 2742 (void) close(fd); 2743 return (IMA_ERROR_INVALID_PARAMETER); 2744 } 2745 2746 if (ioctl(fd, ISCSI_ISNS_SERVER_ADDR_CLEAR, &entry)) { 2747 status = errno; 2748 (void) close(fd); 2749 syslog(LOG_USER|LOG_DEBUG, 2750 "ISCSI_ISNS_SERVER_ADDR_CLEAR ioctl failed, errno: %d", 2751 status); 2752 if (status == EBUSY) { 2753 return (IMA_ERROR_LU_IN_USE); 2754 } else { 2755 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2756 } 2757 } 2758 2759 (void) close(fd); 2760 return (IMA_STATUS_SUCCESS); 2761 } 2762 2763 /*ARGSUSED*/ 2764 IMA_API IMA_STATUS SUN_IMA_AddISNSServerAddress( 2765 const SUN_IMA_TARGET_ADDRESS isnsServerAddress 2766 ) 2767 { 2768 entry_t entry; 2769 int fd; 2770 int status; 2771 2772 if ((status = open_driver(&fd))) { 2773 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 2774 } 2775 2776 if (prepare_discovery_entry(isnsServerAddress, &entry) != 2777 DISC_ADDR_OK) { 2778 (void) close(fd); 2779 return (IMA_ERROR_INVALID_PARAMETER); 2780 } 2781 2782 if (ioctl(fd, ISCSI_ISNS_SERVER_ADDR_SET, &entry)) { 2783 /* 2784 * Encountered problem setting the discovery address. 2785 */ 2786 (void) close(fd); 2787 syslog(LOG_USER|LOG_DEBUG, 2788 "ISCSI_ISNS_SERVER_ADDR_SET ioctl failed, errno: %d", 2789 errno); 2790 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2791 } 2792 2793 (void) close(fd); 2794 return (IMA_STATUS_SUCCESS); 2795 } 2796 2797 IMA_STATUS SUN_IMA_RetrieveISNSServerTargets( 2798 IMA_TARGET_ADDRESS serverAddress, 2799 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES **ppList 2800 ) 2801 { 2802 int fd; 2803 int ctr; 2804 int server_pg_list_sz; 2805 int status; 2806 isns_server_portal_group_list_t *server_pg_list = NULL; 2807 isns_portal_group_list_t *pg_list = NULL; 2808 IMA_BOOL retry = IMA_TRUE; 2809 entry_t entry; 2810 2811 #define ISNS_SERVER_DEFAULT_NUM_TARGETS 50 2812 2813 server_pg_list_sz = sizeof (*server_pg_list) + 2814 ((ISNS_SERVER_DEFAULT_NUM_TARGETS - 1) * 2815 sizeof (isns_portal_group_t)); 2816 2817 server_pg_list = (isns_server_portal_group_list_t *)calloc(1, 2818 server_pg_list_sz); 2819 if (server_pg_list == NULL) { 2820 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2821 } 2822 server_pg_list->addr_port_list.pg_in_cnt = 2823 ISNS_SERVER_DEFAULT_NUM_TARGETS; 2824 2825 if ((prepare_discovery_entry_IMA(serverAddress, &entry) 2826 != DISC_ADDR_OK)) { 2827 free(server_pg_list); 2828 return (IMA_ERROR_INVALID_PARAMETER); 2829 } 2830 server_pg_list->addr.a_port = entry.e_port; 2831 server_pg_list->addr.a_addr.i_insize = entry.e_insize; 2832 if (entry.e_insize == sizeof (struct in_addr)) { 2833 server_pg_list->addr.a_addr.i_addr.in4.s_addr = 2834 (entry.e_u.u_in4.s_addr); 2835 } else if (entry.e_insize == sizeof (struct in6_addr)) { 2836 bcopy(&entry.e_u.u_in6.s6_addr, 2837 server_pg_list->addr.a_addr.i_addr.in6.s6_addr, 16); 2838 } 2839 2840 if ((status = open_driver(&fd))) { 2841 free(server_pg_list); 2842 return (SUN_IMA_ERROR_SYSTEM_ERROR | status); 2843 } 2844 2845 retry_isns: 2846 /* 2847 * Issue ioctl to obtain the ISNS Portal Group List list 2848 */ 2849 if (ioctl(fd, ISCSI_ISNS_SERVER_GET, server_pg_list) != 0) { 2850 int tmp_errno = errno; 2851 IMA_STATUS return_status; 2852 2853 syslog(LOG_USER|LOG_DEBUG, 2854 "ISCSI_ISNS_SERVER_GET ioctl failed, errno: %d", tmp_errno); 2855 if (tmp_errno == EACCES) { 2856 return_status = IMA_ERROR_OBJECT_NOT_FOUND; 2857 } else { 2858 return_status = IMA_ERROR_UNEXPECTED_OS_ERROR; 2859 } 2860 (void) close(fd); 2861 free(server_pg_list); 2862 return (return_status); 2863 } 2864 pg_list = &server_pg_list->addr_port_list; 2865 2866 /* check if all targets received */ 2867 if (pg_list->pg_in_cnt < pg_list->pg_out_cnt) { 2868 if (retry == IMA_TRUE) { 2869 server_pg_list_sz = sizeof (*server_pg_list) + 2870 ((pg_list->pg_out_cnt - 1) * 2871 sizeof (isns_server_portal_group_list_t)); 2872 server_pg_list = (isns_server_portal_group_list_t *) 2873 realloc(server_pg_list, server_pg_list_sz); 2874 if (server_pg_list == NULL) { 2875 (void) close(fd); 2876 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2877 } 2878 pg_list = &server_pg_list->addr_port_list; 2879 pg_list->pg_in_cnt = pg_list->pg_out_cnt; 2880 retry = IMA_FALSE; 2881 goto retry_isns; 2882 } else { 2883 /* 2884 * don't retry after 2 attempts. The target list 2885 * shouldn't continue growing. Just continue 2886 * on and display what was found. 2887 */ 2888 syslog(LOG_USER|LOG_DEBUG, 2889 "ISCSI_SENDTGTS_GET overflow: " 2890 "failed to obtain all targets"); 2891 pg_list->pg_out_cnt = pg_list->pg_in_cnt; 2892 } 2893 } 2894 2895 (void) close(fd); 2896 2897 /* allocate for caller return buffer */ 2898 *ppList = (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *)calloc(1, 2899 sizeof (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES) + 2900 pg_list->pg_out_cnt * sizeof (SUN_IMA_DISC_ADDRESS_KEY)); 2901 if (*ppList == NULL) { 2902 free(server_pg_list); 2903 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2904 } 2905 2906 (*ppList)->keyCount = pg_list->pg_out_cnt; 2907 2908 for (ctr = 0; ctr < pg_list->pg_out_cnt; ctr++) { 2909 (void) mbstowcs((*ppList)->keys[ctr].name, 2910 (char *)pg_list->pg_list[ctr].pg_iscsi_name, 2911 IMA_NODE_NAME_LEN); 2912 2913 (*ppList)->keys[ctr].tpgt = pg_list->pg_list[ctr].pg_tag; 2914 2915 (*ppList)->keys[ctr].address.portNumber = 2916 pg_list->pg_list[ctr].pg_port; 2917 2918 if (pg_list->pg_list[ctr].insize == sizeof (struct in_addr)) { 2919 (*ppList)->keys[ctr].address.ipAddress.ipv4Address = 2920 IMA_TRUE; 2921 } else if (pg_list->pg_list[ctr].insize == 2922 sizeof (struct in6_addr)) { 2923 (*ppList)->keys[ctr].address.ipAddress.ipv4Address = 2924 IMA_FALSE; 2925 } else { 2926 free(pg_list); 2927 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2928 } 2929 2930 (void) memcpy(&(*ppList)->keys[ctr].address.ipAddress.ipAddress, 2931 &(pg_list->pg_list[ctr].pg_ip_addr), 2932 pg_list->pg_list[ctr].insize); 2933 } 2934 free(server_pg_list); 2935 2936 return (IMA_STATUS_SUCCESS); 2937 } 2938 2939 /* ARGSUSED */ 2940 IMA_STATUS SUN_IMA_GetSessionOidList( 2941 IMA_OID initiatorOid, 2942 IMA_OID_LIST **ppList 2943 ) 2944 { 2945 return (get_target_oid_list(ISCSI_TGT_OID_LIST, ppList)); 2946 } 2947 2948 /*ARGSUSED*/ 2949 IMA_API IMA_STATUS SUN_IMA_GetTargetAuthParms( 2950 IMA_OID oid, 2951 IMA_AUTHMETHOD method, 2952 IMA_INITIATOR_AUTHPARMS *pParms 2953 ) 2954 { 2955 int fd; 2956 iscsi_chap_props_t chap_p; 2957 2958 if (pParms == NULL) { 2959 return (IMA_ERROR_INVALID_PARAMETER); 2960 } 2961 2962 if (oid.objectType != IMA_OBJECT_TYPE_TARGET) { 2963 return (IMA_ERROR_INCORRECT_OBJECT_TYPE); 2964 } 2965 2966 if (method != IMA_AUTHMETHOD_CHAP) { 2967 return (IMA_ERROR_INVALID_PARAMETER); 2968 } 2969 2970 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 2971 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 2972 ISCSI_DRIVER_DEVCTL, errno); 2973 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2974 } 2975 2976 (void) memset(&chap_p, 0, sizeof (iscsi_chap_props_t)); 2977 chap_p.c_vers = ISCSI_INTERFACE_VERSION; 2978 chap_p.c_oid = (uint32_t)oid.objectSequenceNumber; 2979 2980 if (ioctl(fd, ISCSI_CHAP_GET, &chap_p) != 0) { 2981 syslog(LOG_USER|LOG_DEBUG, 2982 2983 "ISCSI_CHAP_GET ioctl failed, errno: %d", 2984 errno); 2985 (void) close(fd); 2986 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2987 } 2988 2989 (void) memcpy(pParms->chapParms.name, chap_p.c_user, 2990 chap_p.c_user_len); 2991 2992 pParms->chapParms.nameLength = chap_p.c_user_len; 2993 (void) memcpy(pParms->chapParms.challengeSecret, chap_p.c_secret, 2994 chap_p.c_secret_len); 2995 2996 pParms->chapParms.challengeSecretLength = chap_p.c_secret_len; 2997 2998 return (IMA_STATUS_SUCCESS); 2999 } 3000 3001 IMA_API IMA_STATUS SUN_IMA_GetBootTargetName( 3002 IMA_NODE_NAME tgtName 3003 ) 3004 { 3005 int fd; 3006 IMA_STATUS rtn; 3007 iscsi_boot_property_t bootProp; 3008 3009 bootProp.tgt_name.n_name[0] = '\0'; 3010 bootProp.tgt_chap.c_user[0] = '\0'; 3011 tgtName[0] = L'\0'; 3012 rtn = IMA_ERROR_UNEXPECTED_OS_ERROR; 3013 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 3014 syslog(LOG_USER|LOG_DEBUG, "Unable to open %s (%d)", 3015 ISCSI_DRIVER_DEVCTL, errno); 3016 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3017 } 3018 3019 if (ioctl(fd, ISCSI_BOOTPROP_GET, &bootProp) != 0) { 3020 syslog(LOG_USER|LOG_DEBUG, 3021 "ISCSI_BOOTPROP_GET ioctl failed, errno: %d", 3022 errno); 3023 (void) close(fd); 3024 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3025 } 3026 3027 if ((bootProp.tgt_name.n_name[0] != '\0') && (tgtName != NULL)) { 3028 if (mbstowcs(tgtName, (const char *)bootProp.tgt_name.n_name, 3029 IMA_NODE_NAME_LEN) == (size_t)-1) { 3030 syslog(LOG_USER|LOG_DEBUG, 3031 "ISCSI Target name covert to WCHAR fail"); 3032 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3033 } else { 3034 rtn = IMA_STATUS_SUCCESS; 3035 } 3036 } 3037 3038 return (rtn); 3039 } 3040 3041 IMA_API IMA_STATUS SUN_IMA_GetBootTargetAuthParams( 3042 IMA_INITIATOR_AUTHPARMS *pTgtCHAP 3043 ) 3044 { 3045 int fd; 3046 IMA_STATUS rtn; 3047 iscsi_boot_property_t bootProp; 3048 3049 bootProp.tgt_name.n_name[0] = '\0'; 3050 bootProp.tgt_chap.c_user[0] = '\0'; 3051 bootProp.tgt_chap.c_secret[0] = '\0'; 3052 rtn = IMA_ERROR_UNEXPECTED_OS_ERROR; 3053 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 3054 syslog(LOG_USER|LOG_DEBUG, "Unable to open %s (%d)", 3055 ISCSI_DRIVER_DEVCTL, errno); 3056 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3057 } 3058 3059 if (ioctl(fd, ISCSI_BOOTPROP_GET, &bootProp) != 0) { 3060 syslog(LOG_USER|LOG_DEBUG, 3061 "ISCSI_BOOTPROP_GET ioctl failed, errno: %d", 3062 errno); 3063 (void) close(fd); 3064 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3065 } 3066 3067 if (pTgtCHAP != NULL) { 3068 if (bootProp.tgt_chap.c_user[0] != '\0') { 3069 (void) memcpy(pTgtCHAP->chapParms.name, 3070 bootProp.tgt_chap.c_user, ISCSI_MAX_NAME_LEN); 3071 } else { 3072 pTgtCHAP->chapParms.name[0] = '\0'; 3073 } 3074 if (bootProp.tgt_chap.c_secret[0] != '\0') { 3075 (void) memcpy(pTgtCHAP->chapParms.challengeSecret, 3076 bootProp.tgt_chap.c_secret, MAX_CHAP_SECRET_LEN); 3077 } else { 3078 pTgtCHAP->chapParms.challengeSecret[0] = '\0'; 3079 } 3080 rtn = IMA_STATUS_SUCCESS; 3081 } 3082 return (rtn); 3083 } 3084 3085 IMA_STATUS SUN_IMA_GetBootMpxio( 3086 IMA_BOOL *pMpxioEnabled 3087 ) 3088 { 3089 int fd; 3090 iscsi_boot_property_t bootProp; 3091 3092 bootProp.hba_mpxio_enabled = B_FALSE; 3093 *pMpxioEnabled = IMA_UNKNOWN; 3094 3095 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 3096 syslog(LOG_USER|LOG_DEBUG, "Unable to open %s (%d)", 3097 ISCSI_DRIVER_DEVCTL, errno); 3098 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3099 } 3100 3101 if (ioctl(fd, ISCSI_BOOTPROP_GET, &bootProp) != 0) { 3102 syslog(LOG_USER|LOG_DEBUG, 3103 "ISCSI_BOOTPROP_GET ioctl failed, errno: %d", 3104 errno); 3105 (void) close(fd); 3106 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3107 } 3108 3109 if (bootProp.hba_mpxio_enabled) { 3110 *pMpxioEnabled = IMA_TRUE; 3111 } else { 3112 *pMpxioEnabled = IMA_FALSE; 3113 } 3114 3115 (void) close(fd); 3116 return (IMA_STATUS_SUCCESS); 3117 } 3118 3119 IMA_STATUS SUN_IMA_GetBootIscsi( 3120 IMA_BOOL *pIscsiBoot 3121 ) 3122 { 3123 int fd; 3124 iscsi_boot_property_t bootProp; 3125 3126 bootProp.iscsiboot = 0; 3127 *pIscsiBoot = 0; 3128 3129 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 3130 syslog(LOG_USER|LOG_DEBUG, "Unable to open %s (%d)", 3131 ISCSI_DRIVER_DEVCTL, errno); 3132 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3133 } 3134 3135 if (ioctl(fd, ISCSI_BOOTPROP_GET, &bootProp) != 0) { 3136 syslog(LOG_USER|LOG_DEBUG, 3137 "ISCSI_BOOTPROP_GET ioctl failed, errno: %d", 3138 errno); 3139 (void) close(fd); 3140 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3141 } 3142 3143 *pIscsiBoot = bootProp.iscsiboot; 3144 3145 (void) close(fd); 3146 return (IMA_STATUS_SUCCESS); 3147 } 3148