| 596 | } |
| 597 | |
| 598 | static int |
| 599 | mls_parse_element(struct mac_mls_element *element, char *string) |
| 600 | { |
| 601 | char *compartment, *end, *level; |
| 602 | int value; |
| 603 | |
| 604 | if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) { |
| 605 | element->mme_type = MAC_MLS_TYPE_HIGH; |
| 606 | element->mme_level = MAC_MLS_TYPE_UNDEF; |
| 607 | } else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) { |
| 608 | element->mme_type = MAC_MLS_TYPE_LOW; |
| 609 | element->mme_level = MAC_MLS_TYPE_UNDEF; |
| 610 | } else if (strcmp(string, "equal") == 0 || |
| 611 | strcmp(string, "eq") == 0) { |
| 612 | element->mme_type = MAC_MLS_TYPE_EQUAL; |
| 613 | element->mme_level = MAC_MLS_TYPE_UNDEF; |
| 614 | } else { |
| 615 | element->mme_type = MAC_MLS_TYPE_LEVEL; |
| 616 | |
| 617 | /* |
| 618 | * Numeric level piece of the element. |
| 619 | */ |
| 620 | level = strsep(&string, ":"); |
| 621 | value = strtol(level, &end, 10); |
| 622 | if (end == level || *end != '\0') |
| 623 | return (EINVAL); |
| 624 | if (value < 0 || value > 65535) |
| 625 | return (EINVAL); |
| 626 | element->mme_level = value; |
| 627 | |
| 628 | /* |
| 629 | * Optional compartment piece of the element. If none are |
| 630 | * included, we assume that the label has no compartments. |
| 631 | */ |
| 632 | if (string == NULL) |
| 633 | return (0); |
| 634 | if (*string == '\0') |
| 635 | return (0); |
| 636 | |
| 637 | while ((compartment = strsep(&string, "+")) != NULL) { |
| 638 | value = strtol(compartment, &end, 10); |
| 639 | if (compartment == end || *end != '\0') |
| 640 | return (EINVAL); |
| 641 | if (value < 1 || value > MAC_MLS_MAX_COMPARTMENTS) |
| 642 | return (EINVAL); |
| 643 | MAC_MLS_BIT_SET(value, element->mme_compartments); |
| 644 | } |
| 645 | } |
| 646 | |
| 647 | return (0); |
| 648 | } |
| 649 | |
| 650 | /* |
| 651 | * Note: destructively consumes the string, make a local copy before calling |