diff --git a/kdc/hprop.c b/kdc/hprop.c index 1154d260a..1fb4582ff 100644 --- a/kdc/hprop.c +++ b/kdc/hprop.c @@ -139,11 +139,13 @@ v4_prop(void *arg, Principal *p) ret = krb5_425_conv_principal(pd->context, p->name, p->instance, realm, &ent.principal); if(ret){ - krb5_warn(pd->context, ret, "%s.%s@%s", p->name, p->instance, realm); + krb5_warn(pd->context, ret, + "krb5_425_conv_principal %s.%s@%s", + p->name, p->instance, realm); return 0; } - if(verbose_flag){ + if(verbose_flag) { char *s; krb5_unparse_name_short(pd->context, ent.principal, &s); krb5_warnx(pd->context, "%s.%s -> %s", p->name, p->instance, s); @@ -164,7 +166,8 @@ v4_prop(void *arg, Principal *p) unsigned char null_key[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; memcpy(key, &p->key_low, 4); memcpy(key + 4, &p->key_high, 4); - kdb_encrypt_key((des_cblock*)key, (des_cblock*)key, &mkey4, msched4, 0); + kdb_encrypt_key((des_cblock*)key, (des_cblock*)key, + &mkey4, msched4, DES_DECRYPT); if(memcmp(key, null_key, sizeof(null_key)) == 0) { free_Key(&ent.keys.val[0]); ent.keys.val = 0; @@ -439,21 +442,135 @@ get_creds(krb5_context context, krb5_ccache *cache) if(ret) krb5_err(context, 1, ret, "krb5_cc_store_cred"); } -int main(int argc, char **argv) +static void +iterate (krb5_context context, + const char *database, + const char *afs_cell, + HDB *db, + int v4_db, int ka_db, + struct prop_data *pd) +{ +#ifdef KRB4 + if(v4_db) { + int e = kerb_db_iterate ((k_iter_proc_t)v4_prop, pd); + if(e) + krb5_errx(context, 1, "kerb_db_iterate: %s", + krb_get_err_text(e)); +#ifdef KASERVER_DB + } else if(ka_db) { + int e = ka_dump(pd, database, afs_cell); + if(e) + krb5_errx(context, 1, "ka_dump: %s", krb_get_err_text(e)); +#endif + } else +#endif + { + krb5_error_code ret = hdb_foreach(context, db, HDB_F_DECRYPT, + v5_prop, pd); + if(ret) + krb5_err(context, 1, ret, "hdb_foreach"); + } +} + +static int +dump_database (krb5_context context, int v4_db, int ka_db, + const char *database, const char *afs_cell, + HDB *db) +{ + struct prop_data pd; + + pd.context = context; + pd.auth_context = NULL; + pd.sock = STDOUT_FILENO; + + iterate (context, database, afs_cell, db, v4_db, ka_db, &pd); + return 0; +} + +static int +propagate_database (krb5_context context, int v4_db, int ka_db, + const char *database, const char *afs_cell, + HDB *db, krb5_ccache ccache, + int optind, int argc, char **argv) +{ + krb5_principal server; + krb5_error_code ret; + int i; + + for(i = optind; i < argc; i++){ + krb5_auth_context auth_context; + int fd; + struct prop_data pd; + krb5_data data; + + fd = open_socket(context, argv[i]); + if(fd < 0) { + krb5_warn (context, errno, "connect %s", argv[i]); + continue; + } + + ret = krb5_sname_to_principal(context, argv[i], + HPROP_NAME, KRB5_NT_SRV_HST, &server); + if(ret) { + krb5_warn(context, ret, "krb5_sname_to_principal(%s)", argv[i]); + close(fd); + continue; + } + + auth_context = NULL; + ret = krb5_sendauth(context, + &auth_context, + &fd, + HPROP_VERSION, + NULL, + server, + AP_OPTS_MUTUAL_REQUIRED, + NULL, /* in_data */ + NULL, /* in_creds */ + ccache, + NULL, + NULL, + NULL); + + if(ret) { + krb5_warn(context, ret, "krb5_sendauth"); + close(fd); + continue; + } + + pd.context = context; + pd.auth_context = NULL; + pd.sock = fd; + + iterate (context, database, afs_cell, db, + v4_db, ka_db, &pd); + + data.data = NULL; + data.length = 0; + ret = send_priv(context, auth_context, &data, fd); + if(ret) + krb5_warn(context, ret, "send_priv"); + + ret = recv_priv(context, auth_context, fd, &data); + if(ret) + krb5_warn(context, ret, "recv_priv"); + else + krb5_data_free (&data); + + krb5_auth_con_free(context, auth_context); + close(fd); + } + return 0; +} + +int +main(int argc, char **argv) { krb5_error_code ret; krb5_context context; - krb5_auth_context ac; - krb5_principal server; krb5_ccache ccache; - int fd; HDB *db; int optind = 0; - int i; -#ifdef KRB4 - int e; -#endif - set_progname(argv[0]); @@ -482,29 +599,36 @@ int main(int argc, char **argv) ret = hdb_read_master_key(context, mkeyfile, &mkey5); if(ret && ret != ENOENT) krb5_err(context, 1, ret, "hdb_read_master_key"); - if(ret){ + if(ret) { if(encrypt_flag || decrypt_flag) krb5_errx(context, 1, "No master key file found"); - }else{ + } else { ret = hdb_process_master_key(context, mkey5, &msched5); if(ret) krb5_err(context, 1, ret, "hdb_process_master_key"); } #ifdef KRB4 - if(v4_db){ - e = kerb_db_set_name (database); - if(e) krb5_errx(context, 1, "kerb_db_set_name: %s", krb_get_err_text(e)); + if(v4_db) { + int e = kerb_db_set_name (database); + if(e) + krb5_errx(context, 1, "kerb_db_set_name: %s", + krb_get_err_text(e)); e = kdb_get_master_key(0, &mkey4, msched4); - if(e) krb5_errx(context, 1, "kdb_get_master_key: %s", krb_get_err_text(e)); + if(e) + krb5_errx(context, 1, "kdb_get_master_key: %s", + krb_get_err_text(e)); e = krb_get_lrealm(realm, 1); - if(e) krb5_errx(context, 1, "krb_get_lrealm: %s", krb_get_err_text(e)); + if(e) + krb5_errx(context, 1, "krb_get_lrealm: %s", + krb_get_err_text(e)); #ifdef KASERVER_DB - }else if(ka_db) { - e = krb_get_lrealm(realm, 1); - if(e) krb5_errx(context, 1, "krb_get_lrealm: %s", krb_get_err_text(e)); + } else if(ka_db) { + int e = krb_get_lrealm(realm, 1); + if(e) + krb5_errx(context, 1, "krb_get_lrealm: %s", krb_get_err_text(e)); #endif - }else + } else #endif { ret = hdb_create (context, &db, database); @@ -515,108 +639,13 @@ int main(int argc, char **argv) krb5_err(context, 1, ret, "db->open"); } - if(to_stdout){ - struct prop_data pd; - pd.context = context; - pd.auth_context = ac; - pd.sock = fd; - -#ifdef KRB4 - if(v4_db){ - e = kerb_db_iterate ((k_iter_proc_t)v4_prop, &pd); - if(e) - krb5_errx(context, 1, "kerb_db_iterate: %s", - krb_get_err_text(e)); -#ifdef KASERVER_DB - } else if(ka_db) { - e = ka_dump(&pd, database, afs_cell); - if(e) krb5_errx(context, 1, "ka_dump: %s", krb_get_err_text(e)); -#endif - } else -#endif - { - ret = hdb_foreach(context, db, HDB_F_DECRYPT, v5_prop, &pd); - if(ret) - krb5_err(context, 1, ret, "hdb_foreach"); - } - }else{ - - for(i = optind; i < argc; i++){ - fd = open_socket(context, argv[i]); - if(fd < 0) - continue; - - ret = krb5_sname_to_principal(context, argv[i], - HPROP_NAME, KRB5_NT_SRV_HST, &server); - if(ret) { - krb5_warn(context, ret, "krb5_sname_to_principal(%s)", argv[i]); - close(fd); - continue; - } - - ac = NULL; - ret = krb5_sendauth(context, - &ac, - &fd, - HPROP_VERSION, - NULL, - server, - AP_OPTS_MUTUAL_REQUIRED, - NULL, /* in_data */ - NULL, /* in_creds */ - ccache, - NULL, - NULL, - NULL); - - if(ret){ - krb5_warn(context, ret, "krb5_sendauth"); - close(fd); - continue; - } - - { - struct prop_data pd; - pd.context = context; - pd.auth_context = ac; - pd.sock = fd; - -#ifdef KRB4 - if(v4_db) - e = kerb_db_iterate ((k_iter_proc_t)v4_prop, &pd); -#ifdef KASERVER_DB - else if(ka_db) { - e = ka_dump(&pd, database, afs_cell); - if(e) krb5_errx(context, 1, "ka_dump: %s", - krb_get_err_text(e)); - } -#endif - else -#endif - ret = hdb_foreach(context, db, HDB_F_DECRYPT, - v5_prop, &pd); - } - if(ret) - krb5_warn(context, ret, "krb5_sendauth"); - else { - krb5_data data; - data.data = NULL; - data.length = 0; - ret = send_priv(context, ac, &data, fd); - } - - { - krb5_data data; - ret = recv_priv(context, ac, fd, &data); - if(ret) krb5_warn(context, ret, "recv_priv"); - if(data.length != 0) - krb5_data_free(&data); /* XXX */ - } - - if(ret) krb5_warn(context, ret, "send_priv"); - krb5_auth_con_free(context, ac); - close(fd); - } - } - exit(0); + if (to_stdout) + dump_database (context, v4_db, ka_db, + database, afs_cell, db); + else + propagate_database (context, v4_db, ka_db, + database, afs_cell, + db, ccache, + optind, argc, argv); + return 0; } diff --git a/kdc/hpropd.c b/kdc/hpropd.c index e22431b2a..86840bfb5 100644 --- a/kdc/hpropd.c +++ b/kdc/hpropd.c @@ -48,101 +48,100 @@ time2str(time_t t) } static int -dump_krb4(krb5_context context, hdb_entry *ent, int fd) { - char name[ANAME_SZ]; - char instance[INST_SZ]; - char realm[REALM_SZ]; - char buf[1024]=""; - char *p; - int i; - int ret; - char *princ_name; - Event *modifier; +dump_krb4(krb5_context context, hdb_entry *ent, int fd) +{ + char name[ANAME_SZ]; + char instance[INST_SZ]; + char realm[REALM_SZ]; + char buf[1024]; + char *p; + int i; + int ret; + char *princ_name; + Event *modifier; - ret = krb5_524_conv_principal(context, ent->principal, - name, instance, realm); - if (ret) { - krb5_unparse_name(context, ent->principal, &princ_name); - krb5_warn(context, ret, "%s", princ_name); - free(princ_name); - return -1; - } - strcat(buf, name); - strcat(buf, " "); - strcat(buf, (strlen(instance) != 0) ? instance : "*"); - strcat(buf, " "); + ret = krb5_524_conv_principal(context, ent->principal, + name, instance, realm); + if (ret) { + krb5_unparse_name(context, ent->principal, &princ_name); + krb5_warn(context, ret, "%s", princ_name); + free(princ_name); + return -1; + } + snprintf (buf, sizeof(buf), "%s %s ", name, + (strlen(instance) != 0) ? instance : "*"); - if (ent->max_life) { - asprintf(&p, "%d", krb_time_to_life(0, *ent->max_life)); + if (ent->max_life) { + asprintf(&p, "%d", krb_time_to_life(0, *ent->max_life)); + strcat(buf, p); + free(p); + } else + strcat(buf, "255"); + strcat(buf, " "); + + i = 0; + while (i < ent->keys.len && + ent->keys.val[i].key.keytype != KEYTYPE_DES) + ++i; + + if (i == ent->keys.len) { + krb5_warnx(context, "No DES key for %s.%s", name, instance); + return -1; + } + + if (ent->keys.val[i].mkvno) + asprintf(&p, "%d ", *ent->keys.val[i].mkvno); + else + asprintf(&p, "%d ", 1); strcat(buf, p); free(p); - } - else - strcat(buf, "255"); - strcat(buf, " "); - i = 0; - while (i < ent->keys.len && ((ent->keys.val)+i)->key.keytype != KEYTYPE_DES) { - i++; - } - if (i == ent->keys.len) { - krb5_warnx(context, "No DES key for %s.%s", name, instance); - return -1; - } + asprintf(&p, "%d ", ent->kvno); + strcat(buf, p); + free(p); - if (ent->keys.val[i].mkvno) - asprintf(&p, "%d ", *ent->keys.val[i].mkvno); - else - asprintf(&p, "%d ", 1); - strcat(buf, p); - free(p); + asprintf(&p, "%d ", 0); /* Attributes are always 0*/ + strcat(buf, p); + free(p); - asprintf(&p, "%d ", ent->kvno); - strcat(buf, p); - free(p); - - asprintf(&p, "%d ", 0); /* Attributes are always 0*/ - strcat(buf, p); - free(p); - - { - u_int32_t *key = ((ent->keys.val)+i)->key.keyvalue.data; - kdb_encrypt_key((des_cblock*)key, (des_cblock*)key, &mkey4, msched4, 1); - asprintf(&p, "%x %x ", (int)htonl(*key), (int)htonl(*(key+1))); - strcat(buf, p); - free(p); - - } + { + u_int32_t *key = ent->keys.val[i].key.keyvalue.data; + kdb_encrypt_key((des_cblock*)key, (des_cblock*)key, + &mkey4, msched4, DES_ENCRYPT); + asprintf(&p, "%x %x ", (int)htonl(*key), (int)htonl(*(key+1))); + strcat(buf, p); + free(p); + } - if (ent->pw_end == NULL) - strcat(buf, time2str(60*60*24*365*50)); /* passwd will never expire */ - else - strcat(buf, time2str(*ent->pw_end)); - strcat(buf, " "); + if (ent->pw_end == NULL) + strcat(buf, time2str(60*60*24*365*50)); /* passwd will never expire */ + else + strcat(buf, time2str(*ent->pw_end)); + strcat(buf, " "); - if (ent->modified_by == NULL) - modifier = &ent->created_by; - else - modifier = ent->modified_by; + if (ent->modified_by == NULL) + modifier = &ent->created_by; + else + modifier = ent->modified_by; - ret = krb5_524_conv_principal(context, modifier->principal, - name, instance, realm); - if (ret) { - krb5_unparse_name(context, modifier->principal, &princ_name); - krb5_warn(context, ret, "%s", princ_name); - free(princ_name); - return -1; - } - asprintf(&p, "%s %s %s\n", time2str(modifier->time), - (strlen(name) != 0) ? name : "*", - (strlen(instance) != 0) ? instance : "*"); - strcat(buf, p); - free(p); + ret = krb5_524_conv_principal(context, modifier->principal, + name, instance, realm); + if (ret) { + krb5_unparse_name(context, modifier->principal, &princ_name); + krb5_warn(context, ret, "%s", princ_name); + free(princ_name); + return -1; + } + asprintf(&p, "%s %s %s\n", time2str(modifier->time), + (strlen(name) != 0) ? name : "*", + (strlen(instance) != 0) ? instance : "*"); + strcat(buf, p); + free(p); - ret = write(fd, buf, strlen(buf)); - if (ret == -1) - krb5_warnx(context, "write"); - return 0; + ret = write(fd, buf, strlen(buf)); + if (ret == -1) + krb5_warnx(context, "write"); + return 0; } #endif /* KRB4 */ @@ -156,7 +155,6 @@ open_socket(krb5_context context) sin_len = sizeof(sin); if(getpeername(0, (struct sockaddr*)&sin, &sin_len)){ - s = socket(AF_INET, SOCK_STREAM, 0); if(s < 0){ krb5_warn(context, errno, "socket"); @@ -165,7 +163,8 @@ open_socket(krb5_context context) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one)); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; - sin.sin_port = krb5_getportbyname (context, "hprop", "tcp", HPROP_PORT); + sin.sin_port = krb5_getportbyname (context, "hprop", "tcp", + HPROP_PORT); if(bind(s, (struct sockaddr*)&sin, sizeof(sin)) < 0){ krb5_warn(context, errno, "bind"); close(s); @@ -215,7 +214,6 @@ usage(int ret) exit (ret); } - int main(int argc, char **argv) { @@ -241,7 +239,8 @@ main(int argc, char **argv) set_progname(argv[0]); ret = krb5_init_context(&context); - if(ret) exit(1); + if(ret) + exit(1); ret = krb5_openlog(context, "hpropd", &fac); if(ret) @@ -250,6 +249,7 @@ main(int argc, char **argv) if(getarg(args, num_args, argc, argv, &optind)) usage(1); + #ifdef KRB4 if (v4dump && database == HDB_DEFAULT_DB) database = "/var/kerberos/524_dump"; @@ -270,7 +270,7 @@ main(int argc, char **argv) if(from_stdin) fd = STDIN_FILENO; - else{ + else { fd = open_socket(context); if(fd < 0) krb5_errx(context, 1, "Failed to obtain socket - exiting"); @@ -279,28 +279,36 @@ main(int argc, char **argv) int sin_len; struct sockaddr_in sin; sin_len = sizeof(sin); - if(getpeername(fd, (struct sockaddr*)&sin, &sin_len)) + if(getpeername(fd, (struct sockaddr*)&sin, &sin_len) < 0) krb5_err(context, 1, errno, "getpeername"); - krb5_log(context, fac, 0, "Connection from %s", inet_ntoa(sin.sin_addr)); + krb5_log(context, fac, 0, "Connection from %s", + inet_ntoa(sin.sin_addr)); } gethostname(hostname, sizeof(hostname)); - ret = krb5_sname_to_principal(context, hostname, HPROP_NAME, KRB5_NT_SRV_HST, &server); - if(ret) krb5_err(context, 1, ret, "krb5_sname_to_principal"); + ret = krb5_sname_to_principal(context, hostname, HPROP_NAME, + KRB5_NT_SRV_HST, &server); + if(ret) + krb5_err(context, 1, ret, "krb5_sname_to_principal"); ret = krb5_kt_default(context, &keytab); - if(ret) krb5_err(context, 1, ret, "krb5_kt_default"); + if(ret) + krb5_err(context, 1, ret, "krb5_kt_default"); - ret = krb5_recvauth(context, &ac, &fd, HPROP_VERSION, server, 0, keytab, NULL); - if(ret) krb5_err(context, 1, ret, "krb5_recvauth"); + ret = krb5_recvauth(context, &ac, &fd, HPROP_VERSION, + server, 0, keytab, NULL); + if(ret) + krb5_err(context, 1, ret, "krb5_recvauth"); ret = krb5_auth_getauthenticator(context, ac, &authent); - if(ret) krb5_err(context, 1, ret, "krb5_auth_getauthenticator"); + if(ret) + krb5_err(context, 1, ret, "krb5_auth_getauthenticator"); ret = krb5_make_principal(context, &c1, NULL, "kadmin", "hprop", NULL); - if(ret) krb5_err(context, 1, ret, "krb5_make_principal"); + if(ret) + krb5_err(context, 1, ret, "krb5_make_principal"); principalname2krb5_principal(&c2, authent->cname, authent->crealm); - if(!krb5_principal_compare(context, c1, c2)){ + if(!krb5_principal_compare(context, c1, c2)) { char *s; krb5_unparse_name(context, c2, &s); krb5_errx(context, 1, "Unauthorized connection from %s", s); @@ -309,7 +317,8 @@ main(int argc, char **argv) krb5_free_principal(context, c2); ret = krb5_kt_close(context, keytab); - if(ret) krb5_err(context, 1, ret, "krb5_kt_close"); + if(ret) + krb5_err(context, 1, ret, "krb5_kt_close"); } if(!print_dump) { @@ -334,8 +343,10 @@ main(int argc, char **argv) #ifdef KRB4 if (v4dump) { - e = kdb_get_master_key(0, &mkey4, msched4); - if(e) krb5_errx(context, 1, "kdb_get_master_key: %s", krb_get_err_text(e)); + e = kdb_get_master_key(0, &mkey4, msched4); + if(e) + krb5_errx(context, 1, "kdb_get_master_key: %s", + krb_get_err_text(e)); } #endif /* KRB4 */ @@ -346,14 +357,16 @@ main(int argc, char **argv) if(from_stdin){ ret = recv_clear(context, fd, &data); - if(ret) krb5_err(context, 1, ret, "recv_clear"); + if(ret) + krb5_err(context, 1, ret, "recv_clear"); }else{ ret = recv_priv(context, ac, fd, &data); - if(ret) krb5_err(context, 1, ret, "recv_priv"); + if(ret) + krb5_err(context, 1, ret, "recv_priv"); } - if(data.length == 0){ - if(!from_stdin){ + if(data.length == 0) { + if(!from_stdin) { data.data = NULL; data.length = 0; send_priv(context, ac, &data, fd); @@ -371,15 +384,18 @@ main(int argc, char **argv) #endif /* KRB4 */ { ret = db->rename(context, db, database); - if(ret) krb5_err(context, 1, ret, "db_rename"); + if(ret) + krb5_err(context, 1, ret, "db_rename"); ret = db->close(context, db); - if(ret) krb5_err(context, 1, ret, "db_close"); + if(ret) + krb5_err(context, 1, ret, "db_close"); } break; } } ret = hdb_value2entry(context, &data, &entry); - if(ret) krb5_err(context, 1, ret, "hdb_value2entry"); + if(ret) + krb5_err(context, 1, ret, "hdb_value2entry"); if(print_dump) hdb_print_entry(context, db, &entry, stdout); else { @@ -392,7 +408,7 @@ main(int argc, char **argv) #endif /* KRB4 */ { ret = db->store(context, db, 0, &entry); - if(ret == HDB_ERR_EXISTS){ + if(ret == HDB_ERR_EXISTS) { char *s; krb5_unparse_name(context, entry.principal, &s); krb5_warnx(context, "Entry exists: %s", s);