1*46731Skarels /*
2*46731Skarels  * $Source: /mit/kerberos/src/admin/RCS/kdb_edit.c,v $
3*46731Skarels  * $Author: jtkohl $
4*46731Skarels  *
5*46731Skarels  * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
6*46731Skarels  * of Technology.
7*46731Skarels  *
8*46731Skarels  * For copying and distribution information, please see the file
9*46731Skarels  * <mit-copyright.h>.
10*46731Skarels  *
11*46731Skarels  * This routine changes the Kerberos encryption keys for principals,
12*46731Skarels  * i.e., users or services.
13*46731Skarels  */
14*46731Skarels 
15*46731Skarels /*
16*46731Skarels  * exit returns 	 0 ==> success -1 ==> error
17*46731Skarels  */
18*46731Skarels 
19*46731Skarels #ifndef	lint
20*46731Skarels static char rcsid_kdb_edit_c[] =
21*46731Skarels "$Header: kdb_edit.c,v 4.1 89/03/23 09:58:18 jtkohl Exp $";
22*46731Skarels #endif	lint
23*46731Skarels 
24*46731Skarels #include <mit-copyright.h>
25*46731Skarels 
26*46731Skarels #include <stdio.h>
27*46731Skarels #include <signal.h>
28*46731Skarels #include <errno.h>
29*46731Skarels #include <strings.h>
30*46731Skarels #include <sys/ioctl.h>
31*46731Skarels #include <sys/file.h>
32*46731Skarels #include "time.h"
33*46731Skarels #include <des.h>
34*46731Skarels #include <krb.h>
35*46731Skarels #include <krb_db.h>
36*46731Skarels /* MKEYFILE is now defined in kdc.h */
37*46731Skarels #include <kdc.h>
38*46731Skarels 
39*46731Skarels extern char *errmsg();
40*46731Skarels extern int errno;
41*46731Skarels extern char *strcpy();
42*46731Skarels 
43*46731Skarels void    sig_exit();
44*46731Skarels 
45*46731Skarels char    prog[32];
46*46731Skarels char   *progname = prog;
47*46731Skarels int     nflag = 0;
48*46731Skarels int     cflag;
49*46731Skarels int     lflag;
50*46731Skarels int     uflag;
51*46731Skarels int     debug;
52*46731Skarels extern  kerb_debug;
53*46731Skarels extern char *sys_errlist[];
54*46731Skarels 
55*46731Skarels Key_schedule KS;
56*46731Skarels C_Block new_key;
57*46731Skarels unsigned char *input;
58*46731Skarels 
59*46731Skarels unsigned char *ivec;
60*46731Skarels int     i, j;
61*46731Skarels int     more;
62*46731Skarels 
63*46731Skarels char   *in_ptr;
64*46731Skarels char    input_name[ANAME_SZ];
65*46731Skarels char    input_instance[INST_SZ];
66*46731Skarels char    input_string[ANAME_SZ];
67*46731Skarels 
68*46731Skarels #define	MAX_PRINCIPAL	10
69*46731Skarels Principal principal_data[MAX_PRINCIPAL];
70*46731Skarels 
71*46731Skarels static Principal old_principal;
72*46731Skarels static Principal default_princ;
73*46731Skarels 
74*46731Skarels static C_Block master_key;
75*46731Skarels static C_Block session_key;
76*46731Skarels static Key_schedule master_key_schedule;
77*46731Skarels static char pw_str[255];
78*46731Skarels static long master_key_version;
79*46731Skarels 
80*46731Skarels main(argc, argv)
81*46731Skarels     int     argc;
82*46731Skarels     char   *argv[];
83*46731Skarels 
84*46731Skarels {
85*46731Skarels     /* Local Declarations */
86*46731Skarels 
87*46731Skarels     long    n;
88*46731Skarels 
89*46731Skarels     prog[sizeof prog - 1] = '\0';	/* make sure terminated */
90*46731Skarels     strncpy(prog, argv[0], sizeof prog - 1);	/* salt away invoking
91*46731Skarels 						 * program */
92*46731Skarels 
93*46731Skarels     /* Assume a long is four bytes */
94*46731Skarels     if (sizeof(long) != 4) {
95*46731Skarels 	fprintf(stdout, "%s: size of long is %d.\n", sizeof(long), prog);
96*46731Skarels 	exit(-1);
97*46731Skarels     }
98*46731Skarels     /* Assume <=32 signals */
99*46731Skarels     if (NSIG > 32) {
100*46731Skarels 	fprintf(stderr, "%s: more than 32 signals defined.\n", prog);
101*46731Skarels 	exit(-1);
102*46731Skarels     }
103*46731Skarels     while (--argc > 0 && (*++argv)[0] == '-')
104*46731Skarels 	for (i = 1; argv[0][i] != '\0'; i++) {
105*46731Skarels 	    switch (argv[0][i]) {
106*46731Skarels 
107*46731Skarels 		/* debug flag */
108*46731Skarels 	    case 'd':
109*46731Skarels 		debug = 1;
110*46731Skarels 		continue;
111*46731Skarels 
112*46731Skarels 		/* debug flag */
113*46731Skarels 	    case 'l':
114*46731Skarels 		kerb_debug |= 1;
115*46731Skarels 		continue;
116*46731Skarels 
117*46731Skarels 	    case 'n':		/* read MKEYFILE for master key */
118*46731Skarels 		nflag = 1;
119*46731Skarels 		continue;
120*46731Skarels 
121*46731Skarels 	    default:
122*46731Skarels 		fprintf(stderr, "%s: illegal flag \"%c\"\n",
123*46731Skarels 			progname, argv[0][i]);
124*46731Skarels 		Usage();	/* Give message and die */
125*46731Skarels 	    }
126*46731Skarels 	};
127*46731Skarels 
128*46731Skarels     fprintf(stdout, "Opening database...\n");
129*46731Skarels     fflush(stdout);
130*46731Skarels     kerb_init();
131*46731Skarels     if (argc > 0) {
132*46731Skarels 	if (kerb_db_set_name(*argv) != 0) {
133*46731Skarels 	    fprintf(stderr, "Could not open altername database name\n");
134*46731Skarels 	    exit(1);
135*46731Skarels 	}
136*46731Skarels     }
137*46731Skarels 
138*46731Skarels #ifdef	notdef
139*46731Skarels     no_core_dumps();		/* diddle signals to avoid core dumps! */
140*46731Skarels 
141*46731Skarels     /* ignore whatever is reasonable */
142*46731Skarels     signal(SIGHUP, SIG_IGN);
143*46731Skarels     signal(SIGINT, SIG_IGN);
144*46731Skarels     signal(SIGTSTP, SIG_IGN);
145*46731Skarels 
146*46731Skarels #endif
147*46731Skarels 
148*46731Skarels     if (kdb_get_master_key ((nflag == 0),
149*46731Skarels 			    master_key, master_key_schedule) != 0) {
150*46731Skarels       fprintf (stdout, "Couldn't read master key.\n");
151*46731Skarels       fflush (stdout);
152*46731Skarels       exit (-1);
153*46731Skarels     }
154*46731Skarels 
155*46731Skarels     if ((master_key_version = kdb_verify_master_key(master_key,
156*46731Skarels 						    master_key_schedule,
157*46731Skarels 						    stdout)) < 0)
158*46731Skarels       exit (-1);
159*46731Skarels 
160*46731Skarels     /* lookup the default values */
161*46731Skarels     n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
162*46731Skarels 			   &default_princ, 1, &more);
163*46731Skarels     if (n != 1) {
164*46731Skarels 	fprintf(stderr,
165*46731Skarels 	     "%s: Kerberos error on default value lookup, %d found.\n",
166*46731Skarels 		progname, n);
167*46731Skarels 	exit(-1);
168*46731Skarels     }
169*46731Skarels     fprintf(stdout, "Previous or default values are in [brackets] ,\n");
170*46731Skarels     fprintf(stdout, "enter return to leave the same, or new value.\n");
171*46731Skarels 
172*46731Skarels     while (change_principal()) {
173*46731Skarels     }
174*46731Skarels 
175*46731Skarels     cleanup();
176*46731Skarels }
177*46731Skarels 
178*46731Skarels change_principal()
179*46731Skarels {
180*46731Skarels     static char temp[255];
181*46731Skarels     int     creating = 0;
182*46731Skarels     int     editpw = 0;
183*46731Skarels     int     changed = 0;
184*46731Skarels     long    temp_long;
185*46731Skarels     int     n;
186*46731Skarels     struct tm 	*tp, edate, *localtime();
187*46731Skarels     long 	maketime();
188*46731Skarels 
189*46731Skarels     fprintf(stdout, "\nPrincipal name: ");
190*46731Skarels     fflush(stdout);
191*46731Skarels     if (!gets(input_name) || *input_name == '\0')
192*46731Skarels 	return 0;
193*46731Skarels     fprintf(stdout, "Instance: ");
194*46731Skarels     fflush(stdout);
195*46731Skarels     /* instance can be null */
196*46731Skarels     gets(input_instance);
197*46731Skarels     j = kerb_get_principal(input_name, input_instance, principal_data,
198*46731Skarels 			   MAX_PRINCIPAL, &more);
199*46731Skarels     if (!j) {
200*46731Skarels 	fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
201*46731Skarels 	gets(temp);		/* Default case should work, it didn't */
202*46731Skarels 	if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
203*46731Skarels 	    return -1;
204*46731Skarels 	/* make a new principal, fill in defaults */
205*46731Skarels 	j = 1;
206*46731Skarels 	creating = 1;
207*46731Skarels 	strcpy(principal_data[0].name, input_name);
208*46731Skarels 	strcpy(principal_data[0].instance, input_instance);
209*46731Skarels 	principal_data[0].old = NULL;
210*46731Skarels 	principal_data[0].exp_date = default_princ.exp_date;
211*46731Skarels 	principal_data[0].max_life = default_princ.max_life;
212*46731Skarels 	principal_data[0].attributes = default_princ.attributes;
213*46731Skarels 	principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
214*46731Skarels 	principal_data[0].key_version = 0; /* bumped up later */
215*46731Skarels     }
216*46731Skarels     tp = localtime(&principal_data[0].exp_date);
217*46731Skarels     (void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d",
218*46731Skarels 		   tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
219*46731Skarels 		   tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
220*46731Skarels     for (i = 0; i < j; i++) {
221*46731Skarels 	for (;;) {
222*46731Skarels 	    fprintf(stdout,
223*46731Skarels 		    "\nPrincipal: %s, Instance: %s, kdc_key_ver: %d",
224*46731Skarels 		    principal_data[i].name, principal_data[i].instance,
225*46731Skarels 		    principal_data[i].kdc_key_ver);
226*46731Skarels 	    editpw = 1;
227*46731Skarels 	    changed = 0;
228*46731Skarels 	    if (!creating) {
229*46731Skarels 		/*
230*46731Skarels 		 * copy the existing data so we can use the old values
231*46731Skarels 		 * for the qualifier clause of the replace
232*46731Skarels 		 */
233*46731Skarels 		principal_data[i].old = (char *) &old_principal;
234*46731Skarels 		bcopy(&principal_data[i], &old_principal,
235*46731Skarels 		      sizeof(old_principal));
236*46731Skarels 		printf("\nChange password [n] ? ");
237*46731Skarels 		gets(temp);
238*46731Skarels 		if (strcmp("y", temp) && strcmp("Y", temp))
239*46731Skarels 		    editpw = 0;
240*46731Skarels 	    }
241*46731Skarels 	    /* password */
242*46731Skarels 	    if (editpw) {
243*46731Skarels #ifdef NOENCRYPTION
244*46731Skarels 		placebo_read_pw_string(pw_str, sizeof pw_str,
245*46731Skarels 		    "\nNew Password: ", TRUE);
246*46731Skarels #else
247*46731Skarels 		des_read_pw_string(pw_str, sizeof pw_str,
248*46731Skarels 		    "\nNew Password: ", TRUE);
249*46731Skarels #endif
250*46731Skarels 		if (!strcmp(pw_str, "RANDOM")) {
251*46731Skarels 		    printf("\nRandom password [y] ? ");
252*46731Skarels 		    gets(temp);
253*46731Skarels 		    if (!strcmp("n", temp) || !strcmp("N", temp)) {
254*46731Skarels 			/* no, use literal */
255*46731Skarels #ifdef NOENCRYPTION
256*46731Skarels 			bzero(new_key, sizeof(C_Block));
257*46731Skarels 			new_key[0] = 127;
258*46731Skarels #else
259*46731Skarels 			string_to_key(pw_str, new_key);
260*46731Skarels #endif
261*46731Skarels 			bzero(pw_str, sizeof pw_str);	/* "RANDOM" */
262*46731Skarels 		    } else {
263*46731Skarels #ifdef NOENCRYPTION
264*46731Skarels 			bzero(new_key, sizeof(C_Block));
265*46731Skarels 			new_key[0] = 127;
266*46731Skarels #else
267*46731Skarels 			random_key(new_key);	/* yes, random */
268*46731Skarels #endif
269*46731Skarels 			bzero(pw_str, sizeof pw_str);
270*46731Skarels 		    }
271*46731Skarels 		} else if (!strcmp(pw_str, "NULL")) {
272*46731Skarels 		    printf("\nNull Key [y] ? ");
273*46731Skarels 		    gets(temp);
274*46731Skarels 		    if (!strcmp("n", temp) || !strcmp("N", temp)) {
275*46731Skarels 			/* no, use literal */
276*46731Skarels #ifdef NOENCRYPTION
277*46731Skarels 			bzero(new_key, sizeof(C_Block));
278*46731Skarels 			new_key[0] = 127;
279*46731Skarels #else
280*46731Skarels 			string_to_key(pw_str, new_key);
281*46731Skarels #endif
282*46731Skarels 			bzero(pw_str, sizeof pw_str);	/* "NULL" */
283*46731Skarels 		    } else {
284*46731Skarels 
285*46731Skarels 			principal_data[i].key_low = 0;
286*46731Skarels 			principal_data[i].key_high = 0;
287*46731Skarels 			goto null_key;
288*46731Skarels 		    }
289*46731Skarels 		} else {
290*46731Skarels #ifdef NOENCRYPTION
291*46731Skarels 		    bzero(new_key, sizeof(C_Block));
292*46731Skarels 		    new_key[0] = 127;
293*46731Skarels #else
294*46731Skarels 		    string_to_key(pw_str, new_key);
295*46731Skarels #endif
296*46731Skarels 		    bzero(pw_str, sizeof pw_str);
297*46731Skarels 		}
298*46731Skarels 
299*46731Skarels 		/* seal it under the kerberos master key */
300*46731Skarels 		kdb_encrypt_key (new_key, new_key,
301*46731Skarels 				 master_key, master_key_schedule,
302*46731Skarels 				 ENCRYPT);
303*46731Skarels 		bcopy(new_key, &principal_data[i].key_low, 4);
304*46731Skarels 		bcopy(((long *) new_key) + 1,
305*46731Skarels 		    &principal_data[i].key_high, 4);
306*46731Skarels 		bzero(new_key, sizeof(new_key));
307*46731Skarels 	null_key:
308*46731Skarels 		/* set master key version */
309*46731Skarels 		principal_data[i].kdc_key_ver =
310*46731Skarels 		    (unsigned char) master_key_version;
311*46731Skarels 		/* bump key version # */
312*46731Skarels 		principal_data[i].key_version++;
313*46731Skarels 		fprintf(stdout,
314*46731Skarels 			"\nPrincipal's new key version = %d\n",
315*46731Skarels 			principal_data[i].key_version);
316*46731Skarels 		fflush(stdout);
317*46731Skarels 		changed = 1;
318*46731Skarels 	    }
319*46731Skarels 	    /* expiration date */
320*46731Skarels 	    fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
321*46731Skarels 		    principal_data[i].exp_date_txt);
322*46731Skarels 	    zaptime(&edate);
323*46731Skarels 	    while (gets(temp) && ((n = strlen(temp)) >
324*46731Skarels 				  sizeof(principal_data[0].exp_date_txt))) {
325*46731Skarels 	    bad_date:
326*46731Skarels 		fprintf(stdout, "\07\07Date Invalid\n");
327*46731Skarels 		fprintf(stdout,
328*46731Skarels 			"Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
329*46731Skarels 			principal_data[i].exp_date_txt);
330*46731Skarels 		zaptime(&edate);
331*46731Skarels 	    }
332*46731Skarels 
333*46731Skarels 	    if (*temp) {
334*46731Skarels 		if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
335*46731Skarels 			      &edate.tm_mon, &edate.tm_mday) != 3)
336*46731Skarels 		    goto bad_date;
337*46731Skarels 		(void) strcpy(principal_data[i].exp_date_txt, temp);
338*46731Skarels 		edate.tm_mon--;		/* January is 0, not 1 */
339*46731Skarels 		edate.tm_hour = 23;	/* nearly midnight at the end of the */
340*46731Skarels 		edate.tm_min = 59;	/* specified day */
341*46731Skarels 		edate.tm_zon = 1;	/* local time, not GMT */
342*46731Skarels 		if (!(principal_data[i].exp_date = maketime(&edate)))
343*46731Skarels 		    goto bad_date;
344*46731Skarels 		changed = 1;
345*46731Skarels 	    }
346*46731Skarels 
347*46731Skarels 	    /* maximum lifetime */
348*46731Skarels 	    fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
349*46731Skarels 		    principal_data[i].max_life);
350*46731Skarels 	    while (gets(temp) && *temp) {
351*46731Skarels 		if (sscanf(temp, "%d", &temp_long) != 1)
352*46731Skarels 		    goto bad_life;
353*46731Skarels 		if (temp_long > 255 || (temp_long < 0)) {
354*46731Skarels 		bad_life:
355*46731Skarels 		    fprintf(stdout, "\07\07Invalid, choose 0-255\n");
356*46731Skarels 		    fprintf(stdout,
357*46731Skarels 			    "Max ticket lifetime (*5 minutes) [ %d ] ? ",
358*46731Skarels 			    principal_data[i].max_life);
359*46731Skarels 		    continue;
360*46731Skarels 		}
361*46731Skarels 		changed = 1;
362*46731Skarels 		/* dont clobber */
363*46731Skarels 		principal_data[i].max_life = (unsigned short) temp_long;
364*46731Skarels 		break;
365*46731Skarels 	    }
366*46731Skarels 
367*46731Skarels 	    /* attributes */
368*46731Skarels 	    fprintf(stdout, "Attributes [ %d ] ? ",
369*46731Skarels 		    principal_data[i].attributes);
370*46731Skarels 	    while (gets(temp) && *temp) {
371*46731Skarels 		if (sscanf(temp, "%d", &temp_long) != 1)
372*46731Skarels 		    goto bad_att;
373*46731Skarels 		if (temp_long > 65535 || (temp_long < 0)) {
374*46731Skarels 		bad_att:
375*46731Skarels 		    fprintf(stdout, "\07\07Invalid, choose 0-65535\n");
376*46731Skarels 		    fprintf(stdout, "Attributes [ %d ] ? ",
377*46731Skarels 			    principal_data[i].attributes);
378*46731Skarels 		    continue;
379*46731Skarels 		}
380*46731Skarels 		changed = 1;
381*46731Skarels 		/* dont clobber */
382*46731Skarels 		principal_data[i].attributes =
383*46731Skarels 		    (unsigned short) temp_long;
384*46731Skarels 		break;
385*46731Skarels 	    }
386*46731Skarels 
387*46731Skarels 	    /*
388*46731Skarels 	     * remaining fields -- key versions and mod info, should
389*46731Skarels 	     * not be directly manipulated
390*46731Skarels 	     */
391*46731Skarels 	    if (changed) {
392*46731Skarels 		if (kerb_put_principal(&principal_data[i], 1)) {
393*46731Skarels 		    fprintf(stdout,
394*46731Skarels 			"\nError updating Kerberos database");
395*46731Skarels 		} else {
396*46731Skarels 		    fprintf(stdout, "Edit O.K.");
397*46731Skarels 		}
398*46731Skarels 	    } else {
399*46731Skarels 		fprintf(stdout, "Unchanged");
400*46731Skarels 	    }
401*46731Skarels 
402*46731Skarels 
403*46731Skarels 	    bzero(&principal_data[i].key_low, 4);
404*46731Skarels 	    bzero(&principal_data[i].key_high, 4);
405*46731Skarels 	    fflush(stdout);
406*46731Skarels 	    break;
407*46731Skarels 	}
408*46731Skarels     }
409*46731Skarels     if (more) {
410*46731Skarels 	fprintf(stdout, "\nThere were more tuples found ");
411*46731Skarels 	fprintf(stdout, "than there were space for");
412*46731Skarels       }
413*46731Skarels     return 1;
414*46731Skarels }
415*46731Skarels 
416*46731Skarels 
417*46731Skarels no_core_dumps()
418*46731Skarels {
419*46731Skarels 
420*46731Skarels     signal(SIGQUIT, sig_exit);
421*46731Skarels     signal(SIGILL, sig_exit);
422*46731Skarels     signal(SIGTRAP, sig_exit);
423*46731Skarels     signal(SIGIOT, sig_exit);
424*46731Skarels     signal(SIGEMT, sig_exit);
425*46731Skarels     signal(SIGFPE, sig_exit);
426*46731Skarels     signal(SIGBUS, sig_exit);
427*46731Skarels     signal(SIGSEGV, sig_exit);
428*46731Skarels     signal(SIGSYS, sig_exit);
429*46731Skarels }
430*46731Skarels 
431*46731Skarels void
432*46731Skarels sig_exit(sig, code, scp)
433*46731Skarels     int     sig, code;
434*46731Skarels     struct sigcontext *scp;
435*46731Skarels {
436*46731Skarels     cleanup();
437*46731Skarels     fprintf(stderr,
438*46731Skarels 	"\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting",
439*46731Skarels         sig, code, scp->sc_pc);
440*46731Skarels     exit(-1);
441*46731Skarels }
442*46731Skarels 
443*46731Skarels 
444*46731Skarels cleanup()
445*46731Skarels {
446*46731Skarels 
447*46731Skarels     bzero(master_key, sizeof(master_key));
448*46731Skarels     bzero(session_key, sizeof(session_key));
449*46731Skarels     bzero(master_key_schedule, sizeof(master_key_schedule));
450*46731Skarels     bzero(principal_data, sizeof(principal_data));
451*46731Skarels     bzero(new_key, sizeof(new_key));
452*46731Skarels     bzero(pw_str, sizeof(pw_str));
453*46731Skarels }
454*46731Skarels Usage()
455*46731Skarels {
456*46731Skarels     fprintf(stderr, "Usage: %s [-n]\n", progname);
457*46731Skarels     exit(1);
458*46731Skarels }
459*46731Skarels 
460*46731Skarels /* zaptime code taken from: */
461*46731Skarels /*
462*46731Skarels  * PARTIME		parse date/time string into a TM structure
463*46731Skarels  *
464*46731Skarels  * Usage:
465*46731Skarels  *      #include "time.h"             -- expanded tm structure
466*46731Skarels  *	char *str; struct tm *tp;
467*46731Skarels  *	partime(str,tp);
468*46731Skarels  * Returns:
469*46731Skarels  *	0 if parsing failed
470*46731Skarels  *	else time values in specified TM structure (unspecified values
471*46731Skarels  *		set to TMNULL)
472*46731Skarels  * Notes:
473*46731Skarels  *	This code is quasi-public; it may be used freely in like software.
474*46731Skarels  *	It is not to be sold, nor used in licensed software without
475*46731Skarels  *	permission of the author.
476*46731Skarels  *	For everyone's benefit, please report bugs and improvements!
477*46731Skarels  * 	Copyright 1980 by Ken Harrenstien, SRI International.
478*46731Skarels  *	(ARPANET: KLH @ SRI)
479*46731Skarels  */
480*46731Skarels 
481*46731Skarels zaptime(atm)
482*46731Skarels register struct tm *atm;
483*46731Skarels /* clears atm */
484*46731Skarels {
485*46731Skarels 	atm->tm_sec = TMNULL;
486*46731Skarels 	atm->tm_min = TMNULL;
487*46731Skarels 	atm->tm_hour = TMNULL;
488*46731Skarels 	atm->tm_mday = TMNULL;
489*46731Skarels 	atm->tm_mon = TMNULL;
490*46731Skarels 	atm->tm_year = TMNULL;
491*46731Skarels 	atm->tm_wday = TMNULL;
492*46731Skarels 	atm->tm_yday = TMNULL;
493*46731Skarels 	atm->tm_isdst = TMNULL;
494*46731Skarels 	atm->tm_zon = TMNULL;
495*46731Skarels 	atm->tm_ampm = TMNULL;
496*46731Skarels }
497