Deleted Added
full compact
yppasswdd_server.c (22997) yppasswdd_server.c (27758)
1/*
2 * Copyright (c) 1995, 1996
3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 15 unchanged lines hidden (view full) ---

24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
1/*
2 * Copyright (c) 1995, 1996
3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 15 unchanged lines hidden (view full) ---

24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $Id$
32 * $Id: yppasswdd_server.c,v 1.3 1997/07/29 00:21:00 wpaul Exp $
33 */
34
35#include <stdio.h>
36#include <string.h>
37#include <ctype.h>
38#include <stdlib.h>
39#include <unistd.h>
40#include <dirent.h>

--- 12 unchanged lines hidden (view full) ---

53#include <sys/wait.h>
54#include <sys/param.h>
55#include <sys/fcntl.h>
56struct dom_binding {};
57#include <rpcsvc/ypclnt.h>
58#include "yppasswdd_extern.h"
59#include "yppasswd.h"
60#include "yppasswd_private.h"
33 */
34
35#include <stdio.h>
36#include <string.h>
37#include <ctype.h>
38#include <stdlib.h>
39#include <unistd.h>
40#include <dirent.h>

--- 12 unchanged lines hidden (view full) ---

53#include <sys/wait.h>
54#include <sys/param.h>
55#include <sys/fcntl.h>
56struct dom_binding {};
57#include <rpcsvc/ypclnt.h>
58#include "yppasswdd_extern.h"
59#include "yppasswd.h"
60#include "yppasswd_private.h"
61#include "yppasswd_comm.h"
62
63#ifndef lint
61
62#ifndef lint
64static const char rcsid[] = "$Id$";
63static const char rcsid[] = "$Id: yppasswdd_server.c,v 1.3 1997/07/29 00:21:00 wpaul Exp $";
65#endif /* not lint */
66
67char *tempname;
68
69void reaper(sig)
70 int sig;
71{
72 extern pid_t pid;

--- 608 unchanged lines hidden (view full) ---

681 yp_error("shell changed ('%s' -> '%s')",
682 oldshell, argp->newpw.pw_shell);
683 }
684
685 result = 0;
686 return (&result);
687}
688
64#endif /* not lint */
65
66char *tempname;
67
68void reaper(sig)
69 int sig;
70{
71 extern pid_t pid;

--- 608 unchanged lines hidden (view full) ---

680 yp_error("shell changed ('%s' -> '%s')",
681 oldshell, argp->newpw.pw_shell);
682 }
683
684 result = 0;
685 return (&result);
686}
687
688struct cmessage {
689 struct cmsghdr cmsg;
690 struct cmsgcred cmcred;
691};
692
689/*
690 * Note that this function performs a little less sanity checking
691 * than the last one. Since only the superuser is allowed to use it,
692 * it is assumed that the caller knows what he's doing.
693 */
693/*
694 * Note that this function performs a little less sanity checking
695 * than the last one. Since only the superuser is allowed to use it,
696 * it is assumed that the caller knows what he's doing.
697 */
694static int update_master(master_yppasswd *argp)
698int *yppasswdproc_update_master_1_svc(master_yppasswd *argp,
699 struct svc_req *rqstp)
695{
700{
696 int result;
701 static int result;
697 int pfd, tfd;
698 int pid;
699 int rval = 0;
700 DBT key, data;
701 char *passfile_hold;
702 char passfile_buf[MAXPATHLEN + 2];
702 int pfd, tfd;
703 int pid;
704 int rval = 0;
705 DBT key, data;
706 char *passfile_hold;
707 char passfile_buf[MAXPATHLEN + 2];
708 struct sockaddr_in *rqhost;
709 struct cmessage *cm;
710 SVCXPRT *transp;
703
704 result = 1;
711
712 result = 1;
713
714 /*
715 * NO AF_INET CONNETCIONS ALLOWED!
716 */
717 rqhost = svc_getcaller(rqstp->rq_xprt);
718 if (rqhost->sin_family != AF_UNIX) {
719 yp_error("Alert! %s/%d attempted to use superuser-only \
720procedure!\n", inet_ntoa(rqhost->sin_addr), rqhost->sin_port);
721 svcerr_auth(rqstp->rq_xprt, AUTH_BADCRED);
722 return(&result);
723 }
724
725 transp = rqstp->rq_xprt;
726
727 if (transp->xp_verf.oa_length < sizeof(struct cmessage) ||
728 transp->xp_verf.oa_base == NULL ||
729 transp->xp_verf.oa_flavor != AUTH_UNIX) {
730 yp_error("caller didn't send proper credentials");
731 svcerr_auth(rqstp->rq_xprt, AUTH_BADCRED);
732 return(&result);
733 }
734
735 cm = (struct cmessage *)transp->xp_verf.oa_base;
736 if (cm->cmsg.cmsg_type != SCM_CREDS) {
737 yp_error("caller didn't send proper credentials");
738 svcerr_auth(rqstp->rq_xprt, AUTH_BADCRED);
739 return(&result);
740 }
741
742 if (cm->cmcred.cmcred_euid) {
743 yp_error("caller euid is %d, expecting 0 -- rejecting request",
744 cm->cmcred.cmcred_euid);
745 svcerr_auth(rqstp->rq_xprt, AUTH_BADCRED);
746 return(&result);
747 }
748
705 passfile = passfile_default;
706
707 key.data = argp->newpw.pw_name;
708 key.size = strlen(argp->newpw.pw_name);
709
710 /*
711 * The superuser may add entries to the passwd maps if
712 * rpc.yppasswdd is started with the -a flag. Paranoia

--- 10 unchanged lines hidden (view full) ---

723 else
724 yp_error("restart %s with the -a flag to \
725allow additions to be made to the password database", progname);
726 } else {
727 yp_error("database access error: %s",
728 yperr_string(rval));
729 }
730 if (!allow_additions)
749 passfile = passfile_default;
750
751 key.data = argp->newpw.pw_name;
752 key.size = strlen(argp->newpw.pw_name);
753
754 /*
755 * The superuser may add entries to the passwd maps if
756 * rpc.yppasswdd is started with the -a flag. Paranoia

--- 10 unchanged lines hidden (view full) ---

767 else
768 yp_error("restart %s with the -a flag to \
769allow additions to be made to the password database", progname);
770 } else {
771 yp_error("database access error: %s",
772 yperr_string(rval));
773 }
774 if (!allow_additions)
731 return(result);
775 return(&result);
732 } else {
733
734 /* Nul terminate, please. */
735 *(char *)(data.data + data.size) = '\0';
736
737 copy_yp_pass(data.data, 1, data.size);
738 }
739
740 /*
741 * Perform a small bit of sanity checking.
742 */
743 if (validate_master(rval == YP_TRUE ? &yp_password:NULL,&argp->newpw)){
744 yp_error("rejecting update attempt for %s: bad arguments",
745 argp->newpw.pw_name);
776 } else {
777
778 /* Nul terminate, please. */
779 *(char *)(data.data + data.size) = '\0';
780
781 copy_yp_pass(data.data, 1, data.size);
782 }
783
784 /*
785 * Perform a small bit of sanity checking.
786 */
787 if (validate_master(rval == YP_TRUE ? &yp_password:NULL,&argp->newpw)){
788 yp_error("rejecting update attempt for %s: bad arguments",
789 argp->newpw.pw_name);
746 return(result);
790 return(&result);
747 }
748
749 /*
750 * If the caller specified a domain other than our 'default'
751 * domain, change the path to master.passwd accordingly.
752 */
753
754 if (strcmp(argp->domain, yppasswd_domain)) {
755 snprintf(passfile_buf, sizeof(passfile_buf),
756 "%s/%s/master.passwd", yp_dir, argp->domain);
757 passfile = (char *)&passfile_buf;
758 }
759
760 if ((pfd = pw_lock()) < 0) {
791 }
792
793 /*
794 * If the caller specified a domain other than our 'default'
795 * domain, change the path to master.passwd accordingly.
796 */
797
798 if (strcmp(argp->domain, yppasswd_domain)) {
799 snprintf(passfile_buf, sizeof(passfile_buf),
800 "%s/%s/master.passwd", yp_dir, argp->domain);
801 passfile = (char *)&passfile_buf;
802 }
803
804 if ((pfd = pw_lock()) < 0) {
761 return (result);
805 return (&result);
762 }
763 if ((tfd = pw_tmp()) < 0) {
806 }
807 if ((tfd = pw_tmp()) < 0) {
764 return (result);
808 return (&result);
765 }
766
767 if (pw_copy(pfd, tfd, (struct passwd *)&argp->newpw)) {
768 yp_error("failed to created updated password file -- \
769cleaning up and bailing out");
770 unlink(tempname);
809 }
810
811 if (pw_copy(pfd, tfd, (struct passwd *)&argp->newpw)) {
812 yp_error("failed to created updated password file -- \
813cleaning up and bailing out");
814 unlink(tempname);
771 return(result);
815 return(&result);
772 }
773
774 passfile_hold = yp_mktmpnam();
775 rename(passfile, passfile_hold);
776 if (strcmp(passfile, _PATH_MASTERPASSWD)) {
777 rename(tempname, passfile);
778 } else {
779 if (pw_mkdb(argp->newpw.pw_name) < 0) {
780 yp_error("pwd_mkdb failed");
816 }
817
818 passfile_hold = yp_mktmpnam();
819 rename(passfile, passfile_hold);
820 if (strcmp(passfile, _PATH_MASTERPASSWD)) {
821 rename(tempname, passfile);
822 } else {
823 if (pw_mkdb(argp->newpw.pw_name) < 0) {
824 yp_error("pwd_mkdb failed");
781 return(result);
825 return(&result);
782 }
783 }
784
785 if (inplace) {
786 if ((rval = update_inplace((struct passwd *)&argp->newpw,
787 argp->domain))) {
788 yp_error("inplace update failed -- rebuilding maps");
789 }
790 }
791
792 switch((pid = fork())) {
793 case 0:
826 }
827 }
828
829 if (inplace) {
830 if ((rval = update_inplace((struct passwd *)&argp->newpw,
831 argp->domain))) {
832 yp_error("inplace update failed -- rebuilding maps");
833 }
834 }
835
836 switch((pid = fork())) {
837 case 0:
794 close(yp_sock);
795 if (inplace && !rval) {
796 execlp(MAP_UPDATE_PATH, MAP_UPDATE, passfile,
797 argp->domain, "pushpw", NULL);
798 } else {
799 execlp(MAP_UPDATE_PATH, MAP_UPDATE, passfile,
800 argp->domain, NULL);
801 }
802 yp_error("couldn't exec map update process: %s",
803 strerror(errno));
804 unlink(passfile);
805 rename(passfile_hold, passfile);
806 exit(1);
807 break;
808 case -1:
809 yp_error("fork() failed: %s", strerror(errno));
810 unlink(passfile);
811 rename(passfile_hold, passfile);
838 if (inplace && !rval) {
839 execlp(MAP_UPDATE_PATH, MAP_UPDATE, passfile,
840 argp->domain, "pushpw", NULL);
841 } else {
842 execlp(MAP_UPDATE_PATH, MAP_UPDATE, passfile,
843 argp->domain, NULL);
844 }
845 yp_error("couldn't exec map update process: %s",
846 strerror(errno));
847 unlink(passfile);
848 rename(passfile_hold, passfile);
849 exit(1);
850 break;
851 case -1:
852 yp_error("fork() failed: %s", strerror(errno));
853 unlink(passfile);
854 rename(passfile_hold, passfile);
812 return(result);
855 return(&result);
813 break;
814 default:
815 unlink(passfile_hold);
816 break;
817 }
818
819 yp_error("performed update of user %s (uid %d) domain %s",
820 argp->newpw.pw_name,
821 argp->newpw.pw_uid,
822 argp->domain);
823
824 result = 0;
856 break;
857 default:
858 unlink(passfile_hold);
859 break;
860 }
861
862 yp_error("performed update of user %s (uid %d) domain %s",
863 argp->newpw.pw_name,
864 argp->newpw.pw_uid,
865 argp->domain);
866
867 result = 0;
825 return(result);
868 return(&result);
826}
869}
827
828/*
829 * Pseudo-dispatcher for private 'superuser-only' update handler.
830 */
831void do_master()
832{
833 struct master_yppasswd *pw;
834
835 if ((pw = getdat(yp_sock)) == NULL) {
836 return;
837 }
838
839 yp_error("received update request from superuser on localhost");
840 sendresp(update_master(pw));
841
842 /* Remember to free args. */
843 xdr_free(xdr_master_yppasswd, (char *)pw);
844
845 return;
846}