summaryrefslogtreecommitdiffstats
path: root/src/kadmin/server
diff options
context:
space:
mode:
authorTom Yu <tlyu@mit.edu>1998-01-21 05:17:25 +0000
committerTom Yu <tlyu@mit.edu>1998-01-21 05:17:25 +0000
commit33f4567d3b9e5a8184fe70933b9a5e869550ad16 (patch)
tree0671b1084f6c5a3353bbdb08fa901321a3d859d3 /src/kadmin/server
parent76fb9e7913370dd73d34a607f370f5ae4775a5a3 (diff)
downloadkrb5-33f4567d3b9e5a8184fe70933b9a5e869550ad16.tar.gz
krb5-33f4567d3b9e5a8184fe70933b9a5e869550ad16.tar.xz
krb5-33f4567d3b9e5a8184fe70933b9a5e869550ad16.zip
* schpw.c: New file. Support for Cygnus chpw
* ovsec_kadmd.c: Add support for Cygnus chpw. * Makefile.in (OBJS): Add schpw.o. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@10358 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/kadmin/server')
-rw-r--r--src/kadmin/server/ChangeLog8
-rw-r--r--src/kadmin/server/Makefile.in2
-rw-r--r--src/kadmin/server/ovsec_kadmd.c166
3 files changed, 173 insertions, 3 deletions
diff --git a/src/kadmin/server/ChangeLog b/src/kadmin/server/ChangeLog
index 6f0b239c7..79837230d 100644
--- a/src/kadmin/server/ChangeLog
+++ b/src/kadmin/server/ChangeLog
@@ -1,3 +1,11 @@
+Wed Jan 21 00:00:34 1998 Tom Yu <tlyu@mit.edu>
+
+ * schpw.c: New file. Support for Cygnus chpw.
+
+ * ovsec_kadmd.c: Add support for Cygnus chpw.
+
+ * Makefile.in (OBJS): Add schpw.o.
+
Tue Oct 14 21:06:16 1997 Ezra Peisach <epeisach@mit.edu>
* server_stubs.c (CHANGEPW_SERVICE): Modify to free allocated
diff --git a/src/kadmin/server/Makefile.in b/src/kadmin/server/Makefile.in
index 5ce41d0fe..9d552aabe 100644
--- a/src/kadmin/server/Makefile.in
+++ b/src/kadmin/server/Makefile.in
@@ -4,7 +4,7 @@ PROG_LIBPATH=-L$(TOPLIBD)
PROG_RPATH=$(KRB5_LIBDIR)
PROG = kadmind
-OBJS = kadm_rpc_svc.o server_stubs.o ovsec_kadmd.o misc.o server_glue_v1.o
+OBJS = kadm_rpc_svc.o server_stubs.o ovsec_kadmd.o schpw.o misc.o server_glue_v1.o
all:: $(PROG)
diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c
index 16fb7d259..6ce60976c 100644
--- a/src/kadmin/server/ovsec_kadmd.c
+++ b/src/kadmin/server/ovsec_kadmd.c
@@ -77,6 +77,13 @@ void log_badauth_display_status(char *msg, OM_uint32 major, OM_uint32 minor);
void log_badauth_display_status_1(char *m, OM_uint32 code, int type,
int rec);
+int schpw;
+void do_schpw(int s, kadm5_config_params *params);
+kadm5_config_params params;
+krb5_error_code process_chpw_request(krb5_context context, void *server_handle,
+ char *realm, int s, krb5_keytab keytab,
+ struct sockaddr_in *sin,
+ krb5_data *req, krb5_data *rep);
/*
* Function: usage
@@ -115,7 +122,6 @@ int main(int argc, char *argv[])
int s;
short port = 0;
auth_gssapi_name names[4];
- kadm5_config_params params;
names[0].name = names[1].name = names[2].name = names[3].name = NULL;
names[0].type = names[1].type = names[2].type = names[3].type =
@@ -222,6 +228,17 @@ int main(int argc, char *argv[])
exit(1);
}
+ if ((schpw = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ krb5_klog_syslog(LOG_ERR,
+ "cannot create simple chpw socket: %s",
+ error_message(errno));
+ fprintf(stderr, "Cannot create simple chpw socket: %s",
+ error_message(errno));
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close();
+ exit(1);
+ }
+
#ifdef SO_REUSEADDR
/* the old admin server turned on SO_REUSEADDR for non-default
port numbers. this was necessary, on solaris, for the tests
@@ -248,8 +265,25 @@ int main(int argc, char *argv[])
krb5_klog_close();
exit(1);
}
+ if (setsockopt(schpw, SOL_SOCKET, SO_REUSEADDR,
+ (char *) &allowed, sizeof(allowed)) < 0) {
+ krb5_klog_syslog(LOG_ERR, "main",
+ "cannot set SO_REUSEADDR on simple chpw socket: %s",
+ error_message(errno));
+ fprintf(stderr,
+ "Cannot set SO_REUSEADDR on simple chpw socket: %s",
+ error_message(errno));
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close();
+ }
+
}
#endif /* SO_REUSEADDR */
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
+ addr.sin_port = htons(params.kadmind_port);
+
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
int oerrno = errno;
fprintf(stderr, "%s: Cannot bind socket.\n", whoami);
@@ -283,6 +317,40 @@ int main(int argc, char *argv[])
krb5_klog_close();
exit(1);
}
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
+ /* XXX */
+ addr.sin_port = htons(params.kpasswd_port);
+
+ if (bind(schpw, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ char portbuf[32];
+ int oerrno = errno;
+ fprintf(stderr, "%s: Cannot bind socket.\n", whoami);
+ fprintf(stderr, "bind: %s\n", error_message(oerrno));
+ errno = oerrno;
+ sprintf(portbuf, "%d", ntohs(addr.sin_port));
+ krb5_klog_syslog(LOG_ERR, "cannot bind simple chpw socket: %s",
+ error_message(oerrno));
+ if(oerrno == EADDRINUSE) {
+ char *w = strrchr(whoami, '/');
+ if (w) {
+ w++;
+ }
+ else {
+ w = whoami;
+ }
+ fprintf(stderr,
+"This probably means that another %s process is already\n"
+"running, or that another program is using the server port (number %d).\n"
+"If another %s is already running, you should kill it before\n"
+"restarting the server.\n",
+ w, ntohs(addr.sin_port), w);
+ }
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close();
+ exit(1);
+ }
transp = svctcp_create(s, 0, 0);
if(transp == NULL) {
@@ -447,6 +515,7 @@ void kadm_svc_run(void)
timeout.tv_sec = TIMEOUT;
timeout.tv_usec = 0;
rfd = svc_fdset;
+ FD_SET(schpw, &rfd);
switch(select(sz, (fd_set *) &rfd, NULL, NULL, &timeout)) {
case -1:
if(errno == EINTR)
@@ -457,7 +526,10 @@ void kadm_svc_run(void)
reset_db();
break;
default:
- svc_getreqset(&rfd);
+ if (FD_ISSET(schpw, &rfd))
+ do_schpw(schpw, &params);
+ else
+ svc_getreqset(&rfd);
}
}
}
@@ -781,3 +853,93 @@ void log_badauth_display_status_1(char *m, OM_uint32 code, int type,
break;
}
}
+
+void do_schpw(int s1, kadm5_config_params *params)
+{
+ krb5_error_code ret;
+ /* XXX buffer = ethernet mtu */
+ char req[1500];
+ int len;
+ struct sockaddr_in from;
+ int fromlen;
+ krb5_keytab kt;
+ krb5_data reqdata, repdata;
+ int s2;
+
+ fromlen = sizeof(from);
+ if ((len = recvfrom(s1, req, sizeof(req), 0, (struct sockaddr *)&from,
+ &fromlen)) < 0) {
+ krb5_klog_syslog(LOG_ERR, "chpw: Couldn't receive request: %s",
+ error_message(errno));
+ return;
+ }
+
+ if (ret = krb5_kt_resolve(context, params->admin_keytab, &kt)) {
+ krb5_klog_syslog(LOG_ERR, "chpw: Couldn't open admin keytab %s",
+ error_message(ret));
+ return;
+ }
+
+ reqdata.length = len;
+ reqdata.data = req;
+
+ /* this is really obscure. s1 is used for all communications. it
+ is left unconnected in case the server is multihomed and routes
+ are asymmetric. s2 is connected to resolve routes and get
+ addresses. this is the *only* way to get proper addresses for
+ multihomed hosts if routing is asymmetric.
+
+ A related problem in the server, but not the client, is that
+ many os's have no way to disconnect a connected udp socket, so
+ the s2 socket needs to be closed and recreated for each
+ request. The s1 socket must not be closed, or else queued
+ requests will be lost.
+
+ A "naive" client implementation (one socket, no connect,
+ hostname resolution to get the local ip addr) will work and
+ interoperate if the client is single-homed. */
+
+ if ((s2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ krb5_klog_syslog(LOG_ERR, "cannot create connecting socket: %s",
+ error_message(errno));
+ fprintf(stderr, "Cannot create connecting socket: %s",
+ error_message(errno));
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close();
+ exit(1);
+ }
+
+ if (connect(s2, (struct sockaddr *) &from, sizeof(from)) < 0) {
+ krb5_klog_syslog(LOG_ERR, "chpw: Couldn't connect to client: %s",
+ error_message(errno));
+ return;
+ }
+
+ if (ret = process_chpw_request(context, global_server_handle,
+ params->realm, s2, kt, &from,
+ &reqdata, &repdata)) {
+ krb5_klog_syslog(LOG_ERR, "chpw: Error processing request: %s",
+ error_message(ret));
+ }
+
+ close(s2);
+
+ if (repdata.length == 0)
+ /* just qreturn. This means something really bad happened */
+ return;
+
+ len = sendto(s1, repdata.data, repdata.length, 0,
+ (struct sockaddr *) &from, sizeof(from));
+
+ if (len < repdata.length) {
+ krb5_xfree(repdata.data);
+
+ krb5_klog_syslog(LOG_ERR, "chpw: Error sending reply: %s",
+ error_message(errno));
+ return;
+ }
+
+ krb5_xfree(repdata.data);
+
+ return;
+}