1 /* $NetBSD: pw_yp.c,v 1.22 2009/04/11 12:10:02 lukem Exp $ */ 2 3 /* 4 * Copyright (c) 1988 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 #include <sys/cdefs.h> 32 #ifndef lint 33 #if 0 34 static char sccsid[] = "@(#)pw_yp.c 1.0 2/2/93"; 35 #else 36 __RCSID("$NetBSD: pw_yp.c,v 1.22 2009/04/11 12:10:02 lukem Exp $"); 37 #endif 38 #endif /* not lint */ 39 40 #ifdef YP 41 42 #include <err.h> 43 #include <errno.h> 44 #include <netdb.h> 45 #include <pwd.h> 46 #include <stdio.h> 47 #include <stdlib.h> 48 #include <string.h> 49 #include <time.h> 50 #include <unistd.h> 51 52 #include <rpc/rpc.h> 53 #include <rpcsvc/yp_prot.h> 54 #include <rpcsvc/ypclnt.h> 55 56 #define passwd yp_passwd_rec 57 #include <rpcsvc/yppasswd.h> 58 #undef passwd 59 60 #include "chpass.h" 61 62 static char *domain; 63 64 /* 65 * Check if rpc.yppasswdd is running on the master YP server. 66 * XXX this duplicates some code, but is much less complex 67 * than the alternative. 68 */ 69 int 70 check_yppasswdd(void) 71 { 72 char *master; 73 int rpcport; 74 75 /* 76 * Get local domain 77 */ 78 if (!domain && yp_get_default_domain(&domain) != 0) 79 return (1); 80 81 /* 82 * Find the host for the passwd map; it should be running 83 * the daemon. 84 */ 85 master = NULL; 86 if (yp_master(domain, "passwd.byname", &master) != 0) { 87 if (master != NULL) 88 free (master); 89 return (1); 90 } 91 92 /* 93 * Ask the portmapper for the port of the daemon. 94 */ 95 if ((rpcport = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, 96 IPPROTO_UDP)) == 0) 97 return (1); 98 99 /* 100 * Successful contact with rpc.yppasswdd. 101 */ 102 return (0); 103 } 104 105 int 106 pw_yp(struct passwd *pw, uid_t ypuid) 107 { 108 char *master; 109 int r, rpcport, status; 110 struct yppasswd yppw; 111 struct timeval tv; 112 CLIENT *client; 113 114 /* 115 * Get local domain 116 */ 117 if (!domain && (r = yp_get_default_domain(&domain))) 118 errx(1, "can't get local YP domain. Reason: %s", 119 yperr_string(r)); 120 121 /* 122 * Find the host for the passwd map; it should be running 123 * the daemon. 124 */ 125 master = NULL; 126 if ((r = yp_master(domain, "passwd.byname", &master)) != 0) { 127 if (master) 128 free (master); 129 warnx("can't find the master YP server. Reason: %s", 130 yperr_string(r)); 131 return (1); 132 } 133 134 /* 135 * Ask the portmapper for the port of the daemon. 136 */ 137 if ((rpcport = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, 138 IPPROTO_UDP)) == 0) { 139 warnx("master YP server not running yppasswd daemon.\n\t%s\n", 140 "Can't change password."); 141 return (1); 142 } 143 144 /* 145 * Be sure the port is privileged 146 */ 147 if (rpcport >= IPPORT_RESERVED) { 148 warnx("yppasswd daemon is on an invalid port."); 149 return (1); 150 } 151 152 /* prompt for old password */ 153 memset(&yppw, 0, sizeof yppw); 154 yppw.oldpass = getpass("Old password:"); 155 if (!yppw.oldpass) { 156 warnx("Cancelled."); 157 return (1); 158 } 159 160 /* tell rpc.yppasswdd */ 161 yppw.newpw.pw_name = strdup(pw->pw_name); 162 if (!yppw.newpw.pw_name) { 163 err(1, "strdup"); 164 /*NOTREACHED*/ 165 } 166 yppw.newpw.pw_passwd = strdup(pw->pw_passwd); 167 if (!yppw.newpw.pw_passwd) { 168 err(1, "strdup"); 169 /*NOTREACHED*/ 170 } 171 yppw.newpw.pw_uid = pw->pw_uid; 172 yppw.newpw.pw_gid = pw->pw_gid; 173 yppw.newpw.pw_gecos = strdup(pw->pw_gecos); 174 if (!yppw.newpw.pw_gecos) { 175 err(1, "strdup"); 176 /*NOTREACHED*/ 177 } 178 yppw.newpw.pw_dir = strdup(pw->pw_dir); 179 if (!yppw.newpw.pw_dir) { 180 err(1, "strdup"); 181 /*NOTREACHED*/ 182 } 183 yppw.newpw.pw_shell = strdup(pw->pw_shell); 184 if (!yppw.newpw.pw_shell) { 185 err(1, "strdup"); 186 /*NOTREACHED*/ 187 } 188 189 client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp"); 190 if (client == NULL) { 191 warnx("cannot contact yppasswdd on %s: Reason: %s", 192 master, yperr_string(YPERR_YPBIND)); 193 return (1); 194 } 195 client->cl_auth = authunix_create_default(); 196 tv.tv_sec = 5; 197 tv.tv_usec = 0; 198 r = clnt_call(client, YPPASSWDPROC_UPDATE, 199 xdr_yppasswd, &yppw, xdr_int, &status, tv); 200 if (r) { 201 warnx("rpc to yppasswdd failed."); 202 return (1); 203 } else if (status) 204 printf("Couldn't change YP password.\n"); 205 else 206 printf("%s %s, %s\n", 207 "The YP password information has been changed on", 208 master, "the master YP passwd server."); 209 return (0); 210 } 211 212 void 213 yppw_error(const char *name, int yperr, int eval) 214 { 215 216 if (yperr) { 217 if (name) 218 warn("%s", name); 219 else 220 warn(NULL); 221 } 222 223 errx(eval, "YP passwd information unchanged"); 224 } 225 226 void 227 yppw_prompt(void) 228 { 229 int c; 230 231 (void)printf("re-edit the password file? [y]: "); 232 (void)fflush(stdout); 233 c = getchar(); 234 if (c != EOF && c != '\n') 235 while (getchar() != '\n'); 236 if (c == 'n') 237 yppw_error(NULL, 0, 0); 238 } 239 #endif /* YP */ 240