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