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