summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rpc.yppasswdd/yppasswdd_server.c
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1996-08-04 22:13:05 +0000
committerwpaul <wpaul@FreeBSD.org>1996-08-04 22:13:05 +0000
commitd200f0db63258740cb7899578439321da29d5095 (patch)
treecffc485df7898507e841e7a40789edfd757f9404 /usr.sbin/rpc.yppasswdd/yppasswdd_server.c
parentc6caa4699e4cfaf0e3d4b35411102b5354e19566 (diff)
downloadFreeBSD-src-d200f0db63258740cb7899578439321da29d5095.zip
FreeBSD-src-d200f0db63258740cb7899578439321da29d5095.tar.gz
Fix a couple of bogons. The first two were brought to my attention
by Peter Wemm: - In yppasswdproc_update_1_svc(), I wasn't paying attention and put a couple of lines of code _after_ a return() instead of before. (*blush*) - The removal of certain temp files didn't always work (this showed up mostly if you were using /etc/master.passwd as your NIS passwd template instead of /var/yp/master.passwd). This is because the whole temp file creation mechanism I was using was tragically broken (you can't rename across filesystems). This problem I found myself: - If you have a very large password database (30,000 or more entries), there can be a delay of several seconds while pw_copy() copies the ASCII template file and subsitutes in the modified/new entry. During this time, the clnt_udp() code in the RPC library may get impatient and retry its request. This will get queued at the server and be treated as a second request. By then the password change will have been completed and the second request will fail (the old password is no longer valid). To attempt to fix this, we save the IP address and port of each request and ignore any subsequent requests from the same IP and same port that arrive within five minutes of each other.
Diffstat (limited to 'usr.sbin/rpc.yppasswdd/yppasswdd_server.c')
-rw-r--r--usr.sbin/rpc.yppasswdd/yppasswdd_server.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/usr.sbin/rpc.yppasswdd/yppasswdd_server.c b/usr.sbin/rpc.yppasswdd/yppasswdd_server.c
index 814025b..55a61dc 100644
--- a/usr.sbin/rpc.yppasswdd/yppasswdd_server.c
+++ b/usr.sbin/rpc.yppasswdd/yppasswdd_server.c
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: yppasswdd_server.c,v 1.5 1996/06/23 22:44:06 wpaul Exp $
+ * $Id: yppasswdd_server.c,v 1.6 1996/07/01 19:38:38 guido Exp $
*/
#include <stdio.h>
@@ -61,7 +61,7 @@ struct dom_binding {};
#include "yppasswd_comm.h"
#ifndef lint
-static const char rcsid[] = "$Id: yppasswdd_server.c,v 1.5 1996/06/23 22:44:06 wpaul Exp $";
+static const char rcsid[] = "$Id: yppasswdd_server.c,v 1.6 1996/07/01 19:38:38 guido Exp $";
#endif /* not lint */
char *tempname;
@@ -420,6 +420,19 @@ static int update_inplace(pw, domain)
return(0);
}
+static char *yp_mktmpnam()
+{
+ static char path[MAXPATHLEN];
+ char *p;
+
+ sprintf(path,"%s",passfile);
+ if ((p = strrchr(path, '/')))
+ ++p;
+ else
+ p = path;
+ strcpy(p, "yppwtmp.XXXXXX");
+ return(mktemp(path));
+}
int *
yppasswdproc_update_1_svc(yppasswd *argp, struct svc_req *rqstp)
@@ -437,8 +450,9 @@ yppasswdproc_update_1_svc(yppasswd *argp, struct svc_req *rqstp)
char *oldgecos = NULL;
char *passfile_hold;
char passfile_buf[MAXPATHLEN + 2];
- char template[] = "/etc/yppwtmp.XXXXX";
char *domain = yppasswd_domain;
+ static struct sockaddr_in clntaddr;
+ static struct timeval t_saved, t_test;
/*
* Normal user updates always use the 'default' master.passwd file.
@@ -449,6 +463,20 @@ yppasswdproc_update_1_svc(yppasswd *argp, struct svc_req *rqstp)
rqhost = svc_getcaller(rqstp->rq_xprt);
+ gettimeofday(&t_test, NULL);
+ if (!bcmp((char *)rqhost, (char *)&clntaddr,
+ sizeof(struct sockaddr_in)) &&
+ t_test.tv_sec > t_saved.tv_sec &&
+ t_test.tv_sec - t_saved.tv_sec < 300) {
+
+ bzero((char *)&clntaddr, sizeof(struct sockaddr_in));
+ bzero((char *)&t_saved, sizeof(struct timeval));
+ return(NULL);
+ }
+
+ bcopy((char *)rqhost, (char *)&clntaddr, sizeof(struct sockaddr_in));
+ gettimeofday(&t_saved, NULL);
+
if (yp_access(resvport ? "master.passwd.byname" : NULL, rqstp)) {
yp_error("rejected update request from unauthorized host");
svcerr_auth(rqstp->rq_xprt, AUTH_BADCRED);
@@ -562,7 +590,7 @@ cleaning up and bailing out");
return(&result);
}
- passfile_hold = mktemp((char *)&template);
+ passfile_hold = yp_mktmpnam();
rename(passfile, passfile_hold);
if (strcmp(passfile, _PATH_MASTERPASSWD)) {
rename(tempname, passfile);
@@ -581,7 +609,6 @@ cleaning up and bailing out");
switch((pid = fork())) {
case 0:
- /* unlink(passfile_hold); */
if (inplace && !rval) {
execlp(MAP_UPDATE_PATH, MAP_UPDATE, passfile,
yppasswd_domain, "pushpw", NULL);
@@ -597,11 +624,12 @@ cleaning up and bailing out");
break;
case -1:
yp_error("fork() failed: %s", strerror(errno));
- return(&result);
unlink(passfile);
rename(passfile_hold, passfile);
+ return(&result);
break;
default:
+ unlink(passfile_hold);
break;
}
@@ -624,7 +652,6 @@ cleaning up and bailing out");
result = 0;
return (&result);
-
}
/*
@@ -641,7 +668,6 @@ static int update_master(master_yppasswd *argp)
DBT key, data;
char *passfile_hold;
char passfile_buf[MAXPATHLEN + 2];
- char template[] = "/etc/yppwtmp.XXXXX";
result = 1;
passfile = passfile_default;
@@ -713,7 +739,7 @@ cleaning up and bailing out");
return(result);
}
- passfile_hold = mktemp((char *)&template);
+ passfile_hold = yp_mktmpnam();
rename(passfile, passfile_hold);
if (strcmp(passfile, _PATH_MASTERPASSWD)) {
rename(tempname, passfile);
@@ -754,6 +780,7 @@ cleaning up and bailing out");
return(result);
break;
default:
+ unlink(passfile_hold);
break;
}
OpenPOWER on IntegriCloud