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