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.4 1994/08/17 19:54:23 deraadt 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 fprintf(stderr, "%s: can't get local YP domain. Reason: %s\n", 74 progname, yperr_string(r)); 75 return(0); 76 } 77 78 /* 79 * Find the host for the passwd map; it should be running 80 * the daemon. 81 */ 82 if ((r = yp_master(domain, "passwd.byname", &master)) != 0) { 83 fprintf(stderr, 84 "%s: can't find the master YP server. Reason: %s\n", 85 progname, yperr_string(r)); 86 return(0); 87 } 88 89 /* 90 * Ask the portmapper for the port of the daemon. 91 */ 92 if ((rpcport = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, 93 IPPROTO_UDP)) == 0) { 94 fprintf(stderr, 95 "%s: master YP server not running yppasswd daemon.\n", 96 progname); 97 fprintf(stderr, "\tCan't change password.\n"); 98 return(0); 99 } 100 101 /* 102 * Be sure the port is priviledged 103 */ 104 if (rpcport >= IPPORT_RESERVED) { 105 (void)fprintf(stderr, 106 "%s: yppasswd daemon running on an invalid port.\n", 107 progname); 108 return(0); 109 } 110 111 /* prompt for old password */ 112 bzero(&yppasswd, sizeof yppasswd); 113 yppasswd.oldpass = "none"; 114 yppasswd.oldpass = getpass("Old password:"); 115 if (!yppasswd.oldpass) { 116 (void)fprintf(stderr, "Cancelled.\n"); 117 return(0); 118 } 119 120 /* tell rpc.yppasswdd */ 121 yppasswd.newpw.pw_name = pw->pw_name; 122 yppasswd.newpw.pw_passwd= pw->pw_passwd; 123 yppasswd.newpw.pw_uid = pw->pw_uid; 124 yppasswd.newpw.pw_gid = pw->pw_gid; 125 yppasswd.newpw.pw_gecos = pw->pw_gecos; 126 yppasswd.newpw.pw_dir = pw->pw_dir; 127 yppasswd.newpw.pw_shell = pw->pw_shell; 128 129 client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp"); 130 if (client==NULL) { 131 fprintf(stderr, "can't contact yppasswdd on %s: Reason: %s\n", 132 master, yperr_string(YPERR_YPBIND)); 133 return(0); 134 } 135 client->cl_auth = authunix_create_default(); 136 tv.tv_sec = 5; 137 tv.tv_usec = 0; 138 r = clnt_call(client, YPPASSWDPROC_UPDATE, 139 xdr_yppasswd, &yppasswd, xdr_int, &status, tv); 140 if (r) { 141 fprintf(stderr, "%s: rpc to yppasswdd failed. %d\n", progname, r); 142 return(0); 143 } else if (status) { 144 printf("Couldn't change YP password information.\n"); 145 return(0); 146 } 147 printf("The YP password information has been changed on %s, the master YP passwd server.\n", master); 148 149 return(1); 150 } 151 152 static char * 153 pwskip(p) 154 register char *p; 155 { 156 while (*p && *p != ':' && *p != '\n') 157 ++p; 158 if (*p) 159 *p++ = 0; 160 return (p); 161 } 162 163 static struct passwd * 164 interpret(pwent, line) 165 struct passwd *pwent; 166 char *line; 167 { 168 register char *p = line; 169 register int c; 170 171 pwent->pw_passwd = "*"; 172 pwent->pw_uid = 0; 173 pwent->pw_gid = 0; 174 pwent->pw_gecos = ""; 175 pwent->pw_dir = ""; 176 pwent->pw_shell = ""; 177 pwent->pw_change = 0; 178 pwent->pw_expire = 0; 179 pwent->pw_class = ""; 180 181 /* line without colon separators is no good, so ignore it */ 182 if(!strchr(p,':')) 183 return(NULL); 184 185 pwent->pw_name = p; 186 p = pwskip(p); 187 pwent->pw_passwd = p; 188 p = pwskip(p); 189 pwent->pw_uid = (uid_t)strtoul(p, NULL, 10); 190 p = pwskip(p); 191 pwent->pw_gid = (gid_t)strtoul(p, NULL, 10); 192 p = pwskip(p); 193 pwent->pw_gecos = p; 194 p = pwskip(p); 195 pwent->pw_dir = p; 196 p = pwskip(p); 197 pwent->pw_shell = p; 198 while (*p && *p != '\n') 199 p++; 200 *p = '\0'; 201 return (pwent); 202 } 203 204 struct passwd * 205 ypgetpwnam(nam) 206 char *nam; 207 { 208 static struct passwd pwent; 209 static char line[1024]; 210 char *val; 211 int reason, vallen; 212 213 /* 214 * Get local domain 215 */ 216 if (!domain && (reason = yp_get_default_domain(&domain))) { 217 fprintf(stderr, "%s: can't get local YP domain. Reason: %s\n", 218 progname, yperr_string(reason)); 219 exit(1); 220 } 221 222 reason = yp_match(domain, "passwd.byname", nam, strlen(nam), 223 &val, &vallen); 224 switch(reason) { 225 case 0: 226 break; 227 default: 228 return (NULL); 229 break; 230 } 231 val[vallen] = '\0'; 232 strcpy(line, val); 233 free(val); 234 235 return(interpret(&pwent, line)); 236 } 237 238 struct passwd * 239 ypgetpwuid(uid) 240 uid_t uid; 241 { 242 static struct passwd pwent; 243 static char line[1024]; 244 char *val; 245 int reason, vallen; 246 char namebuf[16]; 247 248 if (!domain && (reason = yp_get_default_domain(&domain))) { 249 fprintf(stderr, "%s: can't get local YP domain. Reason: %s\n", 250 progname, yperr_string(reason)); 251 exit(1); 252 } 253 254 sprintf(namebuf, "%d", uid); 255 reason = yp_match(domain, "passwd.byuid", namebuf, strlen(namebuf), 256 &val, &vallen); 257 switch(reason) { 258 case 0: 259 break; 260 default: 261 return (NULL); 262 break; 263 } 264 val[vallen] = '\0'; 265 strcpy(line, val); 266 free(val); 267 268 return(interpret(&pwent, line)); 269 } 270 271 #endif /* YP */ 272