1/* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights 7 * Reserved. This file contains Original Code and/or Modifications of 8 * Original Code as defined in and that are subject to the Apple Public 9 * Source License Version 1.0 (the 'License'). You may not use this file 10 * except in compliance with the License. Please obtain a copy of the 11 * License at http://www.apple.com/publicsource and read it before using 12 * this file. 13 * 14 * The Original Code and all software distributed under the License are 15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 19 * License for the specific language governing rights and limitations 20 * under the License." 21 * 22 * @APPLE_LICENSE_HEADER_END@ 23 */ 24/* 25 * Copyright (c) 1998 by Apple Computer, Inc. 26 * Portions Copyright (c) 1988 by Sun Microsystems, Inc. 27 * Portions Copyright (c) 1988 The Regents of the University of California. 28 * All rights reserved. 29 * 30 * Redistribution and use in source and binary forms, with or without 31 * modification, are permitted provided that the following conditions 32 * are met: 33 * 1. Redistributions of source code must retain the above copyright 34 * notice, this list of conditions and the following disclaimer. 35 * 2. Redistributions in binary form must reproduce the above copyright 36 * notice, this list of conditions and the following disclaimer in the 37 * documentation and/or other materials provided with the distribution. 38 * 3. All advertising materials mentioning features or use of this software 39 * must display the following acknowledgement: 40 * This product includes software developed by the University of 41 * California, Berkeley and its contributors. 42 * 4. Neither the name of the University nor the names of its contributors 43 * may be used to endorse or promote products derived from this software 44 * without specific prior written permission. 45 * 46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 * SUCH DAMAGE. 57 */ 58 59 60/* update a user's password in NIS. This was based on the Sun implementation 61 * we used in NEXTSTEP, although I've added some stuff from OpenBSD. And 62 * it uses the API to support Rhapsody's proprietry infosystem switch. 63 * lukeh 64 */ 65 66#include <stdio.h> 67#include <stdlib.h> 68#include <unistd.h> 69#include <string.h> 70#include <pwd.h> 71#include <netinet/in.h> 72#include <rpc/types.h> 73#include <rpc/xdr.h> 74#include <rpc/rpc.h> 75#include <rpcsvc/yp_prot.h> 76#include <rpcsvc/ypclnt.h> 77#include <rpcsvc/yppasswd.h> 78#include <netdb.h> 79#include <sys/socket.h> 80#include <sys/file.h> 81#include <errno.h> 82 83extern int getrpcport(char *, int, int, int); 84extern void checkpasswd(char *, char *); 85 86static struct passwd *ypgetpwnam(char *name, char *domain); 87 88int nis_check_passwd(char *uname, char *domain) 89{ 90 int port; 91 char *master; 92 struct passwd *pwd; 93 94 if (domain == NULL) 95 { 96 if (yp_get_default_domain(&domain) != 0) 97 { 98 (void)fprintf(stderr, "can't get domain\n"); 99 exit(1); 100 } 101 } 102 103 if (yp_master(domain, "passwd.byname", &master) != 0) 104 { 105 (void)fprintf(stderr, "can't get master for passwd file\n"); 106 exit(1); 107 } 108 109 port = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, 110 IPPROTO_UDP); 111 if (port == 0) 112 { 113 (void)fprintf(stderr, "%s is not running yppasswd daemon\n", 114 master); 115 exit(1); 116 } 117 if (port >= IPPORT_RESERVED) 118 { 119 (void)fprintf(stderr, 120 "yppasswd daemon is not running on privileged port\n"); 121 exit(1); 122 } 123 124 pwd = ypgetpwnam(uname, domain); 125 if (pwd == NULL) 126 { 127 (void)fprintf(stderr, "user %s not found\n", uname); 128 exit(1); 129 } 130 131 checkpasswd(uname, pwd->pw_passwd); 132 return(0); 133} 134 135static char * 136pwskip(register char *p) 137{ 138 while (*p && *p != ':' && *p != '\n') 139 ++p; 140 if (*p) 141 *p++ = 0; 142 return (p); 143} 144 145struct passwd * 146interpret(struct passwd *pwent, char *line) 147{ 148 register char *p = line; 149 150 pwent->pw_passwd = "*"; 151 pwent->pw_uid = 0; 152 pwent->pw_gid = 0; 153 pwent->pw_gecos = ""; 154 pwent->pw_dir = ""; 155 pwent->pw_shell = ""; 156#ifndef __SLICK__ 157 pwent->pw_change = 0; 158 pwent->pw_expire = 0; 159 pwent->pw_class = ""; 160#endif 161 162 /* line without colon separators is no good, so ignore it */ 163 if(!strchr(p, ':')) 164 return(NULL); 165 166 pwent->pw_name = p; 167 p = pwskip(p); 168 pwent->pw_passwd = p; 169 p = pwskip(p); 170 pwent->pw_uid = (uid_t)strtoul(p, NULL, 10); 171 p = pwskip(p); 172 pwent->pw_gid = (gid_t)strtoul(p, NULL, 10); 173 p = pwskip(p); 174 pwent->pw_gecos = p; 175 p = pwskip(p); 176 pwent->pw_dir = p; 177 p = pwskip(p); 178 pwent->pw_shell = p; 179 while (*p && *p != '\n') 180 p++; 181 *p = '\0'; 182 return (pwent); 183} 184 185 186static struct passwd * 187ypgetpwnam(char *nam, char *domain) 188{ 189 static struct passwd pwent; 190 char *val; 191 int reason, vallen; 192 static char *__yplin = NULL; 193 194 reason = yp_match(domain, "passwd.byname", nam, strlen(nam), 195 &val, &vallen); 196 switch(reason) { 197 case 0: 198 break; 199 default: 200 return (NULL); 201 break; 202 } 203 val[vallen] = '\0'; 204 if (__yplin) 205 free(__yplin); 206 __yplin = (char *)malloc(vallen + 1); 207 strcpy(__yplin, val); 208 free(val); 209 210 return(interpret(&pwent, __yplin)); 211} 212