Print this page
smf: switch to a tri-state for process-security properties true=on,false=off,nil=default


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 {