Home | History | Annotate | Line # | Download | only in chpass
pw_yp.c revision 1.2
      1 /*
      2  * Copyright (c) 1988 The Regents of the University of California.
      3  * 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
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. All advertising materials mentioning features or use of this software
     14  *    must display the following acknowledgement:
     15  *	This product includes software developed by the University of
     16  *	California, Berkeley and its contributors.
     17  * 4. Neither the name of the University nor the names of its contributors
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  */
     33 #ifndef lint
     34 /*static char sccsid[] = "from: @(#)pw_yp.c	1.0 2/2/93";*/
     35 static char rcsid[] = "$Id: pw_yp.c,v 1.2 1993/08/01 18:17:53 mycroft Exp $";
     36 #endif /* not lint */
     37 
     38 #ifdef	YP
     39 
     40 #include <stdio.h>
     41 #include <string.h>
     42 #include <netdb.h>
     43 #include <time.h>
     44 #include <pwd.h>
     45 #include <errno.h>
     46 #include <rpc/rpc.h>
     47 #include <rpcsvc/yp_prot.h>
     48 #include <rpcsvc/ypclnt.h>
     49 #define passwd yp_passwd_rec
     50 #include <rpcsvc/yppasswd.h>
     51 #undef passwd
     52 
     53 extern char *progname;
     54 
     55 static char *domain;
     56 
     57 pw_yp(pw, uid)
     58         struct passwd *pw;
     59         uid_t uid;
     60 {
     61         char *master;
     62         char *pp;
     63         int r, rpcport, status;
     64         struct yppasswd yppasswd;
     65 	struct timeval tv;
     66 	CLIENT *client;
     67         extern char *getpass();
     68 
     69         /*
     70          * Get local domain
     71          */
     72         if (!domain && (r = yp_get_default_domain(&domain))) {
     73                 (void)fprintf(stderr, "%s: can't get local NIS domain. Reason: %s\n", progname, yperr_string(r));
     74                 return(0);
     75         }
     76 
     77         /*
     78          * Find the host for the passwd map; it should be running
     79          * the daemon.
     80          */
     81         if ((r = yp_master(domain, "passwd.byname", &master)) != 0) {
     82                 (void)fprintf(stderr, "%s: can't find the master NIS server. Reason: %s\n", progname, yperr_string(r));
     83                 return(0);
     84         }
     85 
     86         /*
     87          * Ask the portmapper for the port of the daemon.
     88          */
     89         if ((rpcport = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0) {
     90                 (void)fprintf(stderr, "%s: master NIS server not running yppasswd daemon.\n\tCan't change password.\n", progname);
     91                 return(0);
     92         }
     93 
     94         /*
     95          * Be sure the port is priviledged
     96          */
     97         if (rpcport >= IPPORT_RESERVED) {
     98                 (void)fprintf(stderr, "%s: yppasswd daemon running on an invalid port.\n", progname);
     99                 return(0);
    100         }
    101 
    102         /* prompt for old password */
    103         yppasswd.oldpass = "none";
    104         if (uid)
    105                 yppasswd.oldpass = getpass("Old password:");
    106         if (!yppasswd.oldpass) {
    107                 (void)fprintf(stderr, "Cancelled.\n");
    108                 return(0);
    109         }
    110 
    111         /* tell rpc.yppasswdd */
    112         yppasswd.newpw.pw_name	= pw->pw_name;
    113         yppasswd.newpw.pw_passwd= pw->pw_passwd;
    114         yppasswd.newpw.pw_uid 	= pw->pw_uid;
    115         yppasswd.newpw.pw_gid	= pw->pw_gid;
    116         yppasswd.newpw.pw_gecos = pw->pw_gecos;
    117         yppasswd.newpw.pw_dir	= pw->pw_dir;
    118         yppasswd.newpw.pw_shell	= pw->pw_shell;
    119 
    120         client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
    121         if (client==NULL) {
    122                 fprintf(stderr, "can't contact yppasswdd on %s: Reason: %s\n",
    123                         master, yperr_string(YPERR_YPBIND));
    124                 return(0);
    125         }
    126         client->cl_auth = authunix_create_default();
    127         tv.tv_sec = 2;
    128         tv.tv_usec = 0;
    129         r = clnt_call(client, YPPASSWDPROC_UPDATE,
    130                       xdr_yppasswd, &yppasswd, xdr_int, &status, tv);
    131         if (r) {
    132                 fprintf(stderr, "%s: rpc to yppasswdd failed.\n");
    133                 return(0);
    134         }
    135         else if (status) {
    136                 printf("Couldn't change NIS password information.\n");
    137                 return(0);
    138         }
    139         else
    140                 printf("The NIS password information has been changed on %s, the master NIS passwd server.\n", master);
    141 
    142         return(1);
    143 }
    144 
    145 static char *
    146 pwskip(register char *p)
    147 {
    148 	while (*p && *p != ':' && *p != '\n')
    149 		++p;
    150 	if (*p)
    151 		*p++ = 0;
    152 	return (p);
    153 }
    154 
    155 static struct passwd *
    156 interpret(struct passwd *pwent, char *line)
    157 {
    158 	register char	*p = line;
    159 	register int	c;
    160 
    161         pwent->pw_passwd = "*";
    162         pwent->pw_uid = 0;
    163         pwent->pw_gid = 0;
    164         pwent->pw_gecos = "";
    165         pwent->pw_dir = "";
    166         pwent->pw_shell = "";
    167 	pwent->pw_change = 0;
    168 	pwent->pw_expire = 0;
    169 	pwent->pw_class = "";
    170 
    171         /* line without colon separators is no good, so ignore it */
    172         if(!strchr(p,':'))
    173                 return(NULL);
    174 
    175 	pwent->pw_name = p;
    176 	p = pwskip(p);
    177 	pwent->pw_passwd = p;
    178 	p = pwskip(p);
    179 	pwent->pw_uid = (uid_t)strtoul(p, NULL, 10);
    180 	p = pwskip(p);
    181 	pwent->pw_gid = (gid_t)strtoul(p, NULL, 10);
    182 	p = pwskip(p);
    183 	pwent->pw_gecos = p;
    184 	p = pwskip(p);
    185 	pwent->pw_dir = p;
    186 	p = pwskip(p);
    187 	pwent->pw_shell = p;
    188 	while (*p && *p != '\n')
    189 		p++;
    190 	*p = '\0';
    191 	return (pwent);
    192 }
    193 
    194 struct passwd *
    195 ypgetpwnam(nam)
    196         char *nam;
    197 {
    198         static struct passwd pwent;
    199         static char line[1024];
    200         char *val;
    201         int reason, vallen;
    202 
    203         /*
    204          * Get local domain
    205          */
    206         if (!domain && (reason = yp_get_default_domain(&domain))) {
    207                 (void)fprintf(stderr, "%s: can't get local NIS domain. Reason: %s\n", progname, yperr_string(reason));
    208                 exit(1);
    209         }
    210 
    211         reason = yp_match(domain, "passwd.byname", nam, strlen(nam),
    212                           &val, &vallen);
    213         switch(reason) {
    214         case 0:
    215                 break;
    216         default:
    217                 return (NULL);
    218                 break;
    219         }
    220         val[vallen] = '\0';
    221         strcpy(line, val);
    222         free(val);
    223 
    224         return(interpret(&pwent, line));
    225 }
    226 
    227 struct passwd *
    228 ypgetpwuid(uid)
    229         uid_t uid;
    230 {
    231         static struct passwd pwent;
    232         static char line[1024];
    233         char *val;
    234         int reason, vallen;
    235         char namebuf[16];
    236 
    237         if (!domain && (reason = yp_get_default_domain(&domain))) {
    238                 (void)fprintf(stderr, "%s: can't get local NIS domain. Reason: %s\n", progname, yperr_string(reason));
    239                 exit(1);
    240         }
    241 
    242         sprintf(namebuf, "%d", uid);
    243         reason = yp_match(domain, "passwd.byuid", namebuf, strlen(namebuf),
    244                           &val, &vallen);
    245         switch(reason) {
    246         case 0:
    247                 break;
    248         default:
    249                 return (NULL);
    250                 break;
    251         }
    252         val[vallen] = '\0';
    253         strcpy(line, val);
    254         free(val);
    255 
    256         return(interpret(&pwent, line));
    257 }
    258 
    259 #endif	/* YP */
    260