| 2387 | } |
| 2388 | |
| 2389 | static struct mbuf * |
| 2390 | unp_addsockcred(struct thread *td, struct mbuf *control, int mode) |
| 2391 | { |
| 2392 | struct mbuf *m, *n, *n_prev; |
| 2393 | const struct cmsghdr *cm; |
| 2394 | int ngroups, i, cmsgtype; |
| 2395 | size_t ctrlsz; |
| 2396 | |
| 2397 | ngroups = MIN(td->td_ucred->cr_ngroups, CMGROUP_MAX); |
| 2398 | if (mode & UNP_WANTCRED_ALWAYS) { |
| 2399 | ctrlsz = SOCKCRED2SIZE(ngroups); |
| 2400 | cmsgtype = SCM_CREDS2; |
| 2401 | } else { |
| 2402 | ctrlsz = SOCKCREDSIZE(ngroups); |
| 2403 | cmsgtype = SCM_CREDS; |
| 2404 | } |
| 2405 | |
| 2406 | m = sbcreatecontrol(NULL, ctrlsz, cmsgtype, SOL_SOCKET); |
| 2407 | if (m == NULL) |
| 2408 | return (control); |
| 2409 | |
| 2410 | if (mode & UNP_WANTCRED_ALWAYS) { |
| 2411 | struct sockcred2 *sc; |
| 2412 | |
| 2413 | sc = (void *)CMSG_DATA(mtod(m, struct cmsghdr *)); |
| 2414 | sc->sc_version = 0; |
| 2415 | sc->sc_pid = td->td_proc->p_pid; |
| 2416 | sc->sc_uid = td->td_ucred->cr_ruid; |
| 2417 | sc->sc_euid = td->td_ucred->cr_uid; |
| 2418 | sc->sc_gid = td->td_ucred->cr_rgid; |
| 2419 | sc->sc_egid = td->td_ucred->cr_gid; |
| 2420 | sc->sc_ngroups = ngroups; |
| 2421 | for (i = 0; i < sc->sc_ngroups; i++) |
| 2422 | sc->sc_groups[i] = td->td_ucred->cr_groups[i]; |
| 2423 | } else { |
| 2424 | struct sockcred *sc; |
| 2425 | |
| 2426 | sc = (void *)CMSG_DATA(mtod(m, struct cmsghdr *)); |
| 2427 | sc->sc_uid = td->td_ucred->cr_ruid; |
| 2428 | sc->sc_euid = td->td_ucred->cr_uid; |
| 2429 | sc->sc_gid = td->td_ucred->cr_rgid; |
| 2430 | sc->sc_egid = td->td_ucred->cr_gid; |
| 2431 | sc->sc_ngroups = ngroups; |
| 2432 | for (i = 0; i < sc->sc_ngroups; i++) |
| 2433 | sc->sc_groups[i] = td->td_ucred->cr_groups[i]; |
| 2434 | } |
| 2435 | |
| 2436 | /* |
| 2437 | * Unlink SCM_CREDS control messages (struct cmsgcred), since just |
| 2438 | * created SCM_CREDS control message (struct sockcred) has another |
| 2439 | * format. |
| 2440 | */ |
| 2441 | if (control != NULL && cmsgtype == SCM_CREDS) |
| 2442 | for (n = control, n_prev = NULL; n != NULL;) { |
| 2443 | cm = mtod(n, struct cmsghdr *); |
| 2444 | if (cm->cmsg_level == SOL_SOCKET && |
| 2445 | cm->cmsg_type == SCM_CREDS) { |
| 2446 | if (n_prev == NULL) |
no test coverage detected