1 /* $NetBSD: pw_yp.c,v 1.18 2000/10/27 16:16:03 phil 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.18 2000/10/27 16:16:03 phil 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 yppasswd.newpw.pw_passwd = strdup(pw->pw_passwd); 170 yppasswd.newpw.pw_uid = pw->pw_uid; 171 yppasswd.newpw.pw_gid = pw->pw_gid; 172 yppasswd.newpw.pw_gecos = strdup(pw->pw_gecos); 173 yppasswd.newpw.pw_dir = strdup(pw->pw_dir); 174 yppasswd.newpw.pw_shell = strdup(pw->pw_shell); 175 176 client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp"); 177 if (client == NULL) { 178 warnx("cannot contact yppasswdd on %s: Reason: %s", 179 master, yperr_string(YPERR_YPBIND)); 180 return (1); 181 } 182 client->cl_auth = authunix_create_default(); 183 tv.tv_sec = 5; 184 tv.tv_usec = 0; 185 r = clnt_call(client, YPPASSWDPROC_UPDATE, 186 xdr_yppasswd, &yppasswd, xdr_int, &status, tv); 187 if (r) { 188 warnx("rpc to yppasswdd failed."); 189 return (1); 190 } else if (status) 191 printf("Couldn't change YP password.\n"); 192 else 193 printf("%s %s, %s\n", 194 "The YP password information has been changed on", 195 master, "the master YP passwd server."); 196 return (0); 197 } 198 199 void 200 yppw_error(name, err, eval) 201 const char *name; 202 int err, eval; 203 { 204 205 if (err) { 206 if (name) 207 warn("%s", name); 208 else 209 warn(NULL); 210 } 211 212 errx(eval, "YP passwd information unchanged"); 213 } 214 215 void 216 yppw_prompt() 217 { 218 int c; 219 220 (void)printf("re-edit the password file? [y]: "); 221 (void)fflush(stdout); 222 c = getchar(); 223 if (c != EOF && c != '\n') 224 while (getchar() != '\n'); 225 if (c == 'n') 226 yppw_error(NULL, 0, 0); 227 } 228 #endif /* YP */ 229