Handle long lines in dump files
This commit is contained in:

committed by
Nico Williams

parent
496022fa37
commit
d2130e3312
140
kadmin/load.c
140
kadmin/load.c
@@ -31,6 +31,8 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "kadmin_locl.h"
|
#include "kadmin_locl.h"
|
||||||
#include "kadmin-commands.h"
|
#include "kadmin-commands.h"
|
||||||
#include <kadm5/private.h>
|
#include <kadm5/private.h>
|
||||||
@@ -308,9 +310,11 @@ parse_generation(char *str, GENERATION **gen)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* On error modify strp to point to the problem element */
|
||||||
static int
|
static int
|
||||||
parse_extensions(char *str, HDB_extensions **e)
|
parse_extensions(char **strp, HDB_extensions **e)
|
||||||
{
|
{
|
||||||
|
char *str = *strp;
|
||||||
char *p;
|
char *p;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -328,18 +332,21 @@ parse_extensions(char *str, HDB_extensions **e)
|
|||||||
void *d;
|
void *d;
|
||||||
|
|
||||||
len = strlen(p);
|
len = strlen(p);
|
||||||
d = malloc(len);
|
d = emalloc(len);
|
||||||
|
|
||||||
len = hex_decode(p, d, len);
|
len = hex_decode(p, d, len);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
free(d);
|
free(d);
|
||||||
|
*strp = p;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = decode_HDB_extension(d, len, &ext, NULL);
|
ret = decode_HDB_extension(d, len, &ext, NULL);
|
||||||
free(d);
|
free(d);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
*strp = p;
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
d = realloc((*e)->val, ((*e)->len + 1) * sizeof((*e)->val[0]));
|
d = realloc((*e)->val, ((*e)->len + 1) * sizeof((*e)->val[0]));
|
||||||
if (d == NULL)
|
if (d == NULL)
|
||||||
abort();
|
abort();
|
||||||
@@ -353,6 +360,45 @@ parse_extensions(char *str, HDB_extensions **e)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX: Principal names with '\n' cannot be dumped or loaded */
|
||||||
|
static int
|
||||||
|
my_fgetln(FILE *f, char **bufp, size_t *szp, size_t *lenp)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
size_t sz = *szp;
|
||||||
|
char *buf = *bufp;
|
||||||
|
char *p, *n;
|
||||||
|
|
||||||
|
if (!buf) {
|
||||||
|
buf = malloc(sz ? sz : 8192);
|
||||||
|
if (!buf)
|
||||||
|
return ENOMEM;
|
||||||
|
if (!sz)
|
||||||
|
sz = 8192;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
while ((p = fgets(&buf[len], sz-len, f)) != NULL) {
|
||||||
|
len += strlen(&buf[len]);
|
||||||
|
if (buf[len-1] == '\n')
|
||||||
|
break;
|
||||||
|
if (feof(f))
|
||||||
|
break;
|
||||||
|
if (sz > SIZE_MAX/2 ||
|
||||||
|
(n = realloc(buf, sz += 1 + (sz >> 1))) == NULL) {
|
||||||
|
free(buf);
|
||||||
|
*bufp = NULL;
|
||||||
|
*szp = 0;
|
||||||
|
*lenp = 0;
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
buf = n;
|
||||||
|
}
|
||||||
|
*bufp = buf;
|
||||||
|
*szp = sz;
|
||||||
|
*lenp = len;
|
||||||
|
return 0; /* *len == 0 || no EOL -> EOF */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the dump file in `filename' and create the database (merging
|
* Parse the dump file in `filename' and create the database (merging
|
||||||
@@ -363,17 +409,20 @@ static int
|
|||||||
doit(const char *filename, int mergep)
|
doit(const char *filename, int mergep)
|
||||||
{
|
{
|
||||||
krb5_error_code ret = 0;
|
krb5_error_code ret = 0;
|
||||||
|
krb5_error_code ret2 = 0;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char s[8192]; /* XXX should fix this properly */
|
char *line = NULL;
|
||||||
|
size_t linesz = 0;
|
||||||
|
size_t linelen = 0;
|
||||||
char *p;
|
char *p;
|
||||||
int line;
|
int lineno;
|
||||||
int flags = O_RDWR;
|
int flags = O_RDWR;
|
||||||
struct entry e;
|
struct entry e;
|
||||||
hdb_entry_ex ent;
|
hdb_entry_ex ent;
|
||||||
HDB *db = _kadm5_s_get_db(kadm_handle);
|
HDB *db = _kadm5_s_get_db(kadm_handle);
|
||||||
|
|
||||||
f = fopen(filename, "r");
|
f = fopen(filename, "r");
|
||||||
if(f == NULL){
|
if (f == NULL) {
|
||||||
krb5_warn(context, errno, "fopen(%s)", filename);
|
krb5_warn(context, errno, "fopen(%s)", filename);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -396,29 +445,27 @@ doit(const char *filename, int mergep)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!mergep)
|
if (!mergep)
|
||||||
flags |= O_CREAT | O_TRUNC;
|
flags |= O_CREAT | O_TRUNC;
|
||||||
ret = db->hdb_open(context, db, flags, 0600);
|
ret = db->hdb_open(context, db, flags, 0600);
|
||||||
if(ret){
|
if (ret){
|
||||||
krb5_warn(context, ret, "hdb_open");
|
krb5_warn(context, ret, "hdb_open");
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
(void) db->hdb_set_sync(context, db, 0);
|
(void) db->hdb_set_sync(context, db, 0);
|
||||||
line = 0;
|
for (lineno = 1;
|
||||||
ret = 0;
|
(ret2 = my_fgetln(f, &line, &linesz, &linelen)) == 0 && linelen > 0;
|
||||||
while(fgets(s, sizeof(s), f) != NULL) {
|
++lineno) {
|
||||||
line++;
|
p = line;
|
||||||
|
|
||||||
p = s;
|
|
||||||
while (isspace((unsigned char)*p))
|
while (isspace((unsigned char)*p))
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
e.principal = p;
|
e.principal = p;
|
||||||
for(p = s; *p; p++){
|
for (p = line; *p; p++){
|
||||||
if(*p == '\\')
|
if (*p == '\\') /* Support '\n' escapes??? */
|
||||||
p++;
|
p++;
|
||||||
else if(isspace((unsigned char)*p)) {
|
else if (isspace((unsigned char)*p)) {
|
||||||
*p = 0;
|
*p = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -459,100 +506,119 @@ doit(const char *filename, int mergep)
|
|||||||
skip_next(p);
|
skip_next(p);
|
||||||
|
|
||||||
memset(&ent, 0, sizeof(ent));
|
memset(&ent, 0, sizeof(ent));
|
||||||
ret = krb5_parse_name(context, e.principal, &ent.entry.principal);
|
ret2 = krb5_parse_name(context, e.principal, &ent.entry.principal);
|
||||||
if(ret) {
|
if (ret2) {
|
||||||
const char *msg = krb5_get_error_message(context, ret);
|
const char *msg = krb5_get_error_message(context, ret);
|
||||||
fprintf(stderr, "%s:%d:%s (%s)\n",
|
fprintf(stderr, "%s:%d:%s (%s)\n",
|
||||||
filename, line, msg, e.principal);
|
filename, lineno, msg, e.principal);
|
||||||
krb5_free_error_message(context, msg);
|
krb5_free_error_message(context, msg);
|
||||||
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_keys(&ent.entry, e.key)) {
|
if (parse_keys(&ent.entry, e.key)) {
|
||||||
fprintf (stderr, "%s:%d:error parsing keys (%s)\n",
|
fprintf (stderr, "%s:%d:error parsing keys (%s)\n",
|
||||||
filename, line, e.key);
|
filename, lineno, e.key);
|
||||||
hdb_free_entry (context, &ent);
|
hdb_free_entry (context, &ent);
|
||||||
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_event(&ent.entry.created_by, e.created) == -1) {
|
if (parse_event(&ent.entry.created_by, e.created) == -1) {
|
||||||
fprintf (stderr, "%s:%d:error parsing created event (%s)\n",
|
fprintf (stderr, "%s:%d:error parsing created event (%s)\n",
|
||||||
filename, line, e.created);
|
filename, lineno, e.created);
|
||||||
hdb_free_entry (context, &ent);
|
hdb_free_entry (context, &ent);
|
||||||
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (parse_event_alloc (&ent.entry.modified_by, e.modified) == -1) {
|
if (parse_event_alloc (&ent.entry.modified_by, e.modified) == -1) {
|
||||||
fprintf (stderr, "%s:%d:error parsing event (%s)\n",
|
fprintf (stderr, "%s:%d:error parsing event (%s)\n",
|
||||||
filename, line, e.modified);
|
filename, lineno, e.modified);
|
||||||
hdb_free_entry (context, &ent);
|
hdb_free_entry (context, &ent);
|
||||||
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (parse_time_string_alloc (&ent.entry.valid_start, e.valid_start) == -1) {
|
if (parse_time_string_alloc (&ent.entry.valid_start, e.valid_start) == -1) {
|
||||||
fprintf (stderr, "%s:%d:error parsing time (%s)\n",
|
fprintf (stderr, "%s:%d:error parsing time (%s)\n",
|
||||||
filename, line, e.valid_start);
|
filename, lineno, e.valid_start);
|
||||||
hdb_free_entry (context, &ent);
|
hdb_free_entry (context, &ent);
|
||||||
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (parse_time_string_alloc (&ent.entry.valid_end, e.valid_end) == -1) {
|
if (parse_time_string_alloc (&ent.entry.valid_end, e.valid_end) == -1) {
|
||||||
fprintf (stderr, "%s:%d:error parsing time (%s)\n",
|
fprintf (stderr, "%s:%d:error parsing time (%s)\n",
|
||||||
filename, line, e.valid_end);
|
filename, lineno, e.valid_end);
|
||||||
hdb_free_entry (context, &ent);
|
hdb_free_entry (context, &ent);
|
||||||
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (parse_time_string_alloc (&ent.entry.pw_end, e.pw_end) == -1) {
|
if (parse_time_string_alloc (&ent.entry.pw_end, e.pw_end) == -1) {
|
||||||
fprintf (stderr, "%s:%d:error parsing time (%s)\n",
|
fprintf (stderr, "%s:%d:error parsing time (%s)\n",
|
||||||
filename, line, e.pw_end);
|
filename, lineno, e.pw_end);
|
||||||
hdb_free_entry (context, &ent);
|
hdb_free_entry (context, &ent);
|
||||||
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_integer_alloc (&ent.entry.max_life, e.max_life) == -1) {
|
if (parse_integer_alloc (&ent.entry.max_life, e.max_life) == -1) {
|
||||||
fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n",
|
fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n",
|
||||||
filename, line, e.max_life);
|
filename, lineno, e.max_life);
|
||||||
hdb_free_entry (context, &ent);
|
hdb_free_entry (context, &ent);
|
||||||
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (parse_integer_alloc (&ent.entry.max_renew, e.max_renew) == -1) {
|
if (parse_integer_alloc (&ent.entry.max_renew, e.max_renew) == -1) {
|
||||||
fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n",
|
fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n",
|
||||||
filename, line, e.max_renew);
|
filename, lineno, e.max_renew);
|
||||||
hdb_free_entry (context, &ent);
|
hdb_free_entry (context, &ent);
|
||||||
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_hdbflags2int (&ent.entry.flags, e.flags) != 1) {
|
if (parse_hdbflags2int (&ent.entry.flags, e.flags) != 1) {
|
||||||
fprintf (stderr, "%s:%d:error parsing flags (%s)\n",
|
fprintf (stderr, "%s:%d:error parsing flags (%s)\n",
|
||||||
filename, line, e.flags);
|
filename, lineno, e.flags);
|
||||||
hdb_free_entry (context, &ent);
|
hdb_free_entry (context, &ent);
|
||||||
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(parse_generation(e.generation, &ent.entry.generation) == -1) {
|
if(parse_generation(e.generation, &ent.entry.generation) == -1) {
|
||||||
fprintf (stderr, "%s:%d:error parsing generation (%s)\n",
|
fprintf (stderr, "%s:%d:error parsing generation (%s)\n",
|
||||||
filename, line, e.generation);
|
filename, lineno, e.generation);
|
||||||
hdb_free_entry (context, &ent);
|
hdb_free_entry (context, &ent);
|
||||||
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(parse_extensions(e.extensions, &ent.entry.extensions) == -1) {
|
if (parse_extensions(&e.extensions, &ent.entry.extensions) == -1) {
|
||||||
fprintf (stderr, "%s:%d:error parsing extension (%s)\n",
|
fprintf (stderr, "%s:%d:error parsing extension (%s)\n",
|
||||||
filename, line, e.extensions);
|
filename, lineno, e.extensions);
|
||||||
hdb_free_entry (context, &ent);
|
hdb_free_entry (context, &ent);
|
||||||
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = db->hdb_store(context, db, HDB_F_REPLACE, &ent);
|
ret2 = db->hdb_store(context, db, HDB_F_REPLACE, &ent);
|
||||||
hdb_free_entry (context, &ent);
|
hdb_free_entry (context, &ent);
|
||||||
if (ret) {
|
if (ret2) {
|
||||||
krb5_warn(context, ret, "db_store");
|
krb5_warn(context, ret, "db_store");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = db->hdb_set_sync(context, db, 1);
|
free(line);
|
||||||
if (ret)
|
if (ret2)
|
||||||
|
ret = ret2;
|
||||||
|
ret2 = db->hdb_set_sync(context, db, 1);
|
||||||
|
if (ret2) {
|
||||||
krb5_err(context, 1, ret, "failed to sync the HDB");
|
krb5_err(context, 1, ret, "failed to sync the HDB");
|
||||||
|
ret = ret2;
|
||||||
|
}
|
||||||
(void) kadm5_log_end(kadm_handle);
|
(void) kadm5_log_end(kadm_handle);
|
||||||
ret = db->hdb_close(context, db);
|
ret2 = db->hdb_close(context, db);
|
||||||
|
if (ret2 != 0)
|
||||||
|
ret = ret2;
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return ret != 0;
|
return ret != 0;
|
||||||
}
|
}
|
||||||
|
@@ -97,37 +97,43 @@ nexttoken(char **p)
|
|||||||
|
|
||||||
#include <kadm5/admin.h>
|
#include <kadm5/admin.h>
|
||||||
|
|
||||||
/* XXX This is broken: what if the princ name has a \n?! */
|
/* XXX: Principal names with '\n' cannot be dumped or loaded */
|
||||||
static int
|
static int
|
||||||
my_fgetln(FILE *f, char **buf, size_t *sz, size_t *len)
|
my_fgetln(FILE *f, char **bufp, size_t *szp, size_t *lenp)
|
||||||
{
|
{
|
||||||
|
size_t len;
|
||||||
|
size_t sz = *szp;
|
||||||
|
char *buf = *bufp;
|
||||||
char *p, *n;
|
char *p, *n;
|
||||||
|
|
||||||
if (!*buf) {
|
if (!buf) {
|
||||||
*buf = malloc(*sz ? *sz : 2048);
|
buf = malloc(sz ? sz : 8192);
|
||||||
if (!*buf)
|
if (!buf)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
if (!*sz)
|
if (!sz)
|
||||||
*sz = 2048;
|
sz = 8192;
|
||||||
}
|
}
|
||||||
*len = 0;
|
|
||||||
while ((p = fgets(&(*buf)[*len], *sz - *len, f))) {
|
len = 0;
|
||||||
*len = strlen(*buf);
|
while ((p = fgets(&buf[len], sz-len, f)) != NULL) {
|
||||||
|
len += strlen(&buf[len]);
|
||||||
|
if (buf[len-1] == '\n')
|
||||||
|
break;
|
||||||
if (feof(f))
|
if (feof(f))
|
||||||
return 0;
|
break;
|
||||||
if (strchr(*buf, '\n'))
|
if (sz > SIZE_MAX/2 ||
|
||||||
return 0;
|
(n = realloc(buf, sz += 1 + (sz >> 1))) == NULL) {
|
||||||
n = realloc(*buf, *sz + (*sz >> 1));
|
free(buf);
|
||||||
if (!n) {
|
*bufp = NULL;
|
||||||
free(*buf);
|
*szp = 0;
|
||||||
*buf = NULL;
|
*lenp = 0;
|
||||||
*sz = 0;
|
|
||||||
*len = 0;
|
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
*buf = n;
|
buf = n;
|
||||||
*sz += *sz >> 1;
|
|
||||||
}
|
}
|
||||||
|
*bufp = buf;
|
||||||
|
*szp = sz;
|
||||||
|
*lenp = len;
|
||||||
return 0; /* *len == 0 || no EOL -> EOF */
|
return 0; /* *len == 0 || no EOL -> EOF */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,11 +161,11 @@ mit_prop_dump(void *arg, const char *file)
|
|||||||
if (!sp)
|
if (!sp)
|
||||||
goto out;
|
goto out;
|
||||||
while ((ret = my_fgetln(f, &line, &line_bufsz, &line_len)) == 0 &&
|
while ((ret = my_fgetln(f, &line, &line_bufsz, &line_len)) == 0 &&
|
||||||
!feof(f)) {
|
line_len > 0) {
|
||||||
char *p = line;
|
char *p = line;
|
||||||
char *q;
|
char *q;
|
||||||
lineno++;
|
|
||||||
|
|
||||||
|
lineno++;
|
||||||
if(strncmp(line, "kdb5_util", strlen("kdb5_util")) == 0) {
|
if(strncmp(line, "kdb5_util", strlen("kdb5_util")) == 0) {
|
||||||
int major;
|
int major;
|
||||||
q = nexttoken(&p);
|
q = nexttoken(&p);
|
||||||
|
Reference in New Issue
Block a user