36 #include <errno.h>
37 #include <exec_attr.h>
38 #include <grp.h>
39 #include <libsysevent.h>
40 #include <libuutil.h>
41 #include <limits.h>
42 #include <link.h>
43 #include <malloc.h>
44 #include <pool.h>
45 #include <priv.h>
46 #include <project.h>
47 #include <pthread.h>
48 #include <pwd.h>
49 #include <secdb.h>
50 #include <signal.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <syslog.h>
54 #include <sys/corectl.h>
55 #include <sys/machelf.h>
56 #include <sys/task.h>
57 #include <sys/types.h>
58 #include <time.h>
59 #include <unistd.h>
60 #include <ucontext.h>
61
62 #define min(a, b) ((a) > (b) ? (b) : (a))
63
64 #define MKW_TRUE ":true"
65 #define MKW_KILL ":kill"
66 #define MKW_KILL_PROC ":kill_process"
67
68 #define ALLOCFAIL ((char *)"Allocation failure.")
69 #define RCBROKEN ((char *)"Repository connection broken.")
70
71 #define MAX_COMMIT_RETRIES 10
72 #define MAX_COMMIT_RETRY_INT (5 * 1000000) /* 5 seconds */
73 #define INITIAL_COMMIT_RETRY_INT (10000) /* 1/100th second */
74
75 /*
2826
2827 (void) memset(cip, 0, sizeof (*cip));
2828 cip->uid = (uid_t)-1;
2829 cip->euid = (uid_t)-1;
2830 cip->gid = (gid_t)-1;
2831 cip->egid = (gid_t)-1;
2832
2833 cip->vbuf_sz = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH);
2834 assert(cip->vbuf_sz >= 0);
2835 cip->vbuf = malloc(cip->vbuf_sz);
2836 if (cip->vbuf == NULL) {
2837 free(cip);
2838 return (mc_error_create(err, ENOMEM, ALLOCFAIL));
2839 }
2840
2841 if ((instpg = scf_pg_create(h)) == NULL ||
2842 (methpg = scf_pg_create(h)) == NULL ||
2843 (prop = scf_property_create(h)) == NULL ||
2844 (val = scf_value_create(h)) == NULL) {
2845 err = mc_error_create(err, scf_error(),
2846 "Failed to create repository object: %s\n",
2847 scf_strerror(scf_error()));
2848 goto out;
2849 }
2850
2851 /*
2852 * The method environment, and the credentials/profile data,
2853 * may be found either in the pg for the method (methpg),
2854 * or in the instance/service SCF_PG_METHOD_CONTEXT pg (named
2855 * instpg below).
2856 */
2857
2858 if (scf_instance_get_pg_composed(inst, snap, mname, methpg) !=
2859 SCF_SUCCESS) {
2860 err = mc_error_create(err, scf_error(), "Unable to get the "
2861 "\"%s\" method, %s", mname, scf_strerror(scf_error()));
2862 goto out;
2863 }
2864
2865 if (scf_instance_get_pg_composed(inst, snap, SCF_PG_METHOD_CONTEXT,
2866 instpg) != SCF_SUCCESS) {
2878
2879 ret = get_environment(h, methpg, cip, prop, val);
2880 if (ret == ENOENT && instpg != NULL) {
2881 ret = get_environment(h, instpg, cip, prop, val);
2882 }
2883
2884 switch (ret) {
2885 case 0:
2886 mc_used++;
2887 break;
2888 case ENOENT:
2889 break;
2890 case ENOMEM:
2891 err = mc_error_create(err, ret, "Out of memory.");
2892 goto out;
2893 case EINVAL:
2894 err = mc_error_create(err, ret, "Invalid method environment.");
2895 goto out;
2896 default:
2897 err = mc_error_create(err, ret,
2898 "Get method environment failed : %s\n", scf_strerror(ret));
2899 goto out;
2900 }
2901
2902 pg = methpg;
2903
2904 ret = scf_pg_get_property(pg, SCF_PROPERTY_USE_PROFILE, prop);
2905 if (ret && scf_error() == SCF_ERROR_NOT_FOUND && instpg != NULL) {
2906 pg = NULL;
2907 ret = scf_pg_get_property(instpg, SCF_PROPERTY_USE_PROFILE,
2908 prop);
2909 }
2910
2911 if (ret) {
2912 switch (scf_error()) {
2913 case SCF_ERROR_NOT_FOUND:
2914 /* No profile context: use default credentials */
2915 cip->uid = 0;
2916 cip->gid = 0;
2917 break;
2918
3086 "Could not get passwd entry.");
3087 goto out;
3088
3089 default:
3090 bad_fail("lookup_pwd", ret);
3091 }
3092
3093 cip->working_dir = strdup(cip->pwd.pw_dir);
3094 if (cip->working_dir == NULL) {
3095 err = mc_error_create(err, ENOMEM, ALLOCFAIL);
3096 goto out;
3097 }
3098 } else {
3099 cip->working_dir = strdup(cip->vbuf);
3100 if (cip->working_dir == NULL) {
3101 err = mc_error_create(err, ENOMEM, ALLOCFAIL);
3102 goto out;
3103 }
3104 }
3105
3106 /* get (optional) corefile pattern */
3107 if ((methpg != NULL && scf_pg_get_property(methpg,
3108 SCF_PROPERTY_COREFILE_PATTERN, prop) == SCF_SUCCESS) ||
3109 (instpg != NULL && scf_pg_get_property(instpg,
3110 SCF_PROPERTY_COREFILE_PATTERN, prop) == SCF_SUCCESS)) {
3111 if (scf_property_get_value(prop, val) != SCF_SUCCESS) {
3112 ret = scf_error();
3113 switch (ret) {
3114 case SCF_ERROR_CONNECTION_BROKEN:
3115 err = mc_error_create(err, ret, RCBROKEN);
3116 break;
3117
3118 case SCF_ERROR_CONSTRAINT_VIOLATED:
3119 err = mc_error_create(err, ret,
3120 "\"%s\" property has multiple values.",
3121 SCF_PROPERTY_COREFILE_PATTERN);
3122 break;
3123
3124 case SCF_ERROR_NOT_FOUND:
3125 err = mc_error_create(err, ret,
3326 goto out;
3327 }
3328 }
3329 }
3330
3331 /*
3332 * A method_context was not used for any configurable
3333 * elements or attributes, so reset and use the simple
3334 * defaults that provide historic init behavior.
3335 */
3336 if (mc_used == 0) {
3337 free(cip->pwbuf);
3338 free(cip->vbuf);
3339 free(cip->working_dir);
3340
3341 (void) memset(cip, 0, sizeof (*cip));
3342 cip->uid = 0;
3343 cip->gid = 0;
3344 cip->euid = (uid_t)-1;
3345 cip->egid = (gid_t)-1;
3346 }
3347
3348 *mcpp = cip;
3349
3350 out:
3351 (void) scf_value_destroy(val);
3352 scf_property_destroy(prop);
3353 scf_pg_destroy(instpg);
3354 scf_pg_destroy(methpg);
3355
3356 if (cip->pwbuf != NULL) {
3357 free(cip->pwbuf);
3358 cip->pwbuf = NULL;
3359 }
3360
3361 free(cip->vbuf);
3362
3363 if (err->type != 0) {
3364 restarter_free_method_context(cip);
3365 } else {
3398 * EACCES - could not access working_dir (chdir)
3399 * in a TASK_FINAL task (setproject, settaskid)
3400 * no resource pool accepting default binding exists (setproject)
3401 * ELOOP - too many symbolic links in working_dir (chdir)
3402 * ENAMETOOLONG - working_dir is too long (chdir)
3403 * ENOLINK - working_dir is on an inaccessible remote machine (chdir)
3404 * ENOTDIR - working_dir is not a directory (chdir)
3405 * ESRCH - uid is not a user of project (setproject)
3406 * project is invalid (setproject)
3407 * the resource pool specified for project is unknown (setproject)
3408 * EBADF - the configuration for the pool is invalid (pool_set_binding)
3409 * -1 - core_set_process_path() failed (core_set_process_path)
3410 * a resource control assignment failed (setproject)
3411 * a system error occurred during pool_set_binding (pool_set_binding)
3412 */
3413 int
3414 restarter_set_method_context(struct method_context *cip, const char **fp)
3415 {
3416 pid_t mypid = -1;
3417 int r, ret;
3418
3419 cip->pwbuf = NULL;
3420 *fp = NULL;
3421
3422 if (cip->gid != (gid_t)-1) {
3423 if (setregid(cip->gid,
3424 cip->egid != (gid_t)-1 ? cip->egid : cip->gid) != 0) {
3425 *fp = "setregid";
3426
3427 ret = errno;
3428 assert(ret == EINVAL || ret == EPERM);
3429 goto out;
3430 }
3431 } else {
3432 if (cip->pwbuf == NULL) {
3433 switch (ret = lookup_pwd(cip)) {
3434 case 0:
3435 break;
3436
3437 case ENOMEM:
3493 } else if (cip->ngroups > 0 &&
3494 setgroups(cip->ngroups, cip->groups) != 0) {
3495 *fp = "setgroups";
3496
3497 ret = errno;
3498 assert(ret == EINVAL || ret == EPERM);
3499 goto out;
3500 }
3501
3502 if (cip->corefile_pattern != NULL) {
3503 mypid = getpid();
3504
3505 if (core_set_process_path(cip->corefile_pattern,
3506 strlen(cip->corefile_pattern) + 1, mypid) != 0) {
3507 *fp = "core_set_process_path";
3508 ret = -1;
3509 goto out;
3510 }
3511 }
3512
3513 if (restarter_rm_libs_loadable()) {
3514 if (cip->project == NULL) {
3515 if (settaskid(getprojid(), TASK_NORMAL) == -1) {
3516 switch (errno) {
3517 case EACCES:
3518 case EPERM:
3519 *fp = "settaskid";
3520 ret = errno;
3521 goto out;
3522
3523 case EINVAL:
3524 default:
3525 bad_fail("settaskid", errno);
3526 }
3527 }
3528 } else {
3529 switch (ret = lookup_pwd(cip)) {
3530 case 0:
3531 break;
3532
|
36 #include <errno.h>
37 #include <exec_attr.h>
38 #include <grp.h>
39 #include <libsysevent.h>
40 #include <libuutil.h>
41 #include <limits.h>
42 #include <link.h>
43 #include <malloc.h>
44 #include <pool.h>
45 #include <priv.h>
46 #include <project.h>
47 #include <pthread.h>
48 #include <pwd.h>
49 #include <secdb.h>
50 #include <signal.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <syslog.h>
54 #include <sys/corectl.h>
55 #include <sys/machelf.h>
56 #include <sys/secflags.h>
57 #include <sys/task.h>
58 #include <sys/types.h>
59 #include <time.h>
60 #include <unistd.h>
61 #include <ucontext.h>
62
63 #define min(a, b) ((a) > (b) ? (b) : (a))
64
65 #define MKW_TRUE ":true"
66 #define MKW_KILL ":kill"
67 #define MKW_KILL_PROC ":kill_process"
68
69 #define ALLOCFAIL ((char *)"Allocation failure.")
70 #define RCBROKEN ((char *)"Repository connection broken.")
71
72 #define MAX_COMMIT_RETRIES 10
73 #define MAX_COMMIT_RETRY_INT (5 * 1000000) /* 5 seconds */
74 #define INITIAL_COMMIT_RETRY_INT (10000) /* 1/100th second */
75
76 /*
2827
2828 (void) memset(cip, 0, sizeof (*cip));
2829 cip->uid = (uid_t)-1;
2830 cip->euid = (uid_t)-1;
2831 cip->gid = (gid_t)-1;
2832 cip->egid = (gid_t)-1;
2833
2834 cip->vbuf_sz = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH);
2835 assert(cip->vbuf_sz >= 0);
2836 cip->vbuf = malloc(cip->vbuf_sz);
2837 if (cip->vbuf == NULL) {
2838 free(cip);
2839 return (mc_error_create(err, ENOMEM, ALLOCFAIL));
2840 }
2841
2842 if ((instpg = scf_pg_create(h)) == NULL ||
2843 (methpg = scf_pg_create(h)) == NULL ||
2844 (prop = scf_property_create(h)) == NULL ||
2845 (val = scf_value_create(h)) == NULL) {
2846 err = mc_error_create(err, scf_error(),
2847 "Failed to create repository object: %s",
2848 scf_strerror(scf_error()));
2849 goto out;
2850 }
2851
2852 /*
2853 * The method environment, and the credentials/profile data,
2854 * may be found either in the pg for the method (methpg),
2855 * or in the instance/service SCF_PG_METHOD_CONTEXT pg (named
2856 * instpg below).
2857 */
2858
2859 if (scf_instance_get_pg_composed(inst, snap, mname, methpg) !=
2860 SCF_SUCCESS) {
2861 err = mc_error_create(err, scf_error(), "Unable to get the "
2862 "\"%s\" method, %s", mname, scf_strerror(scf_error()));
2863 goto out;
2864 }
2865
2866 if (scf_instance_get_pg_composed(inst, snap, SCF_PG_METHOD_CONTEXT,
2867 instpg) != SCF_SUCCESS) {
2879
2880 ret = get_environment(h, methpg, cip, prop, val);
2881 if (ret == ENOENT && instpg != NULL) {
2882 ret = get_environment(h, instpg, cip, prop, val);
2883 }
2884
2885 switch (ret) {
2886 case 0:
2887 mc_used++;
2888 break;
2889 case ENOENT:
2890 break;
2891 case ENOMEM:
2892 err = mc_error_create(err, ret, "Out of memory.");
2893 goto out;
2894 case EINVAL:
2895 err = mc_error_create(err, ret, "Invalid method environment.");
2896 goto out;
2897 default:
2898 err = mc_error_create(err, ret,
2899 "Get method environment failed: %s", scf_strerror(ret));
2900 goto out;
2901 }
2902
2903 pg = methpg;
2904
2905 ret = scf_pg_get_property(pg, SCF_PROPERTY_USE_PROFILE, prop);
2906 if (ret && scf_error() == SCF_ERROR_NOT_FOUND && instpg != NULL) {
2907 pg = NULL;
2908 ret = scf_pg_get_property(instpg, SCF_PROPERTY_USE_PROFILE,
2909 prop);
2910 }
2911
2912 if (ret) {
2913 switch (scf_error()) {
2914 case SCF_ERROR_NOT_FOUND:
2915 /* No profile context: use default credentials */
2916 cip->uid = 0;
2917 cip->gid = 0;
2918 break;
2919
3087 "Could not get passwd entry.");
3088 goto out;
3089
3090 default:
3091 bad_fail("lookup_pwd", ret);
3092 }
3093
3094 cip->working_dir = strdup(cip->pwd.pw_dir);
3095 if (cip->working_dir == NULL) {
3096 err = mc_error_create(err, ENOMEM, ALLOCFAIL);
3097 goto out;
3098 }
3099 } else {
3100 cip->working_dir = strdup(cip->vbuf);
3101 if (cip->working_dir == NULL) {
3102 err = mc_error_create(err, ENOMEM, ALLOCFAIL);
3103 goto out;
3104 }
3105 }
3106
3107 /* get security flags */
3108 if ((methpg != NULL && scf_pg_get_property(methpg,
3109 SCF_PROPERTY_SECFLAGS, prop) == SCF_SUCCESS) ||
3110 (instpg != NULL && scf_pg_get_property(instpg,
3111 SCF_PROPERTY_SECFLAGS, prop) == SCF_SUCCESS)) {
3112 if (scf_property_get_value(prop, val) != SCF_SUCCESS) {
3113 ret = scf_error();
3114 switch (ret) {
3115 case SCF_ERROR_CONNECTION_BROKEN:
3116 err = mc_error_create(err, ret, RCBROKEN);
3117 break;
3118
3119 case SCF_ERROR_CONSTRAINT_VIOLATED:
3120 err = mc_error_create(err, ret,
3121 "\"%s\" property has multiple values.",
3122 SCF_PROPERTY_SECFLAGS);
3123 break;
3124
3125 case SCF_ERROR_NOT_FOUND:
3126 err = mc_error_create(err, ret,
3127 "\"%s\" property has no values.",
3128 SCF_PROPERTY_SECFLAGS);
3129 break;
3130
3131 default:
3132 bad_fail("scf_property_get_value", ret);
3133 }
3134
3135 (void) strlcpy(cip->vbuf, ":default", cip->vbuf_sz);
3136 } else {
3137 ret = scf_value_get_astring(val, cip->vbuf,
3138 cip->vbuf_sz);
3139 assert(ret != -1);
3140 }
3141 mc_used++;
3142 } else {
3143 ret = scf_error();
3144 switch (ret) {
3145 case SCF_ERROR_NOT_FOUND:
3146 /* okay if missing. */
3147 (void) strlcpy(cip->vbuf, ":default", cip->vbuf_sz);
3148 break;
3149
3150 case SCF_ERROR_CONNECTION_BROKEN:
3151 err = mc_error_create(err, ret, RCBROKEN);
3152 goto out;
3153
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:
3203 err = mc_error_create(err, ret,
3204 "\"%s\" property has multiple values.",
3205 SCF_PROPERTY_COREFILE_PATTERN);
3206 break;
3207
3208 case SCF_ERROR_NOT_FOUND:
3209 err = mc_error_create(err, ret,
3410 goto out;
3411 }
3412 }
3413 }
3414
3415 /*
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:
3591 } else if (cip->ngroups > 0 &&
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 {
3660 switch (ret = lookup_pwd(cip)) {
3661 case 0:
3662 break;
3663
|