1*cd115652Schristos /* $NetBSD: user.c,v 1.3 2020/04/18 19:32:19 christos Exp $ */
2032a4398Schristos
30061c6a5Schristos /* Copyright 1988,1990,1993,1994 by Paul Vixie
40061c6a5Schristos * All rights reserved
50061c6a5Schristos */
60061c6a5Schristos
70061c6a5Schristos /*
80061c6a5Schristos * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
90061c6a5Schristos * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
100061c6a5Schristos *
110061c6a5Schristos * Permission to use, copy, modify, and distribute this software for any
120061c6a5Schristos * purpose with or without fee is hereby granted, provided that the above
130061c6a5Schristos * copyright notice and this permission notice appear in all copies.
140061c6a5Schristos *
150061c6a5Schristos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
160061c6a5Schristos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
170061c6a5Schristos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
180061c6a5Schristos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
190061c6a5Schristos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
200061c6a5Schristos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
210061c6a5Schristos * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
220061c6a5Schristos */
23032a4398Schristos #include <sys/cdefs.h>
240061c6a5Schristos #if !defined(lint) && !defined(LINT)
25032a4398Schristos #if 0
260061c6a5Schristos static char rcsid[] = "Id: user.c,v 1.5 2004/01/23 18:56:43 vixie Exp";
27032a4398Schristos +#else
28*cd115652Schristos +__RCSID("$NetBSD: user.c,v 1.3 2020/04/18 19:32:19 christos Exp $");
29032a4398Schristos #endif
300061c6a5Schristos #endif
310061c6a5Schristos
320061c6a5Schristos /* vix 26jan87 [log is in RCS file]
330061c6a5Schristos */
340061c6a5Schristos
350061c6a5Schristos #include "cron.h"
360061c6a5Schristos
370061c6a5Schristos void
free_user(user * u)380061c6a5Schristos free_user(user *u) {
390061c6a5Schristos entry *e, *ne;
400061c6a5Schristos
410061c6a5Schristos free(u->name);
420061c6a5Schristos for (e = u->crontab; e != NULL; e = ne) {
430061c6a5Schristos ne = e->next;
44*cd115652Schristos job_remove(e, u);
450061c6a5Schristos free_entry(e);
460061c6a5Schristos }
470061c6a5Schristos free(u);
480061c6a5Schristos }
490061c6a5Schristos
500061c6a5Schristos user *
load_user(int crontab_fd,struct passwd * pw,const char * name)510061c6a5Schristos load_user(int crontab_fd, struct passwd *pw, const char *name) {
520061c6a5Schristos char envstr[MAX_ENVSTR];
530061c6a5Schristos FILE *file;
540061c6a5Schristos user *u;
550061c6a5Schristos entry *e;
560061c6a5Schristos int status, save_errno;
570061c6a5Schristos char **envp, **tenvp;
580061c6a5Schristos
590061c6a5Schristos if (!(file = fdopen(crontab_fd, "r"))) {
600061c6a5Schristos perror("fdopen on crontab_fd in load_user");
610061c6a5Schristos return (NULL);
620061c6a5Schristos }
630061c6a5Schristos
64032a4398Schristos Debug(DPARS, ("load_user()\n"));
650061c6a5Schristos
660061c6a5Schristos /* file is open. build user entry, then read the crontab file.
670061c6a5Schristos */
68032a4398Schristos if ((u = malloc(sizeof(*u))) == NULL)
690061c6a5Schristos return (NULL);
700061c6a5Schristos if ((u->name = strdup(name)) == NULL) {
710061c6a5Schristos save_errno = errno;
720061c6a5Schristos free(u);
730061c6a5Schristos errno = save_errno;
740061c6a5Schristos return (NULL);
750061c6a5Schristos }
760061c6a5Schristos u->crontab = NULL;
770061c6a5Schristos
780061c6a5Schristos /* init environment. this will be copied/augmented for each entry.
790061c6a5Schristos */
800061c6a5Schristos if ((envp = env_init()) == NULL) {
810061c6a5Schristos save_errno = errno;
820061c6a5Schristos free(u->name);
830061c6a5Schristos free(u);
840061c6a5Schristos errno = save_errno;
850061c6a5Schristos return (NULL);
860061c6a5Schristos }
870061c6a5Schristos
880061c6a5Schristos /* load the crontab
890061c6a5Schristos */
900061c6a5Schristos while ((status = load_env(envstr, file)) >= OK) {
910061c6a5Schristos switch (status) {
920061c6a5Schristos case ERR:
930061c6a5Schristos free_user(u);
940061c6a5Schristos u = NULL;
950061c6a5Schristos goto done;
960061c6a5Schristos case FALSE:
970061c6a5Schristos e = load_entry(file, NULL, pw, envp);
980061c6a5Schristos if (e) {
990061c6a5Schristos e->next = u->crontab;
1000061c6a5Schristos u->crontab = e;
1010061c6a5Schristos }
1020061c6a5Schristos break;
1030061c6a5Schristos case TRUE:
1040061c6a5Schristos if ((tenvp = env_set(envp, envstr)) == NULL) {
1050061c6a5Schristos save_errno = errno;
1060061c6a5Schristos free_user(u);
1070061c6a5Schristos u = NULL;
1080061c6a5Schristos errno = save_errno;
1090061c6a5Schristos goto done;
1100061c6a5Schristos }
1110061c6a5Schristos envp = tenvp;
1120061c6a5Schristos break;
1130061c6a5Schristos }
1140061c6a5Schristos }
1150061c6a5Schristos
1160061c6a5Schristos done:
1170061c6a5Schristos env_free(envp);
118032a4398Schristos (void)fclose(file);
119032a4398Schristos Debug(DPARS, ("...load_user() done\n"));
1200061c6a5Schristos return (u);
1210061c6a5Schristos }
122