commit bb12a5063c996cf9604bfcb3c6c459d8dbf1771d from: Stefan Sperling via: Thomas Adam date: Sat Dec 30 18:51:43 2023 UTC make the gotd auth process provide the user's account name for later use with tweaks from + ok op@ commit - a7cf3076b06abc153debc994e54adfb606bd77f9 commit + bb12a5063c996cf9604bfcb3c6c459d8dbf1771d blob - 483a3722ebfbc592bd2cab15cfd7c13fb9fa3b20 blob + 5b26d6d8645a84a229ccc5481c0b41026ec9b0e2 --- gotd/auth.c +++ gotd/auth.c @@ -128,8 +128,8 @@ match_identifier(const char *identifier, gid_t *groups } static const struct got_error * -auth_check(struct gotd_access_rule_list *rules, const char *repo_name, - uid_t euid, gid_t egid, int required_auth) +auth_check(char **username, struct gotd_access_rule_list *rules, + const char *repo_name, uid_t euid, gid_t egid, int required_auth) { struct gotd_access_rule *rule; enum gotd_access access = GOTD_ACCESS_DENIED; @@ -137,6 +137,8 @@ auth_check(struct gotd_access_rule_list *rules, const gid_t groups[NGROUPS_MAX]; int ngroups = NGROUPS_MAX; + *username = NULL; + pw = getpwuid(euid); if (pw == NULL) { if (errno) @@ -145,6 +147,10 @@ auth_check(struct gotd_access_rule_list *rules, const return got_error_set_errno(EACCES, repo_name); } + *username = strdup(pw->pw_name); + if (*username == NULL) + return got_error_from_errno("strdup"); + if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups) == -1) log_warnx("group membership list truncated"); @@ -178,6 +184,9 @@ recv_authreq(struct imsg *imsg, struct gotd_imsgev *ie size_t datalen; uid_t euid; gid_t egid; + char *username = NULL; + size_t len; + const size_t maxlen = MAX_IMSGSIZE - IMSG_HEADER_SIZE; log_debug("authentication request received"); @@ -200,18 +209,23 @@ recv_authreq(struct imsg *imsg, struct gotd_imsgev *ie log_debug("authenticating uid %d gid %d", euid, egid); - err = auth_check(&gotd_auth.repo->rules, gotd_auth.repo->name, - iauth.euid, iauth.egid, iauth.required_auth); + err = auth_check(&username, &gotd_auth.repo->rules, + gotd_auth.repo->name, iauth.euid, iauth.egid, iauth.required_auth); if (err) { gotd_imsg_send_error(ibuf, PROC_AUTH, iauth.client_id, err); - return err; + goto done; } - if (gotd_imsg_compose_event(iev, GOTD_IMSG_ACCESS_GRANTED, - PROC_AUTH, -1, NULL, 0) == -1) - return got_error_from_errno("imsg compose ACCESS_GRANTED"); + len = strlen(username); + if (len > maxlen) + len = maxlen; - return NULL; + if (gotd_imsg_compose_event(iev, GOTD_IMSG_ACCESS_GRANTED, + PROC_AUTH, -1, username, len) == -1) + err = got_error_from_errno("imsg compose ACCESS_GRANTED"); +done: + free(username); + return err; } static void blob - dafb216803ec687b6793acf3edd8ffbe9c926e5d blob + d826e23d32b5dd5a3d5b55e14ebc06a0159947db --- gotd/gotd.c +++ gotd/gotd.c @@ -94,6 +94,7 @@ struct gotd_client { struct event tmo; uid_t euid; gid_t egid; + char *username; struct gotd_child_proc *repo; struct gotd_child_proc *auth; struct gotd_child_proc *session; @@ -382,6 +383,7 @@ disconnect(struct gotd_client *client) close(client->fd); else if (client->iev.ibuf.fd != -1) close(client->iev.ibuf.fd); + free(client->username); free(client); client_cnt--; } @@ -1144,6 +1146,7 @@ gotd_dispatch_auth_child(int fd, short event, void *ar struct imsg imsg; uint32_t client_id = 0; int do_disconnect = 0; + size_t datalen; client = find_client_by_proc_fd(fd); if (client == NULL) { @@ -1187,13 +1190,18 @@ gotd_dispatch_auth_child(int fd, short event, void *ar evtimer_del(&client->tmo); + datalen = imsg.hdr.len - IMSG_HEADER_SIZE; + switch (imsg.hdr.type) { case GOTD_IMSG_ERROR: do_disconnect = 1; err = gotd_imsg_recv_error(&client_id, &imsg); break; case GOTD_IMSG_ACCESS_GRANTED: - client->state = GOTD_CLIENT_STATE_ACCESS_GRANTED; + if (client->state != GOTD_CLIENT_STATE_NEW) { + do_disconnect = 1; + err = got_error(GOT_ERR_PRIVSEP_MSG); + } break; default: do_disconnect = 1; @@ -1206,14 +1214,24 @@ gotd_dispatch_auth_child(int fd, short event, void *ar log_debug("dropping imsg type %d from PID %d", imsg.hdr.type, client->auth->pid); } - imsg_free(&imsg); if (do_disconnect) { if (err) disconnect_on_error(client, err); else disconnect(client); + imsg_free(&imsg); return; + } + + client->state = GOTD_CLIENT_STATE_ACCESS_GRANTED; + if (datalen > 0) + client->username = strndup(imsg.data, datalen); + imsg_free(&imsg); + if (client->username == NULL && + asprintf(&client->username, "uid %d", client->euid) == -1) { + err = got_error_from_errno("asprintf"); + goto done; } repo = gotd_find_repo_by_name(client->auth->repo_name, &gotd); @@ -1223,8 +1241,8 @@ gotd_dispatch_auth_child(int fd, short event, void *ar } kill_auth_proc(client); - log_info("authenticated uid %d for repository %s", - client->euid, repo->name); + log_info("authenticated %s for repository %s", + client->username, repo->name); err = start_session_child(client, repo, gotd.argv0, gotd.confpath, gotd.daemonize, gotd.verbosity);