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} | |