146731Skarels /*
246731Skarels  * $Source: /mit/kerberos/src/admin/RCS/kdb_edit.c,v $
346731Skarels  * $Author: jtkohl $
446731Skarels  *
546731Skarels  * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
646731Skarels  * of Technology.
746731Skarels  *
846731Skarels  * For copying and distribution information, please see the file
946731Skarels  * <mit-copyright.h>.
1046731Skarels  *
1146731Skarels  * This routine changes the Kerberos encryption keys for principals,
1246731Skarels  * i.e., users or services.
1346731Skarels  */
1446731Skarels 
1546731Skarels /*
1646731Skarels  * exit returns 	 0 ==> success -1 ==> error
1746731Skarels  */
1846731Skarels 
1946731Skarels #ifndef	lint
2046731Skarels static char rcsid_kdb_edit_c[] =
2146731Skarels "$Header: kdb_edit.c,v 4.1 89/03/23 09:58:18 jtkohl Exp $";
2246731Skarels #endif	lint
2346731Skarels 
2446731Skarels #include <mit-copyright.h>
2546731Skarels 
2646731Skarels #include <stdio.h>
2746731Skarels #include <signal.h>
2846731Skarels #include <errno.h>
2946731Skarels #include <strings.h>
3046731Skarels #include <sys/ioctl.h>
3146731Skarels #include <sys/file.h>
3246731Skarels #include "time.h"
3346731Skarels #include <des.h>
3446731Skarels #include <krb.h>
3546731Skarels #include <krb_db.h>
3646731Skarels /* MKEYFILE is now defined in kdc.h */
3746731Skarels #include <kdc.h>
3846731Skarels 
3946731Skarels extern char *errmsg();
4046731Skarels extern int errno;
4146731Skarels extern char *strcpy();
4246731Skarels 
4346731Skarels void    sig_exit();
4446731Skarels 
4546731Skarels char    prog[32];
4646731Skarels char   *progname = prog;
4746731Skarels int     nflag = 0;
4846731Skarels int     cflag;
4946731Skarels int     lflag;
5046731Skarels int     uflag;
5146731Skarels int     debug;
5246731Skarels extern  kerb_debug;
5346731Skarels extern char *sys_errlist[];
5446731Skarels 
5546731Skarels Key_schedule KS;
5646731Skarels C_Block new_key;
5746731Skarels unsigned char *input;
5846731Skarels 
5946731Skarels unsigned char *ivec;
6046731Skarels int     i, j;
6146731Skarels int     more;
6246731Skarels 
6346731Skarels char   *in_ptr;
6446731Skarels char    input_name[ANAME_SZ];
6546731Skarels char    input_instance[INST_SZ];
6646731Skarels char    input_string[ANAME_SZ];
6746731Skarels 
6846731Skarels #define	MAX_PRINCIPAL	10
6946731Skarels Principal principal_data[MAX_PRINCIPAL];
7046731Skarels 
7146731Skarels static Principal old_principal;
7246731Skarels static Principal default_princ;
7346731Skarels 
7446731Skarels static C_Block master_key;
7546731Skarels static C_Block session_key;
7646731Skarels static Key_schedule master_key_schedule;
7746731Skarels static char pw_str[255];
7846731Skarels static long master_key_version;
7946731Skarels 
80*46735Skarels #define	gets(buf) _gets(buf, sizeof(buf))	/* hack */
81*46735Skarels 
82*46735Skarels char *
_gets(p,n)83*46735Skarels _gets(p, n)
84*46735Skarels 	char *p;
85*46735Skarels 	int n;
86*46735Skarels {
87*46735Skarels 	char *rv, *fgets();
88*46735Skarels 
89*46735Skarels 	if ((rv = fgets(p, n, stdin)) == NULL)
90*46735Skarels 		return (rv);
91*46735Skarels 	if (p = index(p, '\n'))
92*46735Skarels 		*p = '\0';
93*46735Skarels 	return (rv);
94*46735Skarels }
95*46735Skarels 
main(argc,argv)9646731Skarels main(argc, argv)
9746731Skarels     int     argc;
9846731Skarels     char   *argv[];
9946731Skarels 
10046731Skarels {
10146731Skarels     /* Local Declarations */
10246731Skarels 
10346731Skarels     long    n;
10446731Skarels 
10546731Skarels     prog[sizeof prog - 1] = '\0';	/* make sure terminated */
10646731Skarels     strncpy(prog, argv[0], sizeof prog - 1);	/* salt away invoking
10746731Skarels 						 * program */
10846731Skarels 
10946731Skarels     /* Assume a long is four bytes */
11046731Skarels     if (sizeof(long) != 4) {
11146731Skarels 	fprintf(stdout, "%s: size of long is %d.\n", sizeof(long), prog);
11246731Skarels 	exit(-1);
11346731Skarels     }
11446731Skarels     /* Assume <=32 signals */
11546731Skarels     if (NSIG > 32) {
11646731Skarels 	fprintf(stderr, "%s: more than 32 signals defined.\n", prog);
11746731Skarels 	exit(-1);
11846731Skarels     }
11946731Skarels     while (--argc > 0 && (*++argv)[0] == '-')
12046731Skarels 	for (i = 1; argv[0][i] != '\0'; i++) {
12146731Skarels 	    switch (argv[0][i]) {
12246731Skarels 
12346731Skarels 		/* debug flag */
12446731Skarels 	    case 'd':
12546731Skarels 		debug = 1;
12646731Skarels 		continue;
12746731Skarels 
12846731Skarels 		/* debug flag */
12946731Skarels 	    case 'l':
13046731Skarels 		kerb_debug |= 1;
13146731Skarels 		continue;
13246731Skarels 
13346731Skarels 	    case 'n':		/* read MKEYFILE for master key */
13446731Skarels 		nflag = 1;
13546731Skarels 		continue;
13646731Skarels 
13746731Skarels 	    default:
13846731Skarels 		fprintf(stderr, "%s: illegal flag \"%c\"\n",
13946731Skarels 			progname, argv[0][i]);
14046731Skarels 		Usage();	/* Give message and die */
14146731Skarels 	    }
14246731Skarels 	};
14346731Skarels 
14446731Skarels     fprintf(stdout, "Opening database...\n");
14546731Skarels     fflush(stdout);
14646731Skarels     kerb_init();
14746731Skarels     if (argc > 0) {
14846731Skarels 	if (kerb_db_set_name(*argv) != 0) {
14946731Skarels 	    fprintf(stderr, "Could not open altername database name\n");
15046731Skarels 	    exit(1);
15146731Skarels 	}
15246731Skarels     }
15346731Skarels 
15446731Skarels #ifdef	notdef
15546731Skarels     no_core_dumps();		/* diddle signals to avoid core dumps! */
15646731Skarels 
15746731Skarels     /* ignore whatever is reasonable */
15846731Skarels     signal(SIGHUP, SIG_IGN);
15946731Skarels     signal(SIGINT, SIG_IGN);
16046731Skarels     signal(SIGTSTP, SIG_IGN);
16146731Skarels 
16246731Skarels #endif
16346731Skarels 
16446731Skarels     if (kdb_get_master_key ((nflag == 0),
16546731Skarels 			    master_key, master_key_schedule) != 0) {
16646731Skarels       fprintf (stdout, "Couldn't read master key.\n");
16746731Skarels       fflush (stdout);
16846731Skarels       exit (-1);
16946731Skarels     }
17046731Skarels 
17146731Skarels     if ((master_key_version = kdb_verify_master_key(master_key,
17246731Skarels 						    master_key_schedule,
17346731Skarels 						    stdout)) < 0)
17446731Skarels       exit (-1);
17546731Skarels 
17646731Skarels     /* lookup the default values */
17746731Skarels     n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
17846731Skarels 			   &default_princ, 1, &more);
17946731Skarels     if (n != 1) {
18046731Skarels 	fprintf(stderr,
18146731Skarels 	     "%s: Kerberos error on default value lookup, %d found.\n",
18246731Skarels 		progname, n);
18346731Skarels 	exit(-1);
18446731Skarels     }
18546731Skarels     fprintf(stdout, "Previous or default values are in [brackets] ,\n");
18646731Skarels     fprintf(stdout, "enter return to leave the same, or new value.\n");
18746731Skarels 
18846731Skarels     while (change_principal()) {
18946731Skarels     }
19046731Skarels 
19146731Skarels     cleanup();
19246731Skarels }
19346731Skarels 
change_principal()19446731Skarels change_principal()
19546731Skarels {
19646731Skarels     static char temp[255];
19746731Skarels     int     creating = 0;
19846731Skarels     int     editpw = 0;
19946731Skarels     int     changed = 0;
20046731Skarels     long    temp_long;
20146731Skarels     int     n;
20246731Skarels     struct tm 	*tp, edate, *localtime();
20346731Skarels     long 	maketime();
20446731Skarels 
20546731Skarels     fprintf(stdout, "\nPrincipal name: ");
20646731Skarels     fflush(stdout);
20746731Skarels     if (!gets(input_name) || *input_name == '\0')
20846731Skarels 	return 0;
20946731Skarels     fprintf(stdout, "Instance: ");
21046731Skarels     fflush(stdout);
21146731Skarels     /* instance can be null */
21246731Skarels     gets(input_instance);
21346731Skarels     j = kerb_get_principal(input_name, input_instance, principal_data,
21446731Skarels 			   MAX_PRINCIPAL, &more);
21546731Skarels     if (!j) {
216*46735Skarels 	fprintf(stdout, "%s.%s not found, Create [y] ? ", input_name,
217*46735Skarels 	    input_instance);
21846731Skarels 	gets(temp);		/* Default case should work, it didn't */
21946731Skarels 	if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
22046731Skarels 	    return -1;
22146731Skarels 	/* make a new principal, fill in defaults */
22246731Skarels 	j = 1;
22346731Skarels 	creating = 1;
22446731Skarels 	strcpy(principal_data[0].name, input_name);
22546731Skarels 	strcpy(principal_data[0].instance, input_instance);
22646731Skarels 	principal_data[0].old = NULL;
22746731Skarels 	principal_data[0].exp_date = default_princ.exp_date;
22846731Skarels 	principal_data[0].max_life = default_princ.max_life;
22946731Skarels 	principal_data[0].attributes = default_princ.attributes;
23046731Skarels 	principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
23146731Skarels 	principal_data[0].key_version = 0; /* bumped up later */
23246731Skarels     }
23346731Skarels     tp = localtime(&principal_data[0].exp_date);
23446731Skarels     (void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d",
23546731Skarels 		   tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
23646731Skarels 		   tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
23746731Skarels     for (i = 0; i < j; i++) {
23846731Skarels 	for (;;) {
23946731Skarels 	    fprintf(stdout,
240*46735Skarels 		    "Principal: %s, Instance: %s, kdc_key_ver: %d\n",
24146731Skarels 		    principal_data[i].name, principal_data[i].instance,
24246731Skarels 		    principal_data[i].kdc_key_ver);
24346731Skarels 	    editpw = 1;
24446731Skarels 	    changed = 0;
24546731Skarels 	    if (!creating) {
24646731Skarels 		/*
24746731Skarels 		 * copy the existing data so we can use the old values
24846731Skarels 		 * for the qualifier clause of the replace
24946731Skarels 		 */
25046731Skarels 		principal_data[i].old = (char *) &old_principal;
25146731Skarels 		bcopy(&principal_data[i], &old_principal,
25246731Skarels 		      sizeof(old_principal));
253*46735Skarels 		printf("Change password [n] ? ");
25446731Skarels 		gets(temp);
25546731Skarels 		if (strcmp("y", temp) && strcmp("Y", temp))
25646731Skarels 		    editpw = 0;
25746731Skarels 	    }
25846731Skarels 	    /* password */
25946731Skarels 	    if (editpw) {
26046731Skarels #ifdef NOENCRYPTION
26146731Skarels 		placebo_read_pw_string(pw_str, sizeof pw_str,
262*46735Skarels 		    "New Password: ", TRUE);
26346731Skarels #else
26446731Skarels 		des_read_pw_string(pw_str, sizeof pw_str,
265*46735Skarels 		    "New Password: ", TRUE);
26646731Skarels #endif
267*46735Skarels 		if (pw_str[0] == '\0' || !strcmp(pw_str, "RANDOM")) {
268*46735Skarels 		    printf("Random password [y] ? ");
26946731Skarels 		    gets(temp);
27046731Skarels 		    if (!strcmp("n", temp) || !strcmp("N", temp)) {
27146731Skarels 			/* no, use literal */
27246731Skarels #ifdef NOENCRYPTION
27346731Skarels 			bzero(new_key, sizeof(C_Block));
27446731Skarels 			new_key[0] = 127;
27546731Skarels #else
27646731Skarels 			string_to_key(pw_str, new_key);
27746731Skarels #endif
27846731Skarels 			bzero(pw_str, sizeof pw_str);	/* "RANDOM" */
27946731Skarels 		    } else {
28046731Skarels #ifdef NOENCRYPTION
28146731Skarels 			bzero(new_key, sizeof(C_Block));
28246731Skarels 			new_key[0] = 127;
28346731Skarels #else
28446731Skarels 			random_key(new_key);	/* yes, random */
28546731Skarels #endif
28646731Skarels 			bzero(pw_str, sizeof pw_str);
28746731Skarels 		    }
28846731Skarels 		} else if (!strcmp(pw_str, "NULL")) {
28946731Skarels 		    printf("\nNull Key [y] ? ");
29046731Skarels 		    gets(temp);
29146731Skarels 		    if (!strcmp("n", temp) || !strcmp("N", temp)) {
29246731Skarels 			/* no, use literal */
29346731Skarels #ifdef NOENCRYPTION
29446731Skarels 			bzero(new_key, sizeof(C_Block));
29546731Skarels 			new_key[0] = 127;
29646731Skarels #else
29746731Skarels 			string_to_key(pw_str, new_key);
29846731Skarels #endif
29946731Skarels 			bzero(pw_str, sizeof pw_str);	/* "NULL" */
30046731Skarels 		    } else {
30146731Skarels 
30246731Skarels 			principal_data[i].key_low = 0;
30346731Skarels 			principal_data[i].key_high = 0;
30446731Skarels 			goto null_key;
30546731Skarels 		    }
30646731Skarels 		} else {
30746731Skarels #ifdef NOENCRYPTION
30846731Skarels 		    bzero(new_key, sizeof(C_Block));
30946731Skarels 		    new_key[0] = 127;
31046731Skarels #else
31146731Skarels 		    string_to_key(pw_str, new_key);
31246731Skarels #endif
31346731Skarels 		    bzero(pw_str, sizeof pw_str);
31446731Skarels 		}
31546731Skarels 
31646731Skarels 		/* seal it under the kerberos master key */
31746731Skarels 		kdb_encrypt_key (new_key, new_key,
31846731Skarels 				 master_key, master_key_schedule,
31946731Skarels 				 ENCRYPT);
32046731Skarels 		bcopy(new_key, &principal_data[i].key_low, 4);
32146731Skarels 		bcopy(((long *) new_key) + 1,
32246731Skarels 		    &principal_data[i].key_high, 4);
32346731Skarels 		bzero(new_key, sizeof(new_key));
32446731Skarels 	null_key:
32546731Skarels 		/* set master key version */
32646731Skarels 		principal_data[i].kdc_key_ver =
32746731Skarels 		    (unsigned char) master_key_version;
32846731Skarels 		/* bump key version # */
32946731Skarels 		principal_data[i].key_version++;
33046731Skarels 		fprintf(stdout,
33146731Skarels 			"\nPrincipal's new key version = %d\n",
33246731Skarels 			principal_data[i].key_version);
33346731Skarels 		fflush(stdout);
33446731Skarels 		changed = 1;
33546731Skarels 	    }
33646731Skarels 	    /* expiration date */
33746731Skarels 	    fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
33846731Skarels 		    principal_data[i].exp_date_txt);
33946731Skarels 	    zaptime(&edate);
34046731Skarels 	    while (gets(temp) && ((n = strlen(temp)) >
34146731Skarels 				  sizeof(principal_data[0].exp_date_txt))) {
34246731Skarels 	    bad_date:
34346731Skarels 		fprintf(stdout, "\07\07Date Invalid\n");
34446731Skarels 		fprintf(stdout,
34546731Skarels 			"Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
34646731Skarels 			principal_data[i].exp_date_txt);
34746731Skarels 		zaptime(&edate);
34846731Skarels 	    }
34946731Skarels 
35046731Skarels 	    if (*temp) {
35146731Skarels 		if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
35246731Skarels 			      &edate.tm_mon, &edate.tm_mday) != 3)
35346731Skarels 		    goto bad_date;
35446731Skarels 		(void) strcpy(principal_data[i].exp_date_txt, temp);
35546731Skarels 		edate.tm_mon--;		/* January is 0, not 1 */
35646731Skarels 		edate.tm_hour = 23;	/* nearly midnight at the end of the */
35746731Skarels 		edate.tm_min = 59;	/* specified day */
35846731Skarels 		edate.tm_zon = 1;	/* local time, not GMT */
35946731Skarels 		if (!(principal_data[i].exp_date = maketime(&edate)))
36046731Skarels 		    goto bad_date;
36146731Skarels 		changed = 1;
36246731Skarels 	    }
36346731Skarels 
36446731Skarels 	    /* maximum lifetime */
36546731Skarels 	    fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
36646731Skarels 		    principal_data[i].max_life);
36746731Skarels 	    while (gets(temp) && *temp) {
36846731Skarels 		if (sscanf(temp, "%d", &temp_long) != 1)
36946731Skarels 		    goto bad_life;
37046731Skarels 		if (temp_long > 255 || (temp_long < 0)) {
37146731Skarels 		bad_life:
37246731Skarels 		    fprintf(stdout, "\07\07Invalid, choose 0-255\n");
37346731Skarels 		    fprintf(stdout,
37446731Skarels 			    "Max ticket lifetime (*5 minutes) [ %d ] ? ",
37546731Skarels 			    principal_data[i].max_life);
37646731Skarels 		    continue;
37746731Skarels 		}
37846731Skarels 		changed = 1;
37946731Skarels 		/* dont clobber */
38046731Skarels 		principal_data[i].max_life = (unsigned short) temp_long;
38146731Skarels 		break;
38246731Skarels 	    }
38346731Skarels 
38446731Skarels 	    /* attributes */
38546731Skarels 	    fprintf(stdout, "Attributes [ %d ] ? ",
38646731Skarels 		    principal_data[i].attributes);
38746731Skarels 	    while (gets(temp) && *temp) {
38846731Skarels 		if (sscanf(temp, "%d", &temp_long) != 1)
38946731Skarels 		    goto bad_att;
39046731Skarels 		if (temp_long > 65535 || (temp_long < 0)) {
39146731Skarels 		bad_att:
39246731Skarels 		    fprintf(stdout, "\07\07Invalid, choose 0-65535\n");
39346731Skarels 		    fprintf(stdout, "Attributes [ %d ] ? ",
39446731Skarels 			    principal_data[i].attributes);
39546731Skarels 		    continue;
39646731Skarels 		}
39746731Skarels 		changed = 1;
39846731Skarels 		/* dont clobber */
39946731Skarels 		principal_data[i].attributes =
40046731Skarels 		    (unsigned short) temp_long;
40146731Skarels 		break;
40246731Skarels 	    }
40346731Skarels 
40446731Skarels 	    /*
40546731Skarels 	     * remaining fields -- key versions and mod info, should
40646731Skarels 	     * not be directly manipulated
40746731Skarels 	     */
40846731Skarels 	    if (changed) {
40946731Skarels 		if (kerb_put_principal(&principal_data[i], 1)) {
41046731Skarels 		    fprintf(stdout,
41146731Skarels 			"\nError updating Kerberos database");
41246731Skarels 		} else {
41346731Skarels 		    fprintf(stdout, "Edit O.K.");
41446731Skarels 		}
41546731Skarels 	    } else {
41646731Skarels 		fprintf(stdout, "Unchanged");
41746731Skarels 	    }
41846731Skarels 
41946731Skarels 
42046731Skarels 	    bzero(&principal_data[i].key_low, 4);
42146731Skarels 	    bzero(&principal_data[i].key_high, 4);
42246731Skarels 	    fflush(stdout);
42346731Skarels 	    break;
42446731Skarels 	}
42546731Skarels     }
42646731Skarels     if (more) {
42746731Skarels 	fprintf(stdout, "\nThere were more tuples found ");
42846731Skarels 	fprintf(stdout, "than there were space for");
42946731Skarels       }
43046731Skarels     return 1;
43146731Skarels }
43246731Skarels 
43346731Skarels 
no_core_dumps()43446731Skarels no_core_dumps()
43546731Skarels {
43646731Skarels 
43746731Skarels     signal(SIGQUIT, sig_exit);
43846731Skarels     signal(SIGILL, sig_exit);
43946731Skarels     signal(SIGTRAP, sig_exit);
44046731Skarels     signal(SIGIOT, sig_exit);
44146731Skarels     signal(SIGEMT, sig_exit);
44246731Skarels     signal(SIGFPE, sig_exit);
44346731Skarels     signal(SIGBUS, sig_exit);
44446731Skarels     signal(SIGSEGV, sig_exit);
44546731Skarels     signal(SIGSYS, sig_exit);
44646731Skarels }
44746731Skarels 
44846731Skarels void
sig_exit(sig,code,scp)44946731Skarels sig_exit(sig, code, scp)
45046731Skarels     int     sig, code;
45146731Skarels     struct sigcontext *scp;
45246731Skarels {
45346731Skarels     cleanup();
45446731Skarels     fprintf(stderr,
45546731Skarels 	"\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting",
45646731Skarels         sig, code, scp->sc_pc);
45746731Skarels     exit(-1);
45846731Skarels }
45946731Skarels 
46046731Skarels 
cleanup()46146731Skarels cleanup()
46246731Skarels {
46346731Skarels 
46446731Skarels     bzero(master_key, sizeof(master_key));
46546731Skarels     bzero(session_key, sizeof(session_key));
46646731Skarels     bzero(master_key_schedule, sizeof(master_key_schedule));
46746731Skarels     bzero(principal_data, sizeof(principal_data));
46846731Skarels     bzero(new_key, sizeof(new_key));
46946731Skarels     bzero(pw_str, sizeof(pw_str));
47046731Skarels }
Usage()47146731Skarels Usage()
47246731Skarels {
47346731Skarels     fprintf(stderr, "Usage: %s [-n]\n", progname);
47446731Skarels     exit(1);
47546731Skarels }
47646731Skarels 
47746731Skarels /* zaptime code taken from: */
47846731Skarels /*
47946731Skarels  * PARTIME		parse date/time string into a TM structure
48046731Skarels  *
48146731Skarels  * Usage:
48246731Skarels  *      #include "time.h"             -- expanded tm structure
48346731Skarels  *	char *str; struct tm *tp;
48446731Skarels  *	partime(str,tp);
48546731Skarels  * Returns:
48646731Skarels  *	0 if parsing failed
48746731Skarels  *	else time values in specified TM structure (unspecified values
48846731Skarels  *		set to TMNULL)
48946731Skarels  * Notes:
49046731Skarels  *	This code is quasi-public; it may be used freely in like software.
49146731Skarels  *	It is not to be sold, nor used in licensed software without
49246731Skarels  *	permission of the author.
49346731Skarels  *	For everyone's benefit, please report bugs and improvements!
49446731Skarels  * 	Copyright 1980 by Ken Harrenstien, SRI International.
49546731Skarels  *	(ARPANET: KLH @ SRI)
49646731Skarels  */
49746731Skarels 
zaptime(atm)49846731Skarels zaptime(atm)
49946731Skarels register struct tm *atm;
50046731Skarels /* clears atm */
50146731Skarels {
50246731Skarels 	atm->tm_sec = TMNULL;
50346731Skarels 	atm->tm_min = TMNULL;
50446731Skarels 	atm->tm_hour = TMNULL;
50546731Skarels 	atm->tm_mday = TMNULL;
50646731Skarels 	atm->tm_mon = TMNULL;
50746731Skarels 	atm->tm_year = TMNULL;
50846731Skarels 	atm->tm_wday = TMNULL;
50946731Skarels 	atm->tm_yday = TMNULL;
51046731Skarels 	atm->tm_isdst = TMNULL;
51146731Skarels 	atm->tm_zon = TMNULL;
51246731Skarels 	atm->tm_ampm = TMNULL;
51346731Skarels }
514