1 /* $NetBSD: pw_yp.c,v 1.20 2003/08/07 11:13:19 agc 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.20 2003/08/07 11:13:19 agc 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() 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(pw, uid) 107 struct passwd *pw; 108 uid_t uid; 109 { 110 char *master; 111 int r, rpcport, status; 112 struct yppasswd yppasswd; 113 struct timeval tv; 114 CLIENT *client; 115 116 /* 117 * Get local domain 118 */ 119 if (!domain && (r = yp_get_default_domain(&domain))) 120 errx(1, "can't get local YP domain. Reason: %s", 121 yperr_string(r)); 122 123 /* 124 * Find the host for the passwd map; it should be running 125 * the daemon. 126 */ 127 master = NULL; 128 if ((r = yp_master(domain, "passwd.byname", &master)) != 0) { 129 if (master) 130 free (master); 131 warnx("can't find the master YP server. Reason: %s", 132 yperr_string(r)); 133 return (1); 134 } 135 136 /* 137 * Ask the portmapper for the port of the daemon. 138 */ 139 if ((rpcport = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, 140 IPPROTO_UDP)) == 0) { 141 warnx("master YP server not running yppasswd daemon.\n\t%s\n", 142 "Can't change password."); 143 return (1); 144 } 145 146 /* 147 * Be sure the port is privileged 148 */ 149 if (rpcport >= IPPORT_RESERVED) { 150 warnx("yppasswd daemon is on an invalid port."); 151 return (1); 152 } 153 154 /* prompt for old password */ 155 memset(&yppasswd, 0, sizeof yppasswd); 156 yppasswd.oldpass = "none"; 157 yppasswd.oldpass = getpass("Old password:"); 158 if (!yppasswd.oldpass) { 159 warnx("Cancelled."); 160 return (1); 161 } 162 163 /* tell rpc.yppasswdd */ 164 yppasswd.newpw.pw_name = strdup(pw->pw_name); 165 if (!yppasswd.newpw.pw_name) { 166 err(1, "strdup"); 167 /*NOTREACHED*/ 168 } 169 yppasswd.newpw.pw_passwd = strdup(pw->pw_passwd); 170 if (!yppasswd.newpw.pw_passwd) { 171 err(1, "strdup"); 172 /*NOTREACHED*/ 173 } 174 yppasswd.newpw.pw_uid = pw->pw_uid; 175 yppasswd.newpw.pw_gid = pw->pw_gid; 176 yppasswd.newpw.pw_gecos = strdup(pw->pw_gecos); 177 if (!yppasswd.newpw.pw_gecos) { 178 err(1, "strdup"); 179 /*NOTREACHED*/ 180 } 181 yppasswd.newpw.pw_dir = strdup(pw->pw_dir); 182 if (!yppasswd.newpw.pw_dir) { 183 err(1, "strdup"); 184 /*NOTREACHED*/ 185 } 186 yppasswd.newpw.pw_shell = strdup(pw->pw_shell); 187 if (!yppasswd.newpw.pw_shell) { 188 err(1, "strdup"); 189 /*NOTREACHED*/ 190 } 191 192 client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp"); 193 if (client == NULL) { 194 warnx("cannot contact yppasswdd on %s: Reason: %s", 195 master, yperr_string(YPERR_YPBIND)); 196 return (1); 197 } 198 client->cl_auth = authunix_create_default(); 199 tv.tv_sec = 5; 200 tv.tv_usec = 0; 201 r = clnt_call(client, YPPASSWDPROC_UPDATE, 202 xdr_yppasswd, &yppasswd, xdr_int, &status, tv); 203 if (r) { 204 warnx("rpc to yppasswdd failed."); 205 return (1); 206 } else if (status) 207 printf("Couldn't change YP password.\n"); 208 else 209 printf("%s %s, %s\n", 210 "The YP password information has been changed on", 211 master, "the master YP passwd server."); 212 return (0); 213 } 214 215 void 216 yppw_error(name, err, eval) 217 const char *name; 218 int err, eval; 219 { 220 221 if (err) { 222 if (name) 223 warn("%s", name); 224 else 225 warn(NULL); 226 } 227 228 errx(eval, "YP passwd information unchanged"); 229 } 230 231 void 232 yppw_prompt() 233 { 234 int c; 235 236 (void)printf("re-edit the password file? [y]: "); 237 (void)fflush(stdout); 238 c = getchar(); 239 if (c != EOF && c != '\n') 240 while (getchar() != '\n'); 241 if (c == 'n') 242 yppw_error(NULL, 0, 0); 243 } 244 #endif /* YP */ 245