hfingerd

hhvn.uk:79
Log | Files | Refs | LICENSE

commit 921d563a92567c81a7f8597c140afbe9adaf17b7
parent 43967ebf07c808f9a565cf8ab96b73aa49e47577
Author: hhvn <dev@hhvn.uk>
Date:   Sat,  5 Jun 2021 19:56:24 +0100

main.c: get raw .plan files

Diffstat:
Mmain.c | 78+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 65 insertions(+), 13 deletions(-)

diff --git a/main.c b/main.c @@ -16,15 +16,16 @@ #define EXIT_USAGE 2 #define CQUEUE 255 -/* strings for getaddrinfo() */ -#define HOST_DFLT "localhost" -#define PORT_DFLT "79" +/* defaults, must be strings to replace args */ +char *host = "localhost", + *port = "79", + *planfile = ".plan"; char *argv0; void usage(void) { - printf("usage: %s [-h host] [-p port]\n", basename(argv0)); + printf("usage: %s [-h host] [-p port] [-f planfile]\n", basename(argv0)); exit(EXIT_USAGE); } @@ -111,8 +112,60 @@ get_userlist(int fd) { void get_plan(int fd, char *user) { - /* TODO */ - return; + struct passwd *udata; + char path[1024]; + char buf[4096]; + int serrno; + FILE *plan; + + errno = 0; + if ((udata = getpwnam(user)) == NULL) { + serrno = errno; + if (serrno == 0) { + dprintf(fd, "Error: no such user: %s\n", user); + } else { + dprintf(fd, "Server-side error: %s\n", strerror(serrno)); + error("getpwnam(): %s\n", strerror(serrno)); + } + } + + /* drop priviledges to user */ + if (setuid(udata->pw_uid) == -1) + error("setuid(): %s\n", strerror(errno)); + + snprintf(path, sizeof(path), "%s/%s", udata->pw_dir, planfile); + if (access(path, R_OK) == -1) { + serrno = errno; + switch (serrno) { + case ENOTDIR: + case ENOENT: + dprintf(fd, "Error: user %s does not have a %s file\n", + user, planfile); + break; + default: + dprintf(fd, "Error: cannot access user's %s file: %s\n", + planfile, strerror(serrno)); + error("access(): %s: %s\n", path, strerror(serrno)); + } + return; + } + + /* TODO: check if executable + * and implement "CGI" */ + + if ((plan = fopen(path, "rb")) == NULL) { + serrno = errno; + dprintf(fd, "Error: cannot read user's %s file: %s\n", + planfile, strerror(serrno)); + error("fopen(): %s\n", strerror(serrno)); + return; + } + + /* copy file to fd */ + while (fgets(buf, sizeof(buf), plan) != NULL) + write(fd, buf, strlen(buf)); + /* don't use sizeof(buf), + * or you get heartbleed for free */ } void @@ -131,26 +184,25 @@ int main(int argc, char *argv[]) { struct sockaddr *addr; struct addrinfo hints; - char *host = NULL, - *port = NULL; int sock, handle; int serrno; pid_t pid; ARGBEGIN { case 'h': + free(host); host = EARGF(usage()); break; case 'p': + free(port); port = EARGF(usage()); break; + case 'f': + free(planfile); + planfile = EARGF(usage()); + break; } ARGEND; - if (host == NULL) - host = HOST_DFLT; - if (port == NULL) - port = PORT_DFLT; - memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_flags = AI_PASSIVE;