1 /* $OpenBSD: passwd.c,v 1.24 2007/09/08 18:42:36 cloder 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 32 #ifndef lint 33 char copyright[] = 34 "@(#) Copyright (c) 1988 The Regents of the University of California.\n\ 35 All rights reserved.\n"; 36 #endif /* not lint */ 37 38 #ifndef lint 39 /*static const char sccsid[] = "from: @(#)passwd.c 5.5 (Berkeley) 7/6/91";*/ 40 static const char rcsid[] = "$OpenBSD: passwd.c,v 1.24 2007/09/08 18:42:36 cloder Exp $"; 41 #endif /* not lint */ 42 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <unistd.h> 47 #include <err.h> 48 #include <rpcsvc/ypclnt.h> 49 50 #if defined(KRB5) 51 #include <sys/stat.h> 52 #endif 53 54 /* 55 * Note on configuration: 56 * Generally one would not use both Kerberos and YP 57 * to maintain passwords. 58 * 59 */ 60 61 int use_kerberos; 62 int use_yp; 63 64 #ifdef YP 65 int force_yp; 66 #endif 67 68 extern int local_passwd(char *, int); 69 extern int yp_passwd(char *); 70 extern int krb5_passwd(int, char **); 71 extern int _yp_check(char **); 72 void usage(int retval); 73 74 int 75 main(int argc, char **argv) 76 { 77 extern int optind; 78 char *username; 79 int ch; 80 #ifdef YP 81 int status = 0; 82 #endif 83 #if defined(KRB5) 84 char *ccfile; 85 struct stat sb; 86 87 if (!(ccfile = getenv("KRB5CCNAME"))) 88 if (asprintf(&ccfile, "/tmp/krb5cc_%u", (unsigned)getuid()) == 89 -1) 90 errx(1, "out of memory"); 91 92 if ((stat(ccfile, &sb) == 0) && (sb.st_uid == getuid())) 93 use_kerberos = 1; 94 #endif 95 #ifdef YP 96 use_yp = _yp_check(NULL); 97 if (use_yp) { 98 char *dom; 99 100 yp_get_default_domain(&dom); 101 yp_unbind(dom); 102 } 103 #endif 104 105 /* Process args and options */ 106 while ((ch = getopt(argc, argv, "lyK")) != -1) 107 switch (ch) { 108 case 'l': /* change local password file */ 109 use_kerberos = 0; 110 use_yp = 0; 111 break; 112 case 'K': 113 #if defined(KRB5) 114 /* Skip programname and '-K' option */ 115 argc -= 2; 116 argv += 2; 117 exit(krb5_passwd(argc, argv)); 118 #else 119 errx(1, "KerberosV support not enabled"); 120 break; 121 #endif 122 case 'y': /* change YP password */ 123 #ifdef YP 124 if (!use_yp) { 125 fprintf(stderr, "passwd: YP not in use.\n"); 126 exit(1); 127 } 128 use_kerberos = 0; 129 use_yp = 1; 130 force_yp = 1; 131 break; 132 #else 133 fprintf(stderr, "passwd: YP not compiled in\n"); 134 exit(1); 135 #endif 136 default: 137 usage(1); 138 } 139 140 argc -= optind; 141 argv += optind; 142 143 username = getlogin(); 144 if (username == NULL) { 145 fprintf(stderr, "passwd: who are you ??\n"); 146 exit(1); 147 } 148 149 switch (argc) { 150 case 0: 151 break; 152 case 1: 153 username = argv[0]; 154 break; 155 default: 156 usage(1); 157 } 158 159 #if defined(KRB5) 160 if (use_kerberos) 161 exit(krb5_passwd(argc, argv)); 162 #endif 163 #ifdef YP 164 if (force_yp || ((status = local_passwd(username, 0)) && use_yp)) 165 exit(yp_passwd(username)); 166 exit(status); 167 #else 168 exit(local_passwd(username, 0)); 169 #endif 170 } 171 172 void 173 usage(int retval) 174 { 175 fprintf(stderr, "usage: passwd [-K | -l | -y] [user]\n"); 176 exit(retval); 177 } 178