3154 case SCF_ERROR_DELETED:
3155 err = mc_error_create(err, ret,
3156 "Property group could not be found");
3157 goto out;
3158
3159 case SCF_ERROR_HANDLE_MISMATCH:
3160 case SCF_ERROR_INVALID_ARGUMENT:
3161 case SCF_ERROR_NOT_SET:
3162 default:
3163 bad_fail("scf_pg_get_property", ret);
3164 }
3165 }
3166
3167
3168 if (scf_default_secflags(h, &cip->def_secflags) != 0) {
3169 err = mc_error_create(err, EINVAL, "couldn't fetch "
3170 "default security-flags");
3171 goto out;
3172 }
3173
3174 if (strcmp(cip->vbuf, ":default") == 0) {
3175 if (secflags_parse(&cip->def_secflags.psf_inherit, "default",
3176 &cip->secflag_delta) != 0) {
3177 err = mc_error_create(err, EINVAL, "couldn't parse "
3178 "security flags: %s", cip->vbuf);
3179 goto out;
3180 }
3181 } else {
3182 if (secflags_parse(&cip->def_secflags.psf_inherit, cip->vbuf,
3183 &cip->secflag_delta) != 0) {
3184 err = mc_error_create(err, EINVAL, "couldn't parse "
3185 "security flags: %s", cip->vbuf);
3186 goto out;
3187 }
3188 }
3189
3190 /* get (optional) corefile pattern */
3191 if ((methpg != NULL && scf_pg_get_property(methpg,
3192 SCF_PROPERTY_COREFILE_PATTERN, prop) == SCF_SUCCESS) ||
3193 (instpg != NULL && scf_pg_get_property(instpg,
3194 SCF_PROPERTY_COREFILE_PATTERN, prop) == SCF_SUCCESS)) {
3195 if (scf_property_get_value(prop, val) != SCF_SUCCESS) {
3196 ret = scf_error();
3197 switch (ret) {
3198 case SCF_ERROR_CONNECTION_BROKEN:
3199 err = mc_error_create(err, ret, RCBROKEN);
3200 break;
3201
3202 case SCF_ERROR_CONSTRAINT_VIOLATED:
3416 * A method_context was not used for any configurable
3417 * elements or attributes, so reset and use the simple
3418 * defaults that provide historic init behavior.
3419 */
3420 if (mc_used == 0) {
3421 free(cip->pwbuf);
3422 free(cip->vbuf);
3423 free(cip->working_dir);
3424
3425 (void) memset(cip, 0, sizeof (*cip));
3426 cip->uid = 0;
3427 cip->gid = 0;
3428 cip->euid = (uid_t)-1;
3429 cip->egid = (gid_t)-1;
3430
3431 if (scf_default_secflags(h, &cip->def_secflags) != 0) {
3432 err = mc_error_create(err, EINVAL, "couldn't fetch "
3433 "default security-flags");
3434 goto out;
3435 }
3436
3437 if (secflags_parse(&cip->def_secflags.psf_inherit, "default",
3438 &cip->secflag_delta) != 0) {
3439 err = mc_error_create(err, EINVAL, "couldn't parse "
3440 "security flags: %s", cip->vbuf);
3441 goto out;
3442 }
3443 }
3444
3445 *mcpp = cip;
3446
3447 out:
3448 (void) scf_value_destroy(val);
3449 scf_property_destroy(prop);
3450 scf_pg_destroy(instpg);
3451 scf_pg_destroy(methpg);
3452
3453 if (cip->pwbuf != NULL) {
3454 free(cip->pwbuf);
3455 cip->pwbuf = NULL;
3456 }
3457
3458 free(cip->vbuf);
3459
3460 if (err->type != 0) {
3461 restarter_free_method_context(cip);
3462 } else {
3495 * EACCES - could not access working_dir (chdir)
3496 * in a TASK_FINAL task (setproject, settaskid)
3497 * no resource pool accepting default binding exists (setproject)
3498 * ELOOP - too many symbolic links in working_dir (chdir)
3499 * ENAMETOOLONG - working_dir is too long (chdir)
3500 * ENOLINK - working_dir is on an inaccessible remote machine (chdir)
3501 * ENOTDIR - working_dir is not a directory (chdir)
3502 * ESRCH - uid is not a user of project (setproject)
3503 * project is invalid (setproject)
3504 * the resource pool specified for project is unknown (setproject)
3505 * EBADF - the configuration for the pool is invalid (pool_set_binding)
3506 * -1 - core_set_process_path() failed (core_set_process_path)
3507 * a resource control assignment failed (setproject)
3508 * a system error occurred during pool_set_binding (pool_set_binding)
3509 */
3510 int
3511 restarter_set_method_context(struct method_context *cip, const char **fp)
3512 {
3513 pid_t mypid = -1;
3514 int r, ret;
3515 secflagdelta_t delta = {0};
3516
3517 cip->pwbuf = NULL;
3518 *fp = NULL;
3519
3520 if (cip->gid != (gid_t)-1) {
3521 if (setregid(cip->gid,
3522 cip->egid != (gid_t)-1 ? cip->egid : cip->gid) != 0) {
3523 *fp = "setregid";
3524
3525 ret = errno;
3526 assert(ret == EINVAL || ret == EPERM);
3527 goto out;
3528 }
3529 } else {
3530 if (cip->pwbuf == NULL) {
3531 switch (ret = lookup_pwd(cip)) {
3532 case 0:
3533 break;
3534
3535 case ENOMEM:
3592 setgroups(cip->ngroups, cip->groups) != 0) {
3593 *fp = "setgroups";
3594
3595 ret = errno;
3596 assert(ret == EINVAL || ret == EPERM);
3597 goto out;
3598 }
3599
3600 if (cip->corefile_pattern != NULL) {
3601 mypid = getpid();
3602
3603 if (core_set_process_path(cip->corefile_pattern,
3604 strlen(cip->corefile_pattern) + 1, mypid) != 0) {
3605 *fp = "core_set_process_path";
3606 ret = -1;
3607 goto out;
3608 }
3609 }
3610
3611
3612 delta.psd_ass_active = B_TRUE;
3613 secflags_copy(&delta.psd_assign, &cip->def_secflags.psf_inherit);
3614 if (psecflags(P_PID, P_MYID, PSF_INHERIT,
3615 &delta) != 0) {
3616 *fp = "psecflags (inherit defaults)";
3617 ret = errno;
3618 goto out;
3619 }
3620
3621 if (psecflags(P_PID, P_MYID, PSF_INHERIT,
3622 &cip->secflag_delta) != 0) {
3623 *fp = "psecflags (inherit)";
3624 ret = errno;
3625 goto out;
3626 }
3627
3628 secflags_copy(&delta.psd_assign, &cip->def_secflags.psf_lower);
3629 if (psecflags(P_PID, P_MYID, PSF_LOWER,
3630 &delta) != 0) {
3631 *fp = "psecflags (lower)";
3632 ret = errno;
3633 goto out;
3634 }
3635
3636 secflags_copy(&delta.psd_assign, &cip->def_secflags.psf_upper);
3637 if (psecflags(P_PID, P_MYID, PSF_UPPER,
3638 &delta) != 0) {
3639 *fp = "psecflags (upper)";
3640 ret = errno;
3641 goto out;
3642 }
3643
3644 if (restarter_rm_libs_loadable()) {
3645 if (cip->project == NULL) {
3646 if (settaskid(getprojid(), TASK_NORMAL) == -1) {
3647 switch (errno) {
3648 case EACCES:
3649 case EPERM:
3650 *fp = "settaskid";
3651 ret = errno;
3652 goto out;
3653
3654 case EINVAL:
3655 default:
3656 bad_fail("settaskid", errno);
3657 }
3658 }
3659 } else {
|
3154 case SCF_ERROR_DELETED:
3155 err = mc_error_create(err, ret,
3156 "Property group could not be found");
3157 goto out;
3158
3159 case SCF_ERROR_HANDLE_MISMATCH:
3160 case SCF_ERROR_INVALID_ARGUMENT:
3161 case SCF_ERROR_NOT_SET:
3162 default:
3163 bad_fail("scf_pg_get_property", ret);
3164 }
3165 }
3166
3167
3168 if (scf_default_secflags(h, &cip->def_secflags) != 0) {
3169 err = mc_error_create(err, EINVAL, "couldn't fetch "
3170 "default security-flags");
3171 goto out;
3172 }
3173
3174 if (strcmp(cip->vbuf, ":default") != 0) {
3175 if (secflags_parse(NULL, cip->vbuf,
3176 &cip->secflag_delta) != 0) {
3177 err = mc_error_create(err, EINVAL, "couldn't parse "
3178 "security flags: %s", cip->vbuf);
3179 goto out;
3180 }
3181 }
3182
3183 /* get (optional) corefile pattern */
3184 if ((methpg != NULL && scf_pg_get_property(methpg,
3185 SCF_PROPERTY_COREFILE_PATTERN, prop) == SCF_SUCCESS) ||
3186 (instpg != NULL && scf_pg_get_property(instpg,
3187 SCF_PROPERTY_COREFILE_PATTERN, prop) == SCF_SUCCESS)) {
3188 if (scf_property_get_value(prop, val) != SCF_SUCCESS) {
3189 ret = scf_error();
3190 switch (ret) {
3191 case SCF_ERROR_CONNECTION_BROKEN:
3192 err = mc_error_create(err, ret, RCBROKEN);
3193 break;
3194
3195 case SCF_ERROR_CONSTRAINT_VIOLATED:
3409 * A method_context was not used for any configurable
3410 * elements or attributes, so reset and use the simple
3411 * defaults that provide historic init behavior.
3412 */
3413 if (mc_used == 0) {
3414 free(cip->pwbuf);
3415 free(cip->vbuf);
3416 free(cip->working_dir);
3417
3418 (void) memset(cip, 0, sizeof (*cip));
3419 cip->uid = 0;
3420 cip->gid = 0;
3421 cip->euid = (uid_t)-1;
3422 cip->egid = (gid_t)-1;
3423
3424 if (scf_default_secflags(h, &cip->def_secflags) != 0) {
3425 err = mc_error_create(err, EINVAL, "couldn't fetch "
3426 "default security-flags");
3427 goto out;
3428 }
3429 }
3430
3431 *mcpp = cip;
3432
3433 out:
3434 (void) scf_value_destroy(val);
3435 scf_property_destroy(prop);
3436 scf_pg_destroy(instpg);
3437 scf_pg_destroy(methpg);
3438
3439 if (cip->pwbuf != NULL) {
3440 free(cip->pwbuf);
3441 cip->pwbuf = NULL;
3442 }
3443
3444 free(cip->vbuf);
3445
3446 if (err->type != 0) {
3447 restarter_free_method_context(cip);
3448 } else {
3481 * EACCES - could not access working_dir (chdir)
3482 * in a TASK_FINAL task (setproject, settaskid)
3483 * no resource pool accepting default binding exists (setproject)
3484 * ELOOP - too many symbolic links in working_dir (chdir)
3485 * ENAMETOOLONG - working_dir is too long (chdir)
3486 * ENOLINK - working_dir is on an inaccessible remote machine (chdir)
3487 * ENOTDIR - working_dir is not a directory (chdir)
3488 * ESRCH - uid is not a user of project (setproject)
3489 * project is invalid (setproject)
3490 * the resource pool specified for project is unknown (setproject)
3491 * EBADF - the configuration for the pool is invalid (pool_set_binding)
3492 * -1 - core_set_process_path() failed (core_set_process_path)
3493 * a resource control assignment failed (setproject)
3494 * a system error occurred during pool_set_binding (pool_set_binding)
3495 */
3496 int
3497 restarter_set_method_context(struct method_context *cip, const char **fp)
3498 {
3499 pid_t mypid = -1;
3500 int r, ret;
3501
3502 cip->pwbuf = NULL;
3503 *fp = NULL;
3504
3505 if (cip->gid != (gid_t)-1) {
3506 if (setregid(cip->gid,
3507 cip->egid != (gid_t)-1 ? cip->egid : cip->gid) != 0) {
3508 *fp = "setregid";
3509
3510 ret = errno;
3511 assert(ret == EINVAL || ret == EPERM);
3512 goto out;
3513 }
3514 } else {
3515 if (cip->pwbuf == NULL) {
3516 switch (ret = lookup_pwd(cip)) {
3517 case 0:
3518 break;
3519
3520 case ENOMEM:
3577 setgroups(cip->ngroups, cip->groups) != 0) {
3578 *fp = "setgroups";
3579
3580 ret = errno;
3581 assert(ret == EINVAL || ret == EPERM);
3582 goto out;
3583 }
3584
3585 if (cip->corefile_pattern != NULL) {
3586 mypid = getpid();
3587
3588 if (core_set_process_path(cip->corefile_pattern,
3589 strlen(cip->corefile_pattern) + 1, mypid) != 0) {
3590 *fp = "core_set_process_path";
3591 ret = -1;
3592 goto out;
3593 }
3594 }
3595
3596
3597 if (psecflags(P_PID, P_MYID, PSF_INHERIT,
3598 &cip->def_secflags.ss_default) != 0) {
3599 *fp = "psecflags (default inherit)";
3600 ret = errno;
3601 goto out;
3602 }
3603
3604 if (psecflags(P_PID, P_MYID, PSF_LOWER,
3605 &cip->def_secflags.ss_lower) != 0) {
3606 *fp = "psecflags (default lower)";
3607 ret = errno;
3608 goto out;
3609 }
3610
3611 if (psecflags(P_PID, P_MYID, PSF_UPPER,
3612 &cip->def_secflags.ss_upper) != 0) {
3613 *fp = "psecflags (default upper)";
3614 ret = errno;
3615 goto out;
3616 }
3617
3618 if (psecflags(P_PID, P_MYID, PSF_INHERIT,
3619 &cip->secflag_delta) != 0) {
3620 *fp = "psecflags (from manifest)";
3621 ret = errno;
3622 goto out;
3623 }
3624
3625 if (restarter_rm_libs_loadable()) {
3626 if (cip->project == NULL) {
3627 if (settaskid(getprojid(), TASK_NORMAL) == -1) {
3628 switch (errno) {
3629 case EACCES:
3630 case EPERM:
3631 *fp = "settaskid";
3632 ret = errno;
3633 goto out;
3634
3635 case EINVAL:
3636 default:
3637 bad_fail("settaskid", errno);
3638 }
3639 }
3640 } else {
|