acl_to_text_nfs4.c revision 194955
1/*- 2 * Copyright (c) 2008, 2009 Edward Tomasz Napiera��a <trasz@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/lib/libc/posix1e/acl_to_text_nfs4.c 194955 2009-06-25 12:46:59Z trasz $"); 29 30#include <stdio.h> 31#include <stdlib.h> 32#include <unistd.h> 33#include <errno.h> 34#include <assert.h> 35#include <string.h> 36#include <pwd.h> 37#include <grp.h> 38#include <sys/syscall.h> 39#include <sys/types.h> 40#include <sys/acl.h> 41 42#include "acl_support.h" 43 44#define MAX_ENTRY_LENGTH 512 45 46static int 47format_who(char *str, size_t size, const acl_entry_t entry, int numeric) 48{ 49 int error; 50 acl_tag_t tag; 51 struct passwd *pwd; 52 struct group *grp; 53 id_t *id; 54 55 error = acl_get_tag_type(entry, &tag); 56 if (error) 57 return (error); 58 59 switch (tag) { 60 case ACL_USER_OBJ: 61 snprintf(str, size, "owner@"); 62 break; 63 64 case ACL_USER: 65 id = (id_t *)acl_get_qualifier(entry); 66 if (id == NULL) 67 return (-1); 68 /* XXX: Thread-unsafe. */ 69 if (!numeric) 70 pwd = getpwuid(*id); 71 else 72 pwd = NULL; 73 if (pwd == NULL) 74 snprintf(str, size, "user:%d", (unsigned int)*id); 75 else 76 snprintf(str, size, "user:%s", pwd->pw_name); 77 break; 78 79 case ACL_GROUP_OBJ: 80 snprintf(str, size, "group@"); 81 break; 82 83 case ACL_GROUP: 84 id = (id_t *)acl_get_qualifier(entry); 85 if (id == NULL) 86 return (-1); 87 /* XXX: Thread-unsafe. */ 88 if (!numeric) 89 grp = getgrgid(*id); 90 else 91 grp = NULL; 92 if (grp == NULL) 93 snprintf(str, size, "group:%d", (unsigned int)*id); 94 else 95 snprintf(str, size, "group:%s", grp->gr_name); 96 break; 97 98 case ACL_EVERYONE: 99 snprintf(str, size, "everyone@"); 100 break; 101 102 default: 103 return (-1); 104 } 105 106 return (0); 107} 108 109static int 110format_entry_type(char *str, size_t size, const acl_entry_t entry) 111{ 112 int error; 113 acl_entry_type_t entry_type; 114 115 error = acl_get_entry_type_np(entry, &entry_type); 116 if (error) 117 return (error); 118 119 switch (entry_type) { 120 case ACL_ENTRY_TYPE_ALLOW: 121 snprintf(str, size, "allow"); 122 break; 123 case ACL_ENTRY_TYPE_DENY: 124 snprintf(str, size, "deny"); 125 break; 126 case ACL_ENTRY_TYPE_AUDIT: 127 snprintf(str, size, "audit"); 128 break; 129 case ACL_ENTRY_TYPE_ALARM: 130 snprintf(str, size, "alarm"); 131 break; 132 default: 133 return (-1); 134 } 135 136 return (0); 137} 138 139static int 140format_additional_id(char *str, size_t size, const acl_entry_t entry) 141{ 142 int error; 143 acl_tag_t tag; 144 id_t *id; 145 146 error = acl_get_tag_type(entry, &tag); 147 if (error) 148 return (error); 149 150 switch (tag) { 151 case ACL_USER_OBJ: 152 case ACL_GROUP_OBJ: 153 case ACL_EVERYONE: 154 str[0] = '\0'; 155 break; 156 157 default: 158 id = (id_t *)acl_get_qualifier(entry); 159 if (id == NULL) 160 return (-1); 161 snprintf(str, size, ":%d", (unsigned int)*id); 162 } 163 164 return (0); 165} 166 167static int 168format_entry(char *str, size_t size, const acl_entry_t entry, int flags) 169{ 170 size_t off = 0, padding_length, maximum_who_field_length = 18; 171 acl_permset_t permset; 172 acl_flagset_t flagset; 173 int error, len; 174 char buf[MAX_ENTRY_LENGTH + 1]; 175 176 assert(_entry_brand(entry) == ACL_BRAND_NFS4); 177 178 error = acl_get_flagset_np(entry, &flagset); 179 if (error) 180 return (error); 181 182 error = acl_get_permset(entry, &permset); 183 if (error) 184 return (error); 185 186 error = format_who(buf, sizeof(buf), entry, 187 flags & ACL_TEXT_NUMERIC_IDS); 188 if (error) 189 return (error); 190 len = strlen(buf); 191 padding_length = maximum_who_field_length - len; 192 if (padding_length > 0) { 193 memset(str, ' ', padding_length); 194 off += padding_length; 195 } 196 off += snprintf(str + off, size - off, "%s:", buf); 197 198 error = _nfs4_format_access_mask(buf, sizeof(buf), *permset, 199 flags & ACL_TEXT_VERBOSE); 200 if (error) 201 return (error); 202 off += snprintf(str + off, size - off, "%s:", buf); 203 204 error = _nfs4_format_flags(buf, sizeof(buf), *flagset, 205 flags & ACL_TEXT_VERBOSE); 206 if (error) 207 return (error); 208 off += snprintf(str + off, size - off, "%s:", buf); 209 210 error = format_entry_type(buf, sizeof(buf), entry); 211 if (error) 212 return (error); 213 off += snprintf(str + off, size - off, "%s", buf); 214 215 if (flags & ACL_TEXT_APPEND_ID) { 216 error = format_additional_id(buf, sizeof(buf), entry); 217 if (error) 218 return (error); 219 off += snprintf(str + off, size - off, "%s", buf); 220 } 221 222 off += snprintf(str + off, size - off, "\n"); 223 224 /* Make sure we didn't truncate anything. */ 225 assert (off < size); 226 227 return (0); 228} 229 230char * 231_nfs4_acl_to_text_np(const acl_t aclp, ssize_t *len_p, int flags) 232{ 233 int error, off = 0, size, entry_id = ACL_FIRST_ENTRY; 234 char *str; 235 acl_entry_t entry; 236 237 if (aclp->ats_acl.acl_cnt == 0) 238 return strdup(""); 239 240 size = aclp->ats_acl.acl_cnt * MAX_ENTRY_LENGTH; 241 str = malloc(size); 242 if (str == NULL) 243 return (NULL); 244 245 while (acl_get_entry(aclp, entry_id, &entry) == 1) { 246 entry_id = ACL_NEXT_ENTRY; 247 248 assert(off < size); 249 250 error = format_entry(str + off, size - off, entry, flags); 251 if (error) { 252 errno = EINVAL; 253 return (NULL); 254 } 255 256 off = strlen(str); 257 } 258 259 assert(off < size); 260 str[off] = '\0'; 261 262 if (len_p != NULL) 263 *len_p = off; 264 265 return (str); 266} 267/*- 268 * Copyright (c) 2008, 2009 Edward Tomasz Napiera��a <trasz@FreeBSD.org> 269 * All rights reserved. 270 * 271 * Redistribution and use in source and binary forms, with or without 272 * modification, are permitted provided that the following conditions 273 * are met: 274 * 1. Redistributions of source code must retain the above copyright 275 * notice, this list of conditions and the following disclaimer. 276 * 2. Redistributions in binary form must reproduce the above copyright 277 * notice, this list of conditions and the following disclaimer in the 278 * documentation and/or other materials provided with the distribution. 279 * 280 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 281 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 282 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 283 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 284 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 285 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 286 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 287 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 288 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 289 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 290 * SUCH DAMAGE. 291 */ 292 293#include <sys/cdefs.h> 294__FBSDID("$FreeBSD: head/lib/libc/posix1e/acl_to_text_nfs4.c 194955 2009-06-25 12:46:59Z trasz $"); 295 296#include <stdio.h> 297#include <stdlib.h> 298#include <unistd.h> 299#include <errno.h> 300#include <assert.h> 301#include <string.h> 302#include <pwd.h> 303#include <grp.h> 304#include <sys/syscall.h> 305#include <sys/types.h> 306#include <sys/acl.h> 307 308#include "acl_support.h" 309 310#define MAX_ENTRY_LENGTH 512 311 312static int 313format_who(char *str, size_t size, const acl_entry_t entry, int numeric) 314{ 315 int error; 316 acl_tag_t tag; 317 struct passwd *pwd; 318 struct group *grp; 319 id_t *id; 320 321 error = acl_get_tag_type(entry, &tag); 322 if (error) 323 return (error); 324 325 switch (tag) { 326 case ACL_USER_OBJ: 327 snprintf(str, size, "owner@"); 328 break; 329 330 case ACL_USER: 331 id = (id_t *)acl_get_qualifier(entry); 332 if (id == NULL) 333 return (-1); 334 /* XXX: Thread-unsafe. */ 335 if (!numeric) 336 pwd = getpwuid(*id); 337 else 338 pwd = NULL; 339 if (pwd == NULL) 340 snprintf(str, size, "user:%d", (unsigned int)*id); 341 else 342 snprintf(str, size, "user:%s", pwd->pw_name); 343 break; 344 345 case ACL_GROUP_OBJ: 346 snprintf(str, size, "group@"); 347 break; 348 349 case ACL_GROUP: 350 id = (id_t *)acl_get_qualifier(entry); 351 if (id == NULL) 352 return (-1); 353 /* XXX: Thread-unsafe. */ 354 if (!numeric) 355 grp = getgrgid(*id); 356 else 357 grp = NULL; 358 if (grp == NULL) 359 snprintf(str, size, "group:%d", (unsigned int)*id); 360 else 361 snprintf(str, size, "group:%s", grp->gr_name); 362 break; 363 364 case ACL_EVERYONE: 365 snprintf(str, size, "everyone@"); 366 break; 367 368 default: 369 return (-1); 370 } 371 372 return (0); 373} 374 375static int 376format_entry_type(char *str, size_t size, const acl_entry_t entry) 377{ 378 int error; 379 acl_entry_type_t entry_type; 380 381 error = acl_get_entry_type_np(entry, &entry_type); 382 if (error) 383 return (error); 384 385 switch (entry_type) { 386 case ACL_ENTRY_TYPE_ALLOW: 387 snprintf(str, size, "allow"); 388 break; 389 case ACL_ENTRY_TYPE_DENY: 390 snprintf(str, size, "deny"); 391 break; 392 case ACL_ENTRY_TYPE_AUDIT: 393 snprintf(str, size, "audit"); 394 break; 395 case ACL_ENTRY_TYPE_ALARM: 396 snprintf(str, size, "alarm"); 397 break; 398 default: 399 return (-1); 400 } 401 402 return (0); 403} 404 405static int 406format_additional_id(char *str, size_t size, const acl_entry_t entry) 407{ 408 int error; 409 acl_tag_t tag; 410 id_t *id; 411 412 error = acl_get_tag_type(entry, &tag); 413 if (error) 414 return (error); 415 416 switch (tag) { 417 case ACL_USER_OBJ: 418 case ACL_GROUP_OBJ: 419 case ACL_EVERYONE: 420 str[0] = '\0'; 421 break; 422 423 default: 424 id = (id_t *)acl_get_qualifier(entry); 425 if (id == NULL) 426 return (-1); 427 snprintf(str, size, ":%d", (unsigned int)*id); 428 } 429 430 return (0); 431} 432 433static int 434format_entry(char *str, size_t size, const acl_entry_t entry, int flags) 435{ 436 size_t off = 0, padding_length, maximum_who_field_length = 18; 437 acl_permset_t permset; 438 acl_flagset_t flagset; 439 int error, len; 440 char buf[MAX_ENTRY_LENGTH + 1]; 441 442 assert(_entry_brand(entry) == ACL_BRAND_NFS4); 443 444 error = acl_get_flagset_np(entry, &flagset); 445 if (error) 446 return (error); 447 448 error = acl_get_permset(entry, &permset); 449 if (error) 450 return (error); 451 452 error = format_who(buf, sizeof(buf), entry, 453 flags & ACL_TEXT_NUMERIC_IDS); 454 if (error) 455 return (error); 456 len = strlen(buf); 457 padding_length = maximum_who_field_length - len; 458 if (padding_length > 0) { 459 memset(str, ' ', padding_length); 460 off += padding_length; 461 } 462 off += snprintf(str + off, size - off, "%s:", buf); 463 464 error = _nfs4_format_access_mask(buf, sizeof(buf), *permset, 465 flags & ACL_TEXT_VERBOSE); 466 if (error) 467 return (error); 468 off += snprintf(str + off, size - off, "%s:", buf); 469 470 error = _nfs4_format_flags(buf, sizeof(buf), *flagset, 471 flags & ACL_TEXT_VERBOSE); 472 if (error) 473 return (error); 474 off += snprintf(str + off, size - off, "%s:", buf); 475 476 error = format_entry_type(buf, sizeof(buf), entry); 477 if (error) 478 return (error); 479 off += snprintf(str + off, size - off, "%s", buf); 480 481 if (flags & ACL_TEXT_APPEND_ID) { 482 error = format_additional_id(buf, sizeof(buf), entry); 483 if (error) 484 return (error); 485 off += snprintf(str + off, size - off, "%s", buf); 486 } 487 488 off += snprintf(str + off, size - off, "\n"); 489 490 /* Make sure we didn't truncate anything. */ 491 assert (off < size); 492 493 return (0); 494} 495 496char * 497_nfs4_acl_to_text_np(const acl_t aclp, ssize_t *len_p, int flags) 498{ 499 int error, off = 0, size, entry_id = ACL_FIRST_ENTRY; 500 char *str; 501 acl_entry_t entry; 502 503 if (aclp->ats_acl.acl_cnt == 0) 504 return strdup(""); 505 506 size = aclp->ats_acl.acl_cnt * MAX_ENTRY_LENGTH; 507 str = malloc(size); 508 if (str == NULL) 509 return (NULL); 510 511 while (acl_get_entry(aclp, entry_id, &entry) == 1) { 512 entry_id = ACL_NEXT_ENTRY; 513 514 assert(off < size); 515 516 error = format_entry(str + off, size - off, entry, flags); 517 if (error) { 518 errno = EINVAL; 519 return (NULL); 520 } 521 522 off = strlen(str); 523 } 524 525 assert(off < size); 526 str[off] = '\0'; 527 528 if (len_p != NULL) 529 *len_p = off; 530 531 return (str); 532} 533/*- 534 * Copyright (c) 2008, 2009 Edward Tomasz Napiera��a <trasz@FreeBSD.org> 535 * All rights reserved. 536 * 537 * Redistribution and use in source and binary forms, with or without 538 * modification, are permitted provided that the following conditions 539 * are met: 540 * 1. Redistributions of source code must retain the above copyright 541 * notice, this list of conditions and the following disclaimer. 542 * 2. Redistributions in binary form must reproduce the above copyright 543 * notice, this list of conditions and the following disclaimer in the 544 * documentation and/or other materials provided with the distribution. 545 * 546 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 547 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 548 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 549 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 550 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 551 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 552 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 553 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 554 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 555 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 556 * SUCH DAMAGE. 557 */ 558 559#include <sys/cdefs.h> 560__FBSDID("$FreeBSD: head/lib/libc/posix1e/acl_to_text_nfs4.c 194955 2009-06-25 12:46:59Z trasz $"); 561 562#include <stdio.h> 563#include <stdlib.h> 564#include <unistd.h> 565#include <errno.h> 566#include <assert.h> 567#include <string.h> 568#include <pwd.h> 569#include <grp.h> 570#include <sys/syscall.h> 571#include <sys/types.h> 572#include <sys/acl.h> 573 574#include "acl_support.h" 575 576#define MAX_ENTRY_LENGTH 512 577 578static int 579format_who(char *str, size_t size, const acl_entry_t entry, int numeric) 580{ 581 int error; 582 acl_tag_t tag; 583 struct passwd *pwd; 584 struct group *grp; 585 id_t *id; 586 587 error = acl_get_tag_type(entry, &tag); 588 if (error) 589 return (error); 590 591 switch (tag) { 592 case ACL_USER_OBJ: 593 snprintf(str, size, "owner@"); 594 break; 595 596 case ACL_USER: 597 id = (id_t *)acl_get_qualifier(entry); 598 if (id == NULL) 599 return (-1); 600 /* XXX: Thread-unsafe. */ 601 if (!numeric) 602 pwd = getpwuid(*id); 603 else 604 pwd = NULL; 605 if (pwd == NULL) 606 snprintf(str, size, "user:%d", (unsigned int)*id); 607 else 608 snprintf(str, size, "user:%s", pwd->pw_name); 609 break; 610 611 case ACL_GROUP_OBJ: 612 snprintf(str, size, "group@"); 613 break; 614 615 case ACL_GROUP: 616 id = (id_t *)acl_get_qualifier(entry); 617 if (id == NULL) 618 return (-1); 619 /* XXX: Thread-unsafe. */ 620 if (!numeric) 621 grp = getgrgid(*id); 622 else 623 grp = NULL; 624 if (grp == NULL) 625 snprintf(str, size, "group:%d", (unsigned int)*id); 626 else 627 snprintf(str, size, "group:%s", grp->gr_name); 628 break; 629 630 case ACL_EVERYONE: 631 snprintf(str, size, "everyone@"); 632 break; 633 634 default: 635 return (-1); 636 } 637 638 return (0); 639} 640 641static int 642format_entry_type(char *str, size_t size, const acl_entry_t entry) 643{ 644 int error; 645 acl_entry_type_t entry_type; 646 647 error = acl_get_entry_type_np(entry, &entry_type); 648 if (error) 649 return (error); 650 651 switch (entry_type) { 652 case ACL_ENTRY_TYPE_ALLOW: 653 snprintf(str, size, "allow"); 654 break; 655 case ACL_ENTRY_TYPE_DENY: 656 snprintf(str, size, "deny"); 657 break; 658 case ACL_ENTRY_TYPE_AUDIT: 659 snprintf(str, size, "audit"); 660 break; 661 case ACL_ENTRY_TYPE_ALARM: 662 snprintf(str, size, "alarm"); 663 break; 664 default: 665 return (-1); 666 } 667 668 return (0); 669} 670 671static int 672format_additional_id(char *str, size_t size, const acl_entry_t entry) 673{ 674 int error; 675 acl_tag_t tag; 676 id_t *id; 677 678 error = acl_get_tag_type(entry, &tag); 679 if (error) 680 return (error); 681 682 switch (tag) { 683 case ACL_USER_OBJ: 684 case ACL_GROUP_OBJ: 685 case ACL_EVERYONE: 686 str[0] = '\0'; 687 break; 688 689 default: 690 id = (id_t *)acl_get_qualifier(entry); 691 if (id == NULL) 692 return (-1); 693 snprintf(str, size, ":%d", (unsigned int)*id); 694 } 695 696 return (0); 697} 698 699static int 700format_entry(char *str, size_t size, const acl_entry_t entry, int flags) 701{ 702 size_t off = 0, padding_length, maximum_who_field_length = 18; 703 acl_permset_t permset; 704 acl_flagset_t flagset; 705 int error, len; 706 char buf[MAX_ENTRY_LENGTH + 1]; 707 708 assert(_entry_brand(entry) == ACL_BRAND_NFS4); 709 710 error = acl_get_flagset_np(entry, &flagset); 711 if (error) 712 return (error); 713 714 error = acl_get_permset(entry, &permset); 715 if (error) 716 return (error); 717 718 error = format_who(buf, sizeof(buf), entry, 719 flags & ACL_TEXT_NUMERIC_IDS); 720 if (error) 721 return (error); 722 len = strlen(buf); 723 padding_length = maximum_who_field_length - len; 724 if (padding_length > 0) { 725 memset(str, ' ', padding_length); 726 off += padding_length; 727 } 728 off += snprintf(str + off, size - off, "%s:", buf); 729 730 error = _nfs4_format_access_mask(buf, sizeof(buf), *permset, 731 flags & ACL_TEXT_VERBOSE); 732 if (error) 733 return (error); 734 off += snprintf(str + off, size - off, "%s:", buf); 735 736 error = _nfs4_format_flags(buf, sizeof(buf), *flagset, 737 flags & ACL_TEXT_VERBOSE); 738 if (error) 739 return (error); 740 off += snprintf(str + off, size - off, "%s:", buf); 741 742 error = format_entry_type(buf, sizeof(buf), entry); 743 if (error) 744 return (error); 745 off += snprintf(str + off, size - off, "%s", buf); 746 747 if (flags & ACL_TEXT_APPEND_ID) { 748 error = format_additional_id(buf, sizeof(buf), entry); 749 if (error) 750 return (error); 751 off += snprintf(str + off, size - off, "%s", buf); 752 } 753 754 off += snprintf(str + off, size - off, "\n"); 755 756 /* Make sure we didn't truncate anything. */ 757 assert (off < size); 758 759 return (0); 760} 761 762char * 763_nfs4_acl_to_text_np(const acl_t aclp, ssize_t *len_p, int flags) 764{ 765 int error, off = 0, size, entry_id = ACL_FIRST_ENTRY; 766 char *str; 767 acl_entry_t entry; 768 769 if (aclp->ats_acl.acl_cnt == 0) 770 return strdup(""); 771 772 size = aclp->ats_acl.acl_cnt * MAX_ENTRY_LENGTH; 773 str = malloc(size); 774 if (str == NULL) 775 return (NULL); 776 777 while (acl_get_entry(aclp, entry_id, &entry) == 1) { 778 entry_id = ACL_NEXT_ENTRY; 779 780 assert(off < size); 781 782 error = format_entry(str + off, size - off, entry, flags); 783 if (error) { 784 errno = EINVAL; 785 return (NULL); 786 } 787 788 off = strlen(str); 789 } 790 791 assert(off < size); 792 str[off] = '\0'; 793 794 if (len_p != NULL) 795 *len_p = off; 796 797 return (str); 798} 799