Initial import from FreeBSD RELENG_4:
[dragonfly.git] / crypto / kerberosIV / admin / kdb_init.c
1 /*
2  * Copyright 1987, 1988 by the Massachusetts Institute of Technology. 
3  *
4  * For copying and distribution information, please see the file
5  * <mit-copyright.h>. 
6  *
7  * program to initialize the database,  reports error if database file
8  * already exists. 
9  */
10 /* $FreeBSD: src/crypto/kerberosIV/admin/kdb_init.c,v 1.1.1.3.2.1 2003/02/14 22:37:37 nectar Exp $ */
11
12 #include "adm_locl.h"
13
14 RCSID("$Id: kdb_init.c,v 1.25 1999/09/16 20:37:21 assar Exp $");
15
16 enum ap_op {
17     NULL_KEY,                   /* setup null keys */
18     MASTER_KEY,                 /* use master key as new key */
19     RANDOM_KEY                  /* choose a random key */
20 };
21
22 static des_cblock master_key;
23 static des_key_schedule master_key_schedule;
24
25 /* use a return code to indicate success or failure.  check the return */
26 /* values of the routines called by this routine. */
27
28 static int
29 add_principal(char *name, char *instance, enum ap_op aap_op, int maxlife)
30 {
31     Principal principal;
32     des_cblock new_key;
33
34     memset(&principal, 0, sizeof(principal));
35     strlcpy(principal.name, name, ANAME_SZ);
36     strlcpy(principal.instance, instance, INST_SZ);
37     switch (aap_op) {
38     case NULL_KEY:
39         principal.key_low = 0;
40         principal.key_high = 0;
41         break;
42     case RANDOM_KEY:
43 #ifdef NOENCRYPTION
44         memset(new_key, 0, sizeof(des_cblock));
45         new_key[0] = 127;
46 #else
47         des_random_key(new_key);
48 #endif
49         kdb_encrypt_key (&new_key, &new_key, &master_key, master_key_schedule,
50                          DES_ENCRYPT);
51         copy_from_key(new_key, &principal.key_low, &principal.key_high);
52         memset(new_key, 0, sizeof(new_key));
53         break;
54     case MASTER_KEY:
55         memcpy(new_key, master_key, sizeof (des_cblock));
56         kdb_encrypt_key (&new_key, &new_key, &master_key, master_key_schedule,
57                          DES_ENCRYPT);
58         copy_from_key(new_key, &principal.key_low, &principal.key_high);
59         break;
60     }
61     principal.mod_date = time(0);
62     *principal.mod_date_txt = '\0';
63     principal.exp_date = principal.mod_date + 5 * 365 * 24 * 60 * 60;
64     *principal.exp_date_txt = '\0';
65
66     principal.attributes = 0;
67     principal.max_life = maxlife;
68
69     principal.kdc_key_ver = 1;
70     principal.key_version = 1;
71
72     strlcpy(principal.mod_name, "db_creation", ANAME_SZ);
73     strlcpy(principal.mod_instance, "", INST_SZ);
74     principal.old = 0;
75
76     if (kerb_db_put_principal(&principal, 1) != 1)
77         return -1;              /* FAIL */
78     
79     /* let's play it safe */
80     memset(new_key, 0, sizeof (des_cblock));
81     memset(&principal.key_low, 0, 4);
82     memset(&principal.key_high, 0, 4);
83     return 0;
84 }
85
86 int
87 main(int argc, char **argv)
88 {
89     char    realm[REALM_SZ];
90     char   *cp;
91     int code;
92     char *database;
93     
94     set_progname (argv[0]);
95
96     if (argc > 3) {
97         fprintf(stderr, "Usage: %s [realm-name] [database-name]\n", argv[0]);
98         return 1;
99     }
100     if (argc == 3) {
101         database = argv[2];
102         --argc;
103     } else
104         database = DBM_FILE;
105
106     /* Do this first, it'll fail if the database exists */
107     if ((code = kerb_db_create(database)) != 0)
108         err (1, "Couldn't create database %s", database);
109     kerb_db_set_name(database);
110
111     if (argc == 2)
112         strlcpy(realm, argv[1], REALM_SZ);
113     else {
114         if (krb_get_lrealm(realm, 1) != KSUCCESS)
115             strlcpy(realm, KRB_REALM, REALM_SZ);
116         fprintf(stderr, "Realm name [default  %s ]: ", realm);
117         if (fgets(realm, sizeof(realm), stdin) == NULL)
118             errx (1, "\nEOF reading realm");
119         if ((cp = strchr(realm, '\n')))
120             *cp = '\0';
121         if (!*realm)                    /* no realm given */
122                 if (krb_get_lrealm(realm, 1) != KSUCCESS)
123                     strlcpy(realm, KRB_REALM, REALM_SZ);
124     }
125     if (!k_isrealm(realm))
126         errx (1, "Bad kerberos realm name \"%s\"", realm);
127 #ifndef RANDOM_MKEY
128     printf("You will be prompted for the database Master Password.\n");
129     printf("It is important that you NOT FORGET this password.\n");
130 #else
131     printf("To generate a master key, please enter some random data.\n");
132     printf("You do not have to remember this.\n");
133 #endif
134     fflush(stdout);
135
136     if (kdb_get_master_key (KDB_GET_TWICE, &master_key,
137                             master_key_schedule) != 0)
138         errx (1, "Couldn't read master key.");
139
140 #ifdef RANDOM_MKEY
141     if(kdb_kstash(&master_key, MKEYFILE) < 0)
142         err (1, "Error writing master key");
143     fprintf(stderr, "Wrote master key to %s\n", MKEYFILE);
144 #endif
145
146     /* Maximum lifetime for changepw.kerberos (kadmin) tickets, 10 minutes */
147 #define ADMLIFE (1 + (CLOCK_SKEW/(5*60)))
148
149     /* Maximum lifetime for ticket granting tickets, 4 days or 21.25h */
150 #define TGTLIFE ((krb_life_to_time(0, 162) >= 24*60*60) ? 161 : 255)
151
152     /* This means that default lifetimes have not been initialized */
153 #define DEFLIFE 255
154
155 #define NOLIFE 0
156
157     if (
158         add_principal(KERB_M_NAME, KERB_M_INST, MASTER_KEY, NOLIFE) ||
159         add_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, NULL_KEY,DEFLIFE)||
160         add_principal(KRB_TICKET_GRANTING_TICKET, realm, RANDOM_KEY, TGTLIFE)||
161         add_principal(PWSERV_NAME, KRB_MASTER, RANDOM_KEY, ADMLIFE) 
162         ) {
163       putc ('\n', stderr);
164       errx (1, "couldn't initialize database.");
165     }
166
167     /* play it safe */
168     memset(master_key, 0, sizeof (des_cblock));
169     memset(master_key_schedule, 0, sizeof (des_key_schedule));
170     return 0;
171 }