xref: /openbsd/usr.sbin/cron/client.c (revision 09467b48)
1 /*	$OpenBSD: client.c,v 1.10 2018/07/13 08:39:33 krw Exp $	*/
2 
3 /* Copyright 1988,1990,1993,1994 by Paul Vixie
4  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <sys/stat.h>
23 #include <sys/un.h>
24 
25 #include <bitstring.h>		/* for structs.h */
26 #include <err.h>
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <time.h>		/* for structs.h */
32 #include <unistd.h>
33 
34 #include "pathnames.h"
35 #include "macros.h"
36 #include "structs.h"
37 #include "funcs.h"
38 #include "globals.h"
39 
40 /* int in_file(const char *string, FILE *file, int error)
41  *	return TRUE if one of the lines in file matches string exactly,
42  *	FALSE if no lines match, and error on error.
43  */
44 static int
45 in_file(const char *string, FILE *file, int error)
46 {
47 	char line[MAX_TEMPSTR];
48 	char *endp;
49 
50 	if (fseek(file, 0L, SEEK_SET))
51 		return (error);
52 	while (fgets(line, MAX_TEMPSTR, file)) {
53 		if (line[0] != '\0') {
54 			endp = &line[strlen(line) - 1];
55 			if (*endp != '\n')
56 				return (error);
57 			*endp = '\0';
58 			if (0 == strcmp(line, string))
59 				return (TRUE);
60 		}
61 	}
62 	if (ferror(file))
63 		return (error);
64 	return (FALSE);
65 }
66 
67 /* int allowed(const char *username, const char *allow_file, const char *deny_file)
68  *	returns TRUE if (allow_file exists and user is listed)
69  *	or (deny_file exists and user is NOT listed).
70  *	root is always allowed.
71  */
72 int
73 allowed(const char *username, const char *allow_file, const char *deny_file)
74 {
75 	FILE	*fp;
76 	int	isallowed;
77 
78 	if (strcmp(username, "root") == 0)
79 		return (TRUE);
80 	isallowed = FALSE;
81 	if ((fp = fopen(allow_file, "r")) != NULL) {
82 		isallowed = in_file(username, fp, FALSE);
83 		fclose(fp);
84 	} else if ((fp = fopen(deny_file, "r")) != NULL) {
85 		isallowed = !in_file(username, fp, FALSE);
86 		fclose(fp);
87 	}
88 	return (isallowed);
89 }
90 
91 /* void poke_daemon(unsigned char cookie)
92  *	touches spool_dir and sends a poke to the cron daemon if running.
93  */
94 void
95 poke_daemon(unsigned char cookie)
96 {
97 	int sock = -1;
98 	const char *cronsock = _PATH_CRON_SOCK;
99 	struct sockaddr_un s_un;
100 
101 	bzero(&s_un, sizeof(s_un));
102 	if (strlcpy(s_un.sun_path, cronsock, sizeof(s_un.sun_path)) >=
103 	    sizeof(s_un.sun_path)) {
104 		warnc(ENAMETOOLONG, "%s", cronsock);
105 		return;
106 	}
107 	s_un.sun_family = AF_UNIX;
108 	if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0 &&
109 	    connect(sock, (struct sockaddr *)&s_un, sizeof(s_un)) == 0)
110 		send(sock, &cookie, 1, MSG_NOSIGNAL);
111 	else
112 		warnx("warning, cron does not appear to be running");
113 	if (sock >= 0)
114 		close(sock);
115 }
116