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 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #include <stdio.h> 32 #include <limits.h> 33 #include <string.h> 34 #include <stdlib.h> 35 #include <sys/stat.h> /* mkdir declaration is here? */ 36 #include <unistd.h> 37 #include <errno.h> 38 #include <utmpx.h> 39 #include <dirent.h> 40 #include <sys/types.h> 41 #include <locale.h> 42 #include <libintl.h> 43 #include <pkgstrct.h> 44 #include <pkglocs.h> 45 #include "install.h" 46 #include <pkglib.h> 47 #include "libadm.h" 48 #include "libinst.h" 49 #include "pkginstall.h" 50 51 extern struct admin adm; 52 extern struct cfextra **extlist; 53 extern int ckquit, nocnflct, nosetuid, rprcflag; 54 extern char ilockfile[], rlockfile[], instdir[], savlog[], 55 tmpdir[], pkgloc[], pkgloc_sav[], pkgbin[], pkgsav[], 56 *pkginst, *msgtext; 57 extern char saveSpoolInstallDir[]; 58 59 static boolean_t preinstallCheck = B_FALSE; 60 static char *zoneName = (char *)NULL; 61 62 static char ask_cont[100]; 63 64 #define DISPSIZ 20 /* number of items to display on one page */ 65 66 #define MSG_RUNLEVEL "\\nThe current run-level of this machine is <%s>, " \ 67 "which is not a run-level suggested for installation " \ 68 "of this package. Suggested run-levels (in order of " \ 69 "preference) include:" 70 #define HLP_RUNLEVEL "If this package is not installed in a run-level " \ 71 "which has been suggested, it is possible that the " \ 72 "package may not install or operate properly. If " \ 73 "you wish to follow the run-level suggestions, " \ 74 "answer 'n' to stop installation of the package." 75 #define MSG_STATECHG "\\nTo change states, execute\\n\\tshutdown -y " \ 76 "-i%s -g0\\nafter exiting the installation process. " \ 77 "Please note that after changing states you " \ 78 "may have to mount appropriate filesystem(s) " \ 79 "in order to install this package." 80 81 #define ASK_CONFLICT "Do you want to install these conflicting files" 82 #define MSG_CONFLICT "\\nThe following files are already installed on the " \ 83 "system and are being used by another package:" 84 #define MSG_ROGUE "\\n* - conflict with a file which does not " \ 85 "belong to any package." 86 #define HLP_CONFLICT "If you choose to install conflicting files, the " \ 87 "files listed above will be overwritten and/or have " \ 88 "their access permissions changed. If you choose " \ 89 "not to install these files, installation will " \ 90 "proceed but these specific files will not be " \ 91 "installed. Note that sane operation of the " \ 92 "software being installed may require these files " \ 93 "be installed; thus choosing to not to do so may " \ 94 "cause inapropriate operation. If you wish to stop " \ 95 "installation of this package, enter 'q' to quit." 96 97 #define ASK_SETUID "Do you want to install these as setuid/setgid files" 98 #define MSG_SETUID "\\nThe following files are being installed with " \ 99 "setuid and/or setgid permissions:" 100 #define MSG_OVERWR "\\n* - overwriting a file which is also " \ 101 "setuid/setgid." 102 #define HLP_SETUID "The package being installed appears to contain " \ 103 "processes which will have their effective user or " \ 104 "group ids set upon execution. History has shown " \ 105 "that these types of processes can be a source of " \ 106 "security problems on your system. If you choose " \ 107 "not to install these as setuid files, installation " \ 108 "will proceed but these specific files will be " \ 109 "installed as regular files with setuid and/or " \ 110 "setgid permissions reset. Note that sane " \ 111 "operation of the software being installed may " \ 112 "require that these files be installed with setuid " \ 113 "or setgid permissions as delivered; thus choosing " \ 114 "to install them as regular files may cause " \ 115 "inapropriate operation. If you wish to stop " \ 116 "installation of this package, enter 'q' to quit." 117 #define MSG_PARTINST "\\nThe installation of this package was previously " \ 118 "terminated and installation was never successfully " \ 119 "completed." 120 #define MSG_PARTREM "\\nThe removal of this package was terminated at " \ 121 "some point in time, and package removal was only " \ 122 "partially completed." 123 #define HLP_PARTIAL "Installation of partially installed packages is " \ 124 "normally allowable, but some packages providers " \ 125 "may suggest that a partially installed package be " \ 126 "completely removed before re-attempting " \ 127 "installation. Check the documentation provided " \ 128 "with this package, and then answer 'y' if you feel " \ 129 "it is advisable to continue the installation process." 130 131 #define HLP_SPACE "It appears that there is not enough free space on " \ 132 "your system in which to install this package. It " \ 133 "is possible that one or more filesystems are not " \ 134 "properly mounted. Neither installation of the " \ 135 "package nor its operation can be guaranteed under " \ 136 "these conditions. If you choose to disregard this " \ 137 "warning, enter 'y' to continue the installation " \ 138 "process." 139 #define HLP_DEPEND "The package being installed has indicated a " \ 140 "dependency on the existence (or non-existence) " \ 141 "of another software package. If this dependency is " \ 142 "not met before continuing, the package may not " \ 143 "install or operate properly. If you wish to " \ 144 "disregard this dependency, answer 'y' to continue " \ 145 "the installation process." 146 147 #define MSG_PRIV "\\nThis package contains scripts which will be " \ 148 "executed with super-user permission during the " \ 149 "process of installing this package." 150 #define HLP_PRIV "During the installation of this package, certain " \ 151 "scripts provided with the package will execute with " \ 152 "super-user permission. These scripts may modify or " \ 153 "otherwise change your system without your " \ 154 "knowledge. If you are certain of the origin and " \ 155 "trustworthiness of the package being installed, " \ 156 "answer 'y' to continue the installation process." 157 158 #define ASK_CONT "Do you want to continue with the installation of <%s>" 159 #define HLP_CONT "If you choose 'y', installation of this package " \ 160 "will continue. If you want to stop installation " \ 161 "of this package, choose 'n'." 162 163 #define MSG_MKPKGDIR "unable to make packaging directory <%s>" 164 165 #define MSG_CKCONFL_GZ "## Checking for conflicts with packages already " \ 166 "installed." 167 #define MSG_CKCONFL_LZ "## Checking for conflicts with packages already " \ 168 "installed in zone <%s>." 169 #define MSG_CKDEPEND_GZ "## Verifying package dependencies." 170 #define MSG_CKDEPEND_LZ "## Verifying package dependencies in zone <%s>." 171 #define MSG_CKSPACE_GZ "## Verifying disk space requirements." 172 #define MSG_CKSPACE_LZ "## Verifying disk space requirements in zone <%s>." 173 #define MSG_CKUID_GZ "## Checking for setuid/setgid programs." 174 #define MSG_CKUID_LZ "## Checking for setuid/setgid programs in zone <%s>." 175 176 #define MSG_SCRFND "Package scripts were found." 177 #define MSG_UIDFND "Setuid/setgid processes detected." 178 #define MSG_ATTRONLY "!%s %s <attribute change only>" 179 180 #define MSG_CONTDISP "[Hit <RETURN> to continue display]" 181 182 #define ERR_NO_RUNST "unable to determine current run-state" 183 #define ERR_DEPFAILED "Dependency checking failed." 184 #define ERR_SPCFAILED "Space checking failed." 185 #define ERR_CNFFAILED "Conflict checking failed." 186 #define ERR_BADFILE "packaging file <%s> is corrupt" 187 188 /* 189 * Return value: int 190 * 0 - success 191 * 1 - end of file 192 * 2 - undefined error 193 * 3 - answer was not "y"/was "q" 194 * 4 - quit action taken 195 * 5 - interactive mode required 196 * If "preinstallcheck" is set to B_TRUE: 197 * 8 - partial install detected 198 * 9 - partial removal detected 199 */ 200 201 int 202 ckpartial(void) 203 { 204 char ans[MAX_INPUT]; 205 int n; 206 207 if (ADM(partial, "nocheck")) { 208 return (0); 209 } 210 211 if (access(ilockfile, F_OK) == 0) { 212 if (preinstallCheck == B_TRUE) { 213 return (8); /* partial install detected */ 214 } 215 216 (void) snprintf(ask_cont, sizeof (ask_cont), 217 gettext(ASK_CONT), pkginst); 218 219 msgtext = gettext(MSG_PARTINST); 220 ptext(stderr, msgtext); 221 222 if (ADM(partial, "quit")) { 223 return (4); 224 } 225 226 if (echoGetFlag() == B_FALSE) { 227 return (5); 228 } 229 230 msgtext = NULL; 231 232 ckquit = 0; 233 if (n = ckyorn(ans, NULL, NULL, gettext(HLP_PARTIAL), 234 ask_cont)) { 235 return (n); 236 } 237 238 if (strchr("yY", *ans) == NULL) { 239 return (3); 240 } 241 ckquit = 1; 242 } 243 244 if (access(rlockfile, F_OK) == 0) { 245 if (preinstallCheck == B_TRUE) { 246 return (9); /* partial removal detected */ 247 } 248 249 (void) snprintf(ask_cont, sizeof (ask_cont), 250 gettext(ASK_CONT), pkginst); 251 252 253 msgtext = gettext(MSG_PARTREM); 254 ptext(stderr, msgtext); 255 256 if (ADM(partial, "quit")) { 257 return (4); 258 } 259 260 if (echoGetFlag() == B_FALSE) { 261 return (5); 262 } 263 264 msgtext = NULL; 265 266 ckquit = 0; 267 if (n = ckyorn(ans, NULL, NULL, gettext(HLP_PARTIAL), 268 ask_cont)) { 269 return (n); 270 } 271 272 if (strchr("yY", *ans) == NULL) { 273 return (3); 274 } 275 ckquit = 1; 276 } 277 278 return (0); 279 } 280 281 /* 282 * Return value: int 283 * 0 - success 284 * 1 - end of file 285 * 2 - undefined error 286 * 3 - answer was not "y"/was "q" 287 * 4 - quit action taken 288 * 5 - interactive mode required 289 * 99 - fatal error 290 */ 291 292 int 293 ckrunlevel(void) 294 { 295 struct utmpx utmpx; 296 struct utmpx *putmpx; 297 char ans[MAX_INPUT], *pt, *istates, *pstate; 298 int n; 299 char *uxstate; 300 301 if (ADM(runlevel, "nocheck")) { 302 return (0); 303 } 304 305 pt = getenv("ISTATES"); 306 if (pt == NULL) { 307 return (0); 308 } 309 310 utmpx.ut_type = RUN_LVL; 311 putmpx = getutxid(&utmpx); 312 if (putmpx == NULL) { 313 progerr(gettext(ERR_NO_RUNST)); 314 return (99); 315 } 316 317 (void) snprintf(ask_cont, sizeof (ask_cont), 318 gettext(ASK_CONT), pkginst); 319 320 /* 321 * this cryptic code is trying to pull the run level 322 * out of the utmpx entry...the level starts in column 323 * 11 - looks like "run-level %c" 324 */ 325 uxstate = strtok(&putmpx->ut_line[10], " \t\n"); 326 327 istates = qstrdup(pt); 328 if ((pt = strtok(pt, " \t\n, ")) == NULL) { 329 return (0); /* no list is no list */ 330 } 331 332 pstate = pt; 333 do { 334 if (strcmp(pt, uxstate) == 0) { 335 free(istates); 336 return (0); 337 } 338 } while (pt = strtok(NULL, " \t\n, ")); 339 340 if (preinstallCheck == B_FALSE) { 341 msgtext = gettext(MSG_RUNLEVEL); 342 ptext(stderr, msgtext, uxstate); 343 } else { 344 (void) fprintf(stdout, "runlevel=%s", uxstate); 345 } 346 347 pt = strtok(istates, " \t\n, "); 348 do { 349 if (preinstallCheck == B_FALSE) { 350 ptext(stderr, "\\t%s", pt); 351 } else { 352 (void) fprintf(stdout, ":%s", pt); 353 } 354 } while (pt = strtok(NULL, " \t\n, ")); 355 356 if (preinstallCheck == B_TRUE) { 357 (void) fprintf(stdout, "\n"); 358 } 359 360 free(istates); 361 362 if (preinstallCheck == B_TRUE) { 363 return (4); 364 } 365 366 if (ADM(runlevel, "quit")) { 367 return (4); 368 } 369 370 if (echoGetFlag() == B_FALSE) { 371 return (5); 372 } 373 374 msgtext = NULL; 375 376 ckquit = 0; 377 if (n = ckyorn(ans, NULL, NULL, gettext(HLP_RUNLEVEL), 378 ask_cont)) { 379 return (n); 380 } 381 382 ckquit = 1; 383 384 if (strchr("yY", *ans) != NULL) { 385 return (0); 386 } else { 387 if (preinstallCheck == B_FALSE) { 388 ptext(stderr, gettext(MSG_STATECHG), pstate); 389 } 390 return (3); 391 } 392 } 393 394 /* 395 * Return value: int 396 * 0 - success 397 * 1 - end of file 398 * 2 - undefined error 399 * 3 - answer was not "y"/was "q" 400 * 4 - quit action taken 401 * 5 - interactive mode required 402 */ 403 404 int 405 ckdepend(void) 406 { 407 int n; 408 char ans[MAX_INPUT]; 409 char path[PATH_MAX]; 410 411 if (ADM(idepend, "nocheck")) { 412 return (0); 413 } 414 415 (void) snprintf(path, sizeof (path), "%s/%s", instdir, DEPEND_FILE); 416 if (access(path, F_OK) != 0) { 417 return (0); /* no dependency file provided by package */ 418 } 419 420 if (zoneName == (char *)NULL) { 421 echo(gettext(MSG_CKDEPEND_GZ)); 422 } else { 423 echo(gettext(MSG_CKDEPEND_LZ), zoneName); 424 } 425 426 if (dockdeps(path, 0, preinstallCheck)) { 427 (void) snprintf(ask_cont, sizeof (ask_cont), 428 gettext(ASK_CONT), pkginst); 429 msgtext = gettext(ERR_DEPFAILED); 430 431 if (preinstallCheck == B_TRUE) { 432 return (4); 433 } 434 435 if (ADM(idepend, "quit")) { 436 return (4); 437 } 438 439 if (echoGetFlag() == B_FALSE) { 440 return (5); 441 } 442 443 msgtext = NULL; 444 445 ckquit = 0; 446 if (n = ckyorn(ans, NULL, NULL, gettext(HLP_DEPEND), 447 ask_cont)) { 448 return (n); 449 } 450 451 if (strchr("yY", *ans) == NULL) { 452 return (3); 453 } 454 455 ckquit = 1; 456 } 457 458 return (0); 459 } 460 461 void 462 cksetZoneName(char *a_zoneName) 463 { 464 zoneName = a_zoneName; 465 } 466 467 void 468 cksetPreinstallCheck(boolean_t a_preinstallCheck) 469 { 470 preinstallCheck = a_preinstallCheck; 471 } 472 473 /* 474 * Return value: int 475 * 0 - success 476 * 1 - end of file 477 * 2 - undefined error 478 * 3 - answer was not "y"/was "q" 479 * 4 - quit action taken 480 * 5 - interactive mode required 481 */ 482 int 483 ckspace(void) 484 { 485 int n; 486 char ans[MAX_INPUT]; 487 char path[PATH_MAX]; 488 489 if (ADM(space, "nocheck")) { 490 return (0); 491 } 492 493 if (zoneName == (char *)NULL) { 494 echo(gettext(MSG_CKSPACE_GZ)); 495 } else { 496 echo(gettext(MSG_CKSPACE_LZ), zoneName); 497 } 498 499 (void) snprintf(path, sizeof (path), "%s/install/space", instdir); 500 if (access(path, F_OK) == 0) { 501 n = dockspace(path); 502 } else { 503 n = dockspace(NULL); 504 } 505 506 if (n) { 507 msgtext = gettext(ERR_SPCFAILED); 508 (void) snprintf(ask_cont, sizeof (ask_cont), 509 gettext(ASK_CONT), pkginst); 510 511 if (preinstallCheck == B_TRUE) { 512 return (4); 513 } 514 515 if (ADM(space, "quit")) { 516 return (4); 517 } 518 519 if (echoGetFlag() == B_FALSE) { 520 return (5); 521 } 522 523 msgtext = NULL; 524 525 ckquit = 0; 526 n = ckyorn(ans, NULL, NULL, gettext(HLP_SPACE), ask_cont); 527 if (n != 0) { 528 return (n); 529 } 530 531 if (strchr("yY", *ans) == NULL) { 532 return (3); 533 } 534 535 ckquit = 1; 536 } 537 return (0); 538 } 539 540 void 541 ckdirs(void) 542 { 543 char path[PATH_MAX]; 544 545 if (mkpath(get_PKGADM())) { 546 if (preinstallCheck == B_TRUE) { 547 (void) fprintf(stdout, "ckdirs=%s\n", get_PKGADM()); 548 } else { 549 progerr(gettext(MSG_MKPKGDIR), get_PKGADM()); 550 } 551 quit(99); 552 } 553 554 (void) snprintf(path, sizeof (path), "%s/admin", get_PKGADM()); 555 556 if (mkpath(path)) { 557 if (preinstallCheck == B_TRUE) { 558 (void) fprintf(stdout, "ckdirs=%s\n", path); 559 } else { 560 progerr(gettext(MSG_MKPKGDIR), path); 561 } 562 quit(99); 563 } 564 565 (void) snprintf(path, sizeof (path), "%s/logs", get_PKGADM()); 566 567 if (mkpath(path)) { 568 if (preinstallCheck == B_TRUE) { 569 (void) fprintf(stdout, "ckdirs=%s\n", path); 570 } else { 571 progerr(gettext(MSG_MKPKGDIR), path); 572 } 573 quit(99); 574 } 575 576 if (mkpath(PKGSCR)) { 577 if (preinstallCheck == B_TRUE) { 578 (void) fprintf(stdout, "ckdirs=%s\n", PKGSCR); 579 } else { 580 progerr(gettext(MSG_MKPKGDIR), PKGSCR); 581 } 582 quit(99); 583 } 584 585 if (mkpath(get_PKGLOC())) { 586 if (preinstallCheck == B_TRUE) { 587 (void) fprintf(stdout, "ckdirs=%s\n", get_PKGLOC()); 588 } else { 589 progerr(gettext(MSG_MKPKGDIR), get_PKGLOC()); 590 } 591 quit(99); 592 } 593 } 594 595 /* 596 * Return value: int 597 * 0 - success 598 * 99 - failure 599 */ 600 601 int 602 ckpkgdirs(void) 603 { 604 boolean_t nonExistentPkgloc = B_FALSE; 605 606 /* 607 * If pkgloc doesn't exist make sure it gets removed after creating 608 * it if this is a preinstall check. All dryrun and preinstallation 609 * checks must not modify the file system. 610 */ 611 612 if (access(pkgloc, F_OK) != 0) { 613 nonExistentPkgloc = B_TRUE; 614 } 615 616 if (mkpath(pkgloc)) { 617 if (preinstallCheck == B_TRUE) { 618 (void) fprintf(stdout, "ckdirs=%s\n", pkgloc); 619 } else { 620 progerr(gettext(MSG_MKPKGDIR), pkgloc); 621 } 622 return (99); 623 } 624 625 if (mkpath(pkgbin)) { 626 if (preinstallCheck == B_TRUE) { 627 (void) fprintf(stdout, "ckdirs=%s\n", pkgbin); 628 } else { 629 progerr(gettext(MSG_MKPKGDIR), pkgbin); 630 } 631 return (99); 632 } 633 634 if (mkpath(pkgsav)) { 635 if (preinstallCheck == B_TRUE) { 636 (void) fprintf(stdout, "ckdirs=%s\n", pkgsav); 637 } else { 638 progerr(gettext(MSG_MKPKGDIR), pkgsav); 639 } 640 return (99); 641 } 642 643 if (!is_spool_create() && mkpath(saveSpoolInstallDir)) { 644 if (preinstallCheck == B_TRUE) { 645 (void) fprintf(stdout, "ckdirs=%s\n", pkgsav); 646 } else { 647 progerr(gettext(MSG_MKPKGDIR), pkgsav); 648 } 649 return (99); 650 } 651 652 if (preinstallCheck && nonExistentPkgloc) { 653 rrmdir(pkgloc); 654 } 655 656 return (0); 657 } 658 659 /* 660 * Return value: int 661 * 0 - success 662 * 1 - end of file 663 * 2 - undefined error 664 * 3 - answer was not "y"/was "q" 665 * 4 - quit action taken 666 * 5 - interactive mode required 667 */ 668 669 int 670 ckconflct(void) 671 { 672 int i, n, count, has_a_rogue = 0; 673 char ans[MAX_INPUT]; 674 675 if (ADM(conflict, "nochange")) { 676 nocnflct++; 677 return (0); 678 } 679 680 if (ADM(conflict, "nocheck")) { 681 return (0); 682 } 683 684 if (zoneName == (char *)NULL) { 685 echo(gettext(MSG_CKCONFL_GZ)); 686 } else { 687 echo(gettext(MSG_CKCONFL_LZ), zoneName); 688 } 689 690 count = 0; 691 for (i = 0; extlist[i]; i++) { 692 struct cfent *ept; 693 struct mergstat *mstat; 694 695 if (extlist[i]->cf_ent.ftype == 'i') { 696 continue; 697 } 698 699 ept = &(extlist[i]->cf_ent); 700 mstat = &(extlist[i]->mstat); 701 702 if (is_remote_fs(ept->path, &(extlist[i]->fsys_value)) && 703 !is_fs_writeable(ept->path, 704 &(extlist[i]->fsys_value))) { 705 continue; 706 } 707 708 /* 709 * If no other package claims it or it's from a continuation 710 * file, skip it. 711 */ 712 if (!mstat->shared || mstat->preloaded) { 713 continue; 714 } 715 716 if (ept->ftype == 'e') { 717 continue; 718 } 719 720 if (mstat->rogue) { 721 has_a_rogue = 1; 722 } 723 724 if (mstat->contchg) { 725 if (!count++) { 726 if (preinstallCheck == B_FALSE) { 727 ptext(stderr, gettext(MSG_CONFLICT)); 728 } 729 } else if ((echoGetFlag() == B_TRUE) && 730 ((count % DISPSIZ) == 0)) { 731 echo(gettext(MSG_CONTDISP)); 732 (void) getc(stdin); 733 } 734 /* 735 * NOTE : The leading "!" in this string forces 736 * puttext() to print leading white space. 737 */ 738 739 if (preinstallCheck == B_FALSE) { 740 ptext(stderr, "!%s %s", 741 (mstat->rogue) ? "*" : " ", ept->path); 742 } else { 743 (void) fprintf(stdout, 744 "conflict-contents=%s\n", ept->path); 745 } 746 } else if (mstat->attrchg) { 747 if (!count++) { 748 if (preinstallCheck == B_FALSE) { 749 ptext(stderr, gettext(MSG_CONFLICT)); 750 } 751 } else if ((echoGetFlag() == B_TRUE) && 752 ((count % DISPSIZ) == 0)) { 753 echo(gettext(MSG_CONTDISP)); 754 (void) getc(stdin); 755 } 756 if (preinstallCheck == B_FALSE) { 757 ptext(stderr, gettext(MSG_ATTRONLY), 758 (mstat->rogue) ? "*" : " ", ept->path); 759 } else { 760 (void) fprintf(stdout, 761 "conflict-attributes=%s\n", ept->path); 762 } 763 } 764 } 765 766 if (count) { 767 if (has_a_rogue) { 768 if (preinstallCheck == B_FALSE) { 769 ptext(stderr, gettext(MSG_ROGUE)); 770 } 771 } 772 773 msgtext = gettext(ERR_CNFFAILED); 774 775 if (preinstallCheck == B_TRUE) { 776 return (4); 777 } 778 779 if (ADM(conflict, "quit")) { 780 return (4); 781 } 782 783 if (echoGetFlag() == B_FALSE) { 784 return (5); 785 } 786 787 msgtext = NULL; 788 789 if (n = ckyorn(ans, NULL, NULL, gettext(HLP_CONFLICT), 790 gettext(ASK_CONFLICT))) { 791 return (n); 792 } 793 794 if (strchr("yY", *ans) == NULL) { 795 ckquit = 0; 796 (void) snprintf(ask_cont, sizeof (ask_cont), 797 gettext(ASK_CONT), pkginst); 798 799 if (n = ckyorn(ans, NULL, NULL, gettext(HLP_CONT), 800 ask_cont)) { 801 return (n); 802 } 803 804 if (strchr("yY", *ans) == NULL) { 805 return (3); 806 } 807 ckquit = 1; 808 nocnflct++; 809 rprcflag++; 810 } 811 } 812 return (0); 813 } 814 815 /* 816 * Return value: int 817 * 0 - success 818 * 1 - end of file 819 * 2 - undefined error 820 * 3 - answer was not "y"/was "q" 821 * 4 - quit action taken 822 * 5 - interactive mode required 823 */ 824 825 int 826 cksetuid(void) 827 { 828 int i, n, count, overwriting = 0; 829 char ans[MAX_INPUT]; 830 831 /* See if the administrative defaults already resolve this check. */ 832 if (ADM(setuid, "nocheck")) { 833 return (0); 834 } 835 836 if (ADM(setuid, "nochange")) { 837 nosetuid++; /* Do not install processes as setuid/gid. */ 838 return (0); 839 } 840 841 /* The administrative defaults require review of the package. */ 842 843 if (zoneName == (char *)NULL) { 844 echo(gettext(MSG_CKUID_GZ)); 845 } else { 846 echo(gettext(MSG_CKUID_LZ), zoneName); 847 } 848 849 count = 0; 850 for (i = 0; extlist[i]; i++) { 851 int overwr; 852 struct mergstat *mstat = &(extlist[i]->mstat); 853 854 /* 855 * Provide the administrator with info as to whether there is 856 * already a setuid process in place. This is only necessary 857 * to help the administrator decide whether or not to lay 858 * down the process, it doesn't have anything to do with the 859 * administrative defaults. 860 */ 861 if (mstat->osetuid || mstat->osetgid) { 862 overwr = 1; 863 overwriting = 1; 864 } else 865 overwr = 0; 866 867 if (mstat->setuid || mstat->setgid) { 868 if (!count++) { 869 if (preinstallCheck == B_FALSE) { 870 ptext(stderr, gettext(MSG_SETUID)); 871 } 872 } else if ((echoGetFlag() == B_TRUE) && 873 ((count % DISPSIZ) == 0)) { 874 echo(gettext(MSG_CONTDISP)); 875 (void) getc(stdin); 876 } 877 /* 878 * NOTE : The leading "!" in these strings forces 879 * puttext() to print leading white space. 880 */ 881 882 if (mstat->setuid && mstat->setgid) { 883 if (preinstallCheck == B_FALSE) { 884 ptext(stderr, gettext( 885 "!%s %s <setuid %s setgid %s>"), 886 (overwr) ? "*" : " ", 887 extlist[i]->cf_ent.path, 888 extlist[i]->cf_ent.ainfo.owner, 889 extlist[i]->cf_ent.ainfo.group); 890 } else { 891 (void) fprintf(stdout, "setuid=%s:%s\n", 892 extlist[i]->cf_ent.path, 893 extlist[i]->cf_ent.ainfo.owner); 894 (void) fprintf(stdout, "setgid=%s:%s\n", 895 extlist[i]->cf_ent.path, 896 extlist[i]->cf_ent.ainfo.group); 897 } 898 } else if (mstat->setuid) { 899 if (preinstallCheck == B_FALSE) { 900 ptext(stderr, gettext( 901 "!%s %s <setuid %s>"), 902 (overwr) ? "*" : " ", 903 extlist[i]->cf_ent.path, 904 extlist[i]->cf_ent.ainfo.owner); 905 } else { 906 (void) fprintf(stdout, "setuid=%s:%s\n", 907 extlist[i]->cf_ent.path, 908 extlist[i]->cf_ent.ainfo.owner); 909 } 910 } else if (mstat->setgid) { 911 if (preinstallCheck == B_FALSE) { 912 ptext(stderr, gettext( 913 "!%s%s <setgid %s>"), 914 (overwr) ? "*" : " ", 915 extlist[i]->cf_ent.path, 916 extlist[i]->cf_ent.ainfo.group); 917 } else { 918 (void) fprintf(stdout, "setgid=%s:%s\n", 919 extlist[i]->cf_ent.path, 920 extlist[i]->cf_ent.ainfo.group); 921 } 922 } 923 } 924 } 925 926 if (count) { 927 if (overwriting) { 928 if (preinstallCheck == B_FALSE) { 929 ptext(stderr, gettext(MSG_OVERWR)); 930 } else { 931 (void) fprintf(stdout, 932 "setuid-overwrite=true\n"); 933 } 934 } 935 936 msgtext = gettext(MSG_UIDFND); 937 938 if (preinstallCheck == B_TRUE) { 939 return (4); 940 } 941 942 if (ADM(setuid, "quit")) { 943 return (4); 944 } 945 if (echoGetFlag() == B_FALSE) { 946 return (5); 947 } 948 msgtext = NULL; 949 950 if (n = ckyorn(ans, NULL, NULL, gettext(HLP_SETUID), 951 gettext(ASK_SETUID))) { 952 return (n); 953 } 954 if (strchr("yY", *ans) == NULL) { 955 ckquit = 0; 956 (void) snprintf(ask_cont, sizeof (ask_cont), 957 gettext(ASK_CONT), pkginst); 958 if (n = ckyorn(ans, NULL, NULL, gettext(HLP_CONT), 959 ask_cont)) { 960 return (n); 961 } 962 if (strchr("yY", *ans) == NULL) { 963 return (3); 964 } 965 ckquit = 1; 966 nosetuid++; 967 rprcflag++; 968 } 969 } 970 971 return (0); 972 } 973 974 /* 975 * Return value: int 976 * 0 - success 977 * 1 - end of file 978 * 2 - undefined error 979 * 3 - answer was not "y"/was "q" 980 * 4 - quit action taken 981 * 5 - interactive mode required 982 */ 983 984 int 985 ckpriv(void) 986 { 987 struct dirent *dp; 988 DIR *dirfp; 989 int n, found; 990 char ans[MAX_INPUT], path[PATH_MAX]; 991 992 if (ADM(action, "nocheck")) { 993 return (0); 994 } 995 996 (void) snprintf(path, sizeof (path), "%s/install", instdir); 997 if ((dirfp = opendir(path)) == NULL) { 998 return (0); 999 } 1000 1001 found = 0; 1002 while ((dp = readdir(dirfp)) != NULL) { 1003 if (strcmp(dp->d_name, "preinstall") == 0 || 1004 strcmp(dp->d_name, "postinstall") == 0 || 1005 strncmp(dp->d_name, "i.", 2) == 0) { 1006 found++; 1007 break; 1008 } 1009 } 1010 (void) closedir(dirfp); 1011 1012 if (found) { 1013 if (preinstallCheck == B_FALSE) { 1014 ptext(stderr, gettext(MSG_PRIV)); 1015 msgtext = gettext(MSG_SCRFND); 1016 } 1017 (void) snprintf(ask_cont, sizeof (ask_cont), 1018 gettext(ASK_CONT), pkginst); 1019 1020 if (preinstallCheck == B_TRUE) { 1021 return (4); 1022 } 1023 1024 if (ADM(action, "quit")) { 1025 return (4); 1026 } 1027 1028 if (echoGetFlag() == B_FALSE) { 1029 return (5); 1030 } 1031 1032 msgtext = NULL; 1033 1034 ckquit = 0; 1035 if (n = ckyorn(ans, NULL, NULL, gettext(HLP_PRIV), 1036 ask_cont)) { 1037 return (n); 1038 } 1039 1040 if (strchr("yY", *ans) == NULL) { 1041 return (3); 1042 } 1043 ckquit = 1; 1044 } 1045 1046 return (0); 1047 } 1048 1049 /* 1050 * Return value: int 1051 * 0 - success 1052 * 99 - failure 1053 */ 1054 1055 int 1056 ckpkgfiles(void) 1057 { 1058 register int i; 1059 struct cfent *ept; 1060 int errflg; 1061 char source[PATH_MAX]; 1062 1063 errflg = 0; 1064 for (i = 0; extlist[i]; i++) { 1065 ept = &(extlist[i]->cf_ent); 1066 if (ept->ftype != 'i') { 1067 continue; 1068 } 1069 1070 if (ept->ainfo.local) { 1071 (void) snprintf(source, sizeof (source), 1072 "%s/%s", instdir, ept->ainfo.local); 1073 } else if (strcmp(ept->path, PKGINFO) == 0) { 1074 (void) snprintf(source, sizeof (source), 1075 "%s/%s", instdir, ept->path); 1076 } else { 1077 (void) snprintf(source, sizeof (source), 1078 "%s/install/%s", instdir, ept->path); 1079 } 1080 if (cverify(0, &ept->ftype, source, &ept->cinfo, 1)) { 1081 errflg++; 1082 if (preinstallCheck == B_FALSE) { 1083 progerr(gettext(ERR_BADFILE), source); 1084 logerr(getErrbufAddr()); 1085 } else { 1086 (void) fprintf(stdout, "ckpkgfilebad=%s", 1087 source); 1088 } 1089 } 1090 } 1091 1092 if (errflg) { 1093 return (99); 1094 } else { 1095 return (0); 1096 } 1097 } 1098