more code
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@4460 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
		
							
								
								
									
										54
									
								
								lib/kadm5/iprop.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								lib/kadm5/iprop.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| /* | ||||
|  * Copyright (c) 1998 Kungliga Tekniska H<>gskolan | ||||
|  * (Royal Institute of Technology, Stockholm, Sweden).  | ||||
|  * All rights reserved.  | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without  | ||||
|  * modification, are permitted provided that the following conditions  | ||||
|  * are met:  | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright  | ||||
|  *    notice, this list of conditions and the following disclaimer.  | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright  | ||||
|  *    notice, this list of conditions and the following disclaimer in the  | ||||
|  *    documentation and/or other materials provided with the distribution.  | ||||
|  * | ||||
|  * 3. All advertising materials mentioning features or use of this software  | ||||
|  *    must display the following acknowledgement:  | ||||
|  *      This product includes software developed by Kungliga Tekniska  | ||||
|  *      H<>gskolan and its contributors.  | ||||
|  * | ||||
|  * 4. Neither the name of the Institute nor the names of its contributors  | ||||
|  *    may be used to endorse or promote products derived from this software  | ||||
|  *    without specific prior written permission.  | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  | ||||
|  * SUCH DAMAGE.  | ||||
|  */ | ||||
|  | ||||
| /* $Id$ */ | ||||
|  | ||||
| #ifndef __IPROP_H__ | ||||
| #define __IPROP_H__ | ||||
|  | ||||
| #include "kadm5_locl.h" | ||||
|  | ||||
| #define IPROP_VERSION "iprop-0.0" | ||||
|  | ||||
| #define KADM5_SLAVE_ACL HDB_DB_DIR "/slaves" | ||||
|  | ||||
| #define IPROP_NAME "iprop" | ||||
|  | ||||
| enum iprop_cmd { I_HAVE = 1, FOR_YOU = 2 }; | ||||
|  | ||||
| #endif /* __IPROP_H__ */ | ||||
| @@ -36,7 +36,7 @@ | ||||
|  * SUCH DAMAGE.  | ||||
|  */ | ||||
|  | ||||
| #include "kadm5_locl.h" | ||||
| #include "iprop.h" | ||||
|  | ||||
| RCSID("$Id$"); | ||||
|  | ||||
| @@ -179,6 +179,134 @@ error: | ||||
|     free(s); | ||||
| } | ||||
|  | ||||
| static void | ||||
| remove_slave (krb5_context context, slave *s, slave **root) | ||||
| { | ||||
|     slave **p; | ||||
|  | ||||
|     close (s->fd); | ||||
|     free (s->name); | ||||
|     krb5_auth_con_free (context, s->ac); | ||||
|  | ||||
|     for (p = root; *p; p = &(*p)->next) | ||||
| 	if (*p == s) { | ||||
| 	    *p = s->next; | ||||
| 	    break; | ||||
| 	} | ||||
|     free (s); | ||||
| } | ||||
|  | ||||
| static int | ||||
| send_diffs (krb5_context context, slave *s, int log_fd) | ||||
| { | ||||
|     krb5_storage *sp, *data_sp; | ||||
|     u_int32_t ver; | ||||
|     time_t timestamp; | ||||
|     enum kadm_ops op; | ||||
|     u_int32_t len; | ||||
|     off_t right, left; | ||||
|     krb5_data data; | ||||
|     krb5_data priv_data; | ||||
|     int ret = 0; | ||||
|     u_char buf[4]; | ||||
|  | ||||
|     sp = kadm5_log_goto_end (log_fd); | ||||
|     right = sp->seek(sp, 0, SEEK_CUR); | ||||
|     for (;;) { | ||||
| 	if (kadm5_log_previous (sp, &ver, ×tamp, &op, &len)) | ||||
| 	    abort (); | ||||
| 	left = sp->seek(sp, -16, SEEK_CUR); | ||||
| 	if (ver == s->version) | ||||
| 	    break; | ||||
|     } | ||||
|     krb5_data_alloc (&data, right - left + 4); | ||||
|     sp->fetch (sp, (char *)data.data + 4, data.length - 4); | ||||
|     krb5_storage_free(sp); | ||||
|  | ||||
|     data_sp = krb5_storage_from_mem (data.data, 4); | ||||
|     krb5_store_int32 (data_sp, FOR_YOU); | ||||
|     krb5_storage_free(sp); | ||||
|  | ||||
|     ret = krb5_mk_priv (context, s->ac, &data, &priv_data, NULL); | ||||
|     krb5_data_free(&data); | ||||
|     if (ret) { | ||||
| 	krb5_warn (context, ret, "krb_mk_priv"); | ||||
| 	return 0; | ||||
|     } | ||||
|     buf[0] = (priv_data.length >> 24) & 0xFF; | ||||
|     buf[1] = (priv_data.length >> 16) & 0xFF; | ||||
|     buf[2] = (priv_data.length >>  8) & 0xFF; | ||||
|     buf[3] = (priv_data.length >>  0) & 0xFF; | ||||
|     ret = krb5_net_write (context, &s->fd, buf, 4); | ||||
|     if (ret < 0) { | ||||
| 	krb5_data_free (&priv_data); | ||||
| 	krb5_warn (context, ret, "krb_net_write"); | ||||
| 	return 1; | ||||
|     } | ||||
|     ret = krb5_net_write (context, &s->fd, priv_data.data, priv_data.length); | ||||
|     krb5_data_free (&priv_data); | ||||
|     if (ret < 0) { | ||||
| 	krb5_warn (context, ret, "krb_net_write"); | ||||
| 	return 1; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| process_msg (krb5_context context, slave *s, int log_fd) | ||||
| { | ||||
|     int ret = 0; | ||||
|     u_int32_t len; | ||||
|     krb5_data in, out; | ||||
|     krb5_storage *sp; | ||||
|     int32_t tmp; | ||||
|     u_char buf[8]; | ||||
|  | ||||
|     ret = krb5_net_read (context, &s->fd, buf, 4); | ||||
|     if (ret == 0) { | ||||
| 	return 1; | ||||
|     } | ||||
|     if (ret < 0) { | ||||
| 	krb5_warn(context, errno, "krb5_net_read"); | ||||
| 	return 1; | ||||
|     } | ||||
|     len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; | ||||
|     ret = krb5_data_alloc (&in, len); | ||||
|     if (ret) { | ||||
| 	krb5_warn (context, ret, "krb5_data_alloc"); | ||||
| 	return 1; | ||||
|     } | ||||
|     ret = krb5_net_read(context, &s->fd, in.data, in.length); | ||||
|     if (ret < 0) { | ||||
| 	krb5_warn(context, errno, "krb5_net_read"); | ||||
| 	krb5_data_free (&in); | ||||
| 	return 1; | ||||
|     } | ||||
|     ret = krb5_rd_priv (context, s->ac, &in, &out, NULL); | ||||
|     krb5_data_free (&in); | ||||
|     if (ret) { | ||||
| 	krb5_warn (context, ret, "krb5_rd_priv"); | ||||
| 	return 1; | ||||
|     } | ||||
|  | ||||
|     sp = krb5_storage_from_mem (out.data, out.length); | ||||
|     krb5_ret_int32 (sp, &tmp); | ||||
|     switch (tmp) { | ||||
|     case I_HAVE : | ||||
| 	krb5_ret_int32 (sp, &tmp); | ||||
| 	s->version = tmp; | ||||
| 	ret = send_diffs (context, s, log_fd); | ||||
| 	break; | ||||
|     case FOR_YOU : | ||||
|     default : | ||||
| 	krb5_warnx (context, "Ignoring command %d", tmp); | ||||
| 	break; | ||||
|     } | ||||
|  | ||||
|     krb5_data_free (&out); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| int | ||||
| main(int argc, char **argv) | ||||
| { | ||||
| @@ -190,7 +318,7 @@ main(int argc, char **argv) | ||||
|     int signal_fd, listen_fd; | ||||
|     int log_fd; | ||||
|     slave *slaves = NULL; | ||||
|     u_int32_t version, old_version = 0; | ||||
|     u_int32_t current_version, old_version = 0; | ||||
|  | ||||
|     set_progname(argv[0]); | ||||
|  | ||||
| @@ -242,9 +370,11 @@ main(int argc, char **argv) | ||||
| 	    else | ||||
| 		krb5_err (context, 1, errno, "select"); | ||||
| 	} | ||||
| 	kadm5_log_get_version (log_fd, &version); | ||||
| 	if (version > old_version) | ||||
| 	    ; /* XXX - send out updates */ | ||||
| 	kadm5_log_get_version (log_fd, ¤t_version); | ||||
| 	if (current_version > old_version) { | ||||
| 	    for (p = slaves; p != NULL; p = p->next) | ||||
| 		send_diffs (context, p, log_fd); | ||||
| 	} | ||||
| 	if (ret && FD_ISSET(signal_fd, &readset)) { | ||||
| 	    struct sockaddr_un peer_addr; | ||||
| 	    size_t peer_len = sizeof(peer_addr); | ||||
| @@ -264,7 +394,8 @@ main(int argc, char **argv) | ||||
|  | ||||
| 	for(p = slaves; ret-- && p != NULL; p = p->next) | ||||
| 	    if (FD_ISSET(p->fd, &readset)) { | ||||
| 		/* XXX */ | ||||
| 		if(process_msg (context, p, log_fd)) | ||||
| 		    remove_slave (context, p, &slaves); | ||||
| 	    } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -36,7 +36,7 @@ | ||||
|  * SUCH DAMAGE.  | ||||
|  */ | ||||
|  | ||||
| #include "kadm5_locl.h" | ||||
| #include "iprop.h" | ||||
|  | ||||
| RCSID("$Id$"); | ||||
|  | ||||
| @@ -97,6 +97,69 @@ get_creds(krb5_context context, krb5_ccache *cache) | ||||
|     if(ret) krb5_err(context, 1, ret, "krb5_cc_store_cred"); | ||||
| } | ||||
|  | ||||
| static void | ||||
| ihave (krb5_context context, krb5_auth_context auth_context, | ||||
|        int fd, u_int32_t version) | ||||
| { | ||||
|     int ret; | ||||
|     u_char buf[8]; | ||||
|     krb5_storage *sp; | ||||
|     krb5_data data, priv_data; | ||||
|  | ||||
|     sp = krb5_storage_from_mem (buf, 8); | ||||
|     krb5_store_int32 (sp, I_HAVE); | ||||
|     krb5_store_int32 (sp, version); | ||||
|     krb5_storage_free (sp); | ||||
|     data.length = 8; | ||||
|     data.data   = buf; | ||||
|      | ||||
|     ret = krb5_mk_priv (context, auth_context, &data, &priv_data, NULL); | ||||
|     if (ret) | ||||
| 	krb5_err (context, 1, ret, "krb_mk_priv"); | ||||
|     buf[0] = (priv_data.length >> 24) & 0xFF; | ||||
|     buf[1] = (priv_data.length >> 16) & 0xFF; | ||||
|     buf[2] = (priv_data.length >>  8) & 0xFF; | ||||
|     buf[3] = (priv_data.length >>  0) & 0xFF; | ||||
|     ret = krb5_net_write (context, &fd, buf, 4); | ||||
|     if (ret < 0) | ||||
| 	krb5_err (context, 1, ret, "krb_net_write"); | ||||
|     ret = krb5_net_write (context, &fd, priv_data.data, priv_data.length); | ||||
|     krb5_data_free (&priv_data); | ||||
|     if (ret < 0) | ||||
| 	krb5_err (context, 1, ret, "krb_net_write"); | ||||
| } | ||||
|  | ||||
| static void | ||||
| receive (krb5_context context, | ||||
| 	 krb5_storage *sp, | ||||
| 	 kadm5_server_context *server_context) | ||||
| { | ||||
|     int ret; | ||||
|  | ||||
|     for (;;) { | ||||
| 	int32_t vers, len, timestamp, tmp; | ||||
| 	enum kadm_ops op; | ||||
|  | ||||
| 	if(krb5_ret_int32 (sp, &vers) != 0) | ||||
| 	    return; | ||||
| 	krb5_ret_int32 (sp, ×tamp); | ||||
| 	krb5_ret_int32 (sp, &tmp); | ||||
| 	op = tmp; | ||||
| 	krb5_ret_int32 (sp, &len); | ||||
| 	if (tmp < server_context->log_context.version) { | ||||
| 	    sp->seek(sp, len, SEEK_CUR); | ||||
| 	} else { | ||||
| 	    ret = kadm5_log_replay (server_context, | ||||
| 				    op, vers, len, sp); | ||||
| 	    if (ret) | ||||
| 		krb5_warn (context, ret, "kadm5_log_replay"); | ||||
| 	    else | ||||
| 		server_context->log_context.version = vers; | ||||
| 	} | ||||
| 	sp->seek (sp, 8, SEEK_CUR); | ||||
|     } | ||||
| } | ||||
|  | ||||
| int | ||||
| main(int argc, char **argv) | ||||
| { | ||||
| @@ -126,6 +189,12 @@ main(int argc, char **argv) | ||||
|  | ||||
|     server_context = (kadm5_server_context *)kadm_handle; | ||||
|  | ||||
|     ret = kadm5_log_init (server_context); | ||||
|     if (ret) | ||||
| 	krb5_err (context, 1, ret, "kadm5_log_init"); | ||||
|  | ||||
|     get_creds(context, &ccache); | ||||
|  | ||||
|     master_fd = connect_to_master (context, argv[1]); | ||||
|  | ||||
|     ret = krb5_sname_to_principal (context, argv[1], IPROP_NAME, | ||||
| @@ -133,8 +202,6 @@ main(int argc, char **argv) | ||||
|     if (ret) | ||||
| 	krb5_err (context, 1, ret, "krb5_sname_to_principal"); | ||||
|  | ||||
|     get_creds(context, &ccache); | ||||
|  | ||||
|     auth_context = NULL; | ||||
|     ret = krb5_sendauth (context, &auth_context, &master_fd, | ||||
| 			 IPROP_VERSION, NULL, server, | ||||
| @@ -143,5 +210,41 @@ main(int argc, char **argv) | ||||
|     if (ret) | ||||
| 	krb5_err (context, 1, ret, "krb5_sendauth"); | ||||
|  | ||||
|     ihave (context, auth_context, master_fd, | ||||
| 	   server_context->log_context.version); | ||||
|  | ||||
|     for (;;) { | ||||
| 	u_char buf[4]; | ||||
| 	int ret; | ||||
| 	krb5_data data, out; | ||||
| 	u_int32_t len; | ||||
| 	krb5_storage *sp; | ||||
| 	int32_t tmp; | ||||
|  | ||||
| 	ret = krb5_net_read (context, &master_fd, buf, 4); | ||||
| 	if (ret != 4) | ||||
| 	    krb5_err (context, 1, ret, "krb5_net_read"); | ||||
| 	len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; | ||||
| 	ret = krb5_data_alloc (&data, len); | ||||
| 	if (ret) | ||||
| 	    krb5_err (context, 1, ret, "krb5_data_alloc"); | ||||
| 	ret = krb5_net_read (context, &master_fd, data.data, data.length); | ||||
| 	if (ret) | ||||
| 	    krb5_err (context, 1, ret, "krb5_net_read"); | ||||
| 	ret = krb5_rd_priv (context, auth_context,  &data, &out, NULL); | ||||
| 	if (ret) | ||||
| 	    krb5_err (context, 1, ret, "krb5_rd_priv"); | ||||
| 	sp = krb5_storage_from_mem (out.data, out.length); | ||||
| 	krb5_ret_int32 (sp, &tmp); | ||||
| 	switch (tmp) { | ||||
| 	case FOR_YOU : | ||||
| 	    receive (context, sp, server_context); | ||||
| 	case I_HAVE : | ||||
| 	default : | ||||
| 	    krb5_warnx (context, "Ignoring command %d", tmp); | ||||
| 	    break; | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -49,6 +49,7 @@ | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
| #include <assert.h> | ||||
| #ifdef HAVE_UNISTD_H | ||||
| #include <unistd.h> | ||||
| #endif | ||||
| @@ -287,12 +288,16 @@ kadm5_log_replay (kadm5_server_context *context, | ||||
| 		  u_int32_t len, | ||||
| 		  krb5_storage *sp); | ||||
|  | ||||
| krb5_storage * | ||||
| kadm5_log_goto_end (int fd); | ||||
|  | ||||
| kadm5_ret_t | ||||
| kadm5_log_previous (krb5_storage *sp, | ||||
| 		    u_int32_t *ver, | ||||
| 		    time_t *timestamp, | ||||
| 		    enum kadm_ops *op, | ||||
| 		    u_int32_t *len); | ||||
|  | ||||
| #define KADM5_LOG_SIGNAL HDB_DB_DIR "/signal" | ||||
|  | ||||
| #define IPROP_VERSION "iprop-0.0" | ||||
|  | ||||
| #define KADM5_SLAVE_ACL HDB_DB_DIR "/slaves" | ||||
|  | ||||
| #define IPROP_NAME "iprop" | ||||
|  | ||||
| #endif /* __KADM5_LOCL_H__ */ | ||||
|   | ||||
| @@ -596,6 +596,50 @@ kadm5_log_foreach (kadm5_server_context *context, | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Go to end of log. | ||||
|  */ | ||||
|  | ||||
| krb5_storage * | ||||
| kadm5_log_goto_end (int fd) | ||||
| { | ||||
|     krb5_storage *sp; | ||||
|  | ||||
|     sp = krb5_storage_from_fd (fd); | ||||
|     sp->seek(sp, 0, SEEK_END); | ||||
|     return sp; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Return previous log entry. | ||||
|  */ | ||||
|  | ||||
| kadm5_ret_t | ||||
| kadm5_log_previous (krb5_storage *sp, | ||||
| 		    u_int32_t *ver, | ||||
| 		    time_t *timestamp, | ||||
| 		    enum kadm_ops *op, | ||||
| 		    u_int32_t *len) | ||||
| { | ||||
|     int32_t tmp; | ||||
|  | ||||
|     sp->seek(sp, -8, SEEK_CUR); | ||||
|     krb5_ret_int32 (sp, &tmp); | ||||
|     *len = tmp; | ||||
|     krb5_ret_int32 (sp, &tmp); | ||||
|     *ver = tmp; | ||||
|     sp->seek(sp, -(48 + *len), SEEK_CUR); | ||||
|     krb5_ret_int32 (sp, &tmp); | ||||
|     assert(tmp == *ver); | ||||
|     krb5_ret_int32 (sp, &tmp); | ||||
|     *timestamp = tmp; | ||||
|     krb5_ret_int32 (sp, &tmp); | ||||
|     *op = tmp; | ||||
|     krb5_ret_int32 (sp, &tmp); | ||||
|     assert(tmp == *len); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Replay a record from the log | ||||
|  */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Assar Westerlund
					Assar Westerlund