1 /*
2  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
3  *
4  *	Openvision retains the copyright to derivative works of
5  *	this source code.  Do *NOT* create a derivative of this
6  *	source code before consulting with your legal department.
7  *	Do *NOT* integrate *ANY* of this source code into another
8  *	product before consulting with your legal department.
9  *
10  *	For further information, read the top-level Openvision
11  *	copyright which is contained in the top-level MIT Kerberos
12  *	copyright.
13  *
14  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
15  *
16  */
17 
18 
19 #include    <unistd.h>
20 #include    <string.h>
21 #include    <stdlib.h>
22 #include    "autoconf.h"
23 #ifdef HAVE_MEMORY_H
24 #include    <memory.h>
25 #endif
26 
27 #include    <k5-int.h>
28 #include <kadm5/admin.h>
29 #include <kadm5/server_internal.h>
30 #include    <kdb.h>
31 #include    "import_err.h"
32 #include    "kdb5_util.h"
33 #include    "nstrtok.h"
34 
35 #define LINESIZE	32768 /* XXX */
36 #define PLURAL(count)	(((count) == 1) ? error_message(IMPORT_SINGLE_RECORD) : error_message(IMPORT_PLURAL_RECORDS))
37 
parse_pw_hist_ent(current,hist)38 static int parse_pw_hist_ent(current, hist)
39    char *current;
40    osa_pw_hist_ent *hist;
41 {
42      int tmp, i, j, ret;
43      char *cp;
44 
45      ret = 0;
46      hist->n_key_data = 1;
47 
48      hist->key_data = (krb5_key_data *) malloc(hist->n_key_data *
49 					       sizeof(krb5_key_data));
50      if (hist->key_data == NULL)
51 	  return ENOMEM;
52      memset(hist->key_data, 0, sizeof(krb5_key_data)*hist->n_key_data);
53 
54      for (i = 0; i < hist->n_key_data; i++) {
55 	  krb5_key_data *key_data = &hist->key_data[i];
56 
57 	  key_data->key_data_ver = 1;
58 
59 	  if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
60 	       com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
61 	       ret = IMPORT_FAILED;
62 	       goto done;
63 	  }
64 	  key_data->key_data_type[0] = atoi(cp);
65 
66 	  if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
67 	       com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
68 	       ret =  IMPORT_FAILED;
69 	       goto done;
70 	  }
71 	  key_data->key_data_length[0] = atoi(cp);
72 
73 	  if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
74 	       com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
75 	       ret = IMPORT_FAILED;
76 	       goto done;
77 	  }
78 	  if(!(key_data->key_data_contents[0] =
79 	       (krb5_octet *) malloc(key_data->key_data_length[0]+1))) {
80 	       ret = ENOMEM;
81 	       goto done;
82 	  }
83 	  for(j = 0; j < key_data->key_data_length[0]; j++) {
84 	       if(sscanf(cp, "%02x", &tmp) != 1) {
85 		    com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
86 		    ret = IMPORT_FAILED;
87 		    goto done;
88 	       }
89 	       key_data->key_data_contents[0][j] = tmp;
90 	       cp = strchr(cp, ' ') + 1;
91 	  }
92      }
93 
94 done:
95      return ret;
96 }
97 
98 /*
99  * Function: parse_principal
100  *
101  * Purpose: parse principal line in db dump file
102  *
103  * Arguments:
104  * 	<return value>	0 on success, error code on failure
105  *
106  * Requires:
107  *	principal database to be opened.
108  *	nstrtok(3) to have a valid buffer in memory.
109  *
110  * Effects:
111  *	[effects]
112  *
113  * Modifies:
114  *	[modifies]
115  *
116  */
process_ov_principal(fname,kcontext,filep,verbose,linenop)117 int process_ov_principal(fname, kcontext, filep, verbose, linenop)
118     char		*fname;
119     krb5_context	kcontext;
120     FILE		*filep;
121     int			verbose;
122     int			*linenop;
123 {
124     XDR			    xdrs;
125     osa_princ_ent_t	    rec;
126     krb5_error_code	    ret;
127     krb5_tl_data	    tl_data;
128     krb5_principal	    princ;
129     krb5_db_entry	    kdb;
130     char		    *current;
131     char		    *cp;
132     int			    x, one;
133     krb5_boolean	    more;
134     char		    line[LINESIZE];
135 
136     if (fgets(line, LINESIZE, filep) == (char *) NULL) {
137 	 return IMPORT_BAD_FILE;
138     }
139     if((cp = nstrtok(line, "\t")) == NULL)
140 	return IMPORT_BAD_FILE;
141     if((rec = (osa_princ_ent_t) malloc(sizeof(osa_princ_ent_rec))) == NULL)
142 	return ENOMEM;
143     memset(rec, 0, sizeof(osa_princ_ent_rec));
144     if((ret = krb5_parse_name(kcontext, cp, &princ)))
145 	goto done;
146     krb5_unparse_name(kcontext, princ, &current);
147     if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
148 	com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
149 	ret =  IMPORT_FAILED;
150 	goto done;
151     } else {
152 	if(strcmp(cp, "")) {
153 	    if((rec->policy = (char *) malloc(strlen(cp)+1)) == NULL)  {
154 		ret = ENOMEM;
155 		goto done;
156 	    }
157 	    strcpy(rec->policy, cp);
158 	} else rec->policy = NULL;
159     }
160     if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
161 	com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
162 	ret = IMPORT_FAILED;
163 	goto done;
164     }
165     rec->aux_attributes = strtol(cp, (char  **)NULL, 16);
166     if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
167 	com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
168 	ret = IMPORT_FAILED;
169 	goto done;
170     }
171     rec->old_key_len = atoi(cp);
172     if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
173 	com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
174 	ret = IMPORT_FAILED;
175 	goto done;
176     }
177     rec->old_key_next = atoi(cp);
178     if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
179 	com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
180 	ret = IMPORT_FAILED;
181 	goto done;
182     }
183     rec->admin_history_kvno = atoi(cp);
184     if (! rec->old_key_len) {
185        rec->old_keys = NULL;
186     } else {
187        if(!(rec->old_keys = (osa_pw_hist_ent *)
188 	    malloc(sizeof(osa_pw_hist_ent) * rec->old_key_len))) {
189 	  ret = ENOMEM;
190 	  goto done;
191        }
192        memset(rec->old_keys,0,
193 	      sizeof(osa_pw_hist_ent) * rec->old_key_len);
194        for(x = 0; x < rec->old_key_len; x++)
195 	    parse_pw_hist_ent(current, &rec->old_keys[x]);
196     }
197 
198     xdralloc_create(&xdrs, XDR_ENCODE);
199     if (! xdr_osa_princ_ent_rec(&xdrs, rec)) {
200 	 xdr_destroy(&xdrs);
201 	 ret = KADM5_XDR_FAILURE;
202 	 goto done;
203     }
204 
205     tl_data.tl_data_type = KRB5_TL_KADM_DATA;
206     tl_data.tl_data_length = xdr_getpos(&xdrs);
207     tl_data.tl_data_contents = (krb5_octet *) xdralloc_getdata(&xdrs);
208 
209     one = 1;
210     ret = krb5_db_get_principal(kcontext, princ, &kdb, &one, &more);
211     if (ret)
212 	 goto done;
213 
214     ret = krb5_dbe_update_tl_data(kcontext, &kdb, &tl_data);
215     if (ret)
216 	 goto done;
217 
218     ret = krb5_db_put_principal(kcontext, &kdb, &one);
219     if (ret)
220 	 goto done;
221 
222     xdr_destroy(&xdrs);
223 
224     (*linenop)++;
225 
226 done:
227     free(current);
228     krb5_free_principal(kcontext, princ);
229     osa_free_princ_ent(rec);
230     return ret;
231 }
232