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#define INFO_FILE 1
25#define INFO_NIS 2
26#define INFO_OPEN_DIRECTORY 3
27#define INFO_PAM 4
28
29#ifndef __SLICK__
30#define _PASSWD_FILE "/etc/master.passwd"
31#else
32#define _PASSWD_FILE "/etc/passwd"
33#endif
34
35#include <stdio.h>
36#include <errno.h>
37#include <pwd.h>
38#include <libc.h>
39#include <ctype.h>
40#include <string.h>
41#include <pwd.h>
42#include "stringops.h"
43
44#ifdef __SLICK__
45#define _PASSWORD_LEN 8
46#endif
47
48const char* progname = "chkpasswd";
49
50static int literal = 0;
51
52extern int file_check_passwd(char *, char *);
53extern int nis_check_passwd(char *, char *);
54extern int od_check_passwd(char *, char *);
55extern int pam_check_passwd(char *);
56
57void
58checkpasswd(char *name, char *old_pw)
59{
60	int isNull;
61	char *p;
62
63	printf("Checking password for %s.\n", name);
64
65	p = "";
66	isNull = 0;
67	if (old_pw == NULL) isNull = 1;
68	if ((isNull == 0) && (old_pw[0] == '\0')) isNull = 1;
69	if (isNull == 0)
70	{
71		p = getpass("Password:");
72		sleep(1); // make sure this doesn't go too quickly
73		if (strcmp(literal ? p : crypt(p, old_pw), old_pw))
74		{
75			errno = EACCES;
76			fprintf(stderr, "Sorry\n");
77			exit(1);
78		}
79	}
80	return;
81}
82
83void
84usage()
85{
86	fprintf(stderr, "usage: chkpasswd [-i infosystem] [-l location] [-c] [name]\n");
87	fprintf(stderr, "  infosystem:\n");
88	fprintf(stderr, "    file\n");
89	fprintf(stderr, "    NIS\n");
90	fprintf(stderr, "    OpenDirectory\n");
91	fprintf(stderr, "  location (for infosystem):\n");
92	fprintf(stderr, "    file           location is path to file (default is %s)\n", _PASSWD_FILE);
93	fprintf(stderr, "    NIS            location is NIS domain name\n");
94	fprintf(stderr, "    OpenDirectory  location is directory node name\n");
95	fprintf(stderr, "  -c: supplied password is compared verbatim without first\n");
96	fprintf(stderr, "      being crypted\n");
97	exit(1);
98}
99
100int
101main(int argc, char *argv[])
102{
103	char* user = NULL;
104	char* locn = NULL;
105	int infosystem, ch;
106
107	infosystem = INFO_PAM;
108
109	while ((ch = getopt(argc, argv, "ci:l:")) != -1) {
110		switch(ch) {
111		case 'i':
112			if (!strcasecmp(optarg, "file")) {
113				infosystem = INFO_FILE;
114			} else if (!strcasecmp(optarg, "NIS")) {
115				infosystem = INFO_NIS;
116			} else if (!strcasecmp(optarg, "YP")) {
117				infosystem = INFO_NIS;
118			} else if (!strcasecmp(optarg, "opendirectory")) {
119				infosystem = INFO_OPEN_DIRECTORY;
120			} else if (!strcasecmp(optarg, "PAM")) {
121				infosystem = INFO_PAM;
122			} else {
123				fprintf(stderr, "%s: Unknown info system \'%s\'.\n",
124					progname, optarg);
125				usage();
126			}
127			break;
128		case 'l':
129			locn = optarg;
130			break;
131		case 'c':
132			literal++;
133			break;
134		case '?':
135		default:
136			usage();
137			break;
138		}
139	}
140	argc -= optind;
141	argv += optind;
142
143	if (argc > 1) {
144		usage();
145	} else if (argc == 1) {
146		user = argv[0];
147	}
148
149	if (user == NULL) {
150		struct passwd* pw = getpwuid(getuid());
151		if (pw != NULL && pw->pw_name != NULL) {
152			user = strdup(pw->pw_name);
153		}
154		if (user == NULL) {
155			fprintf(stderr, "you don't have a login name\n");
156			exit(1);
157		}
158	}
159
160	switch (infosystem)
161	{
162		case INFO_FILE:
163			file_check_passwd(user, locn);
164			break;
165		case INFO_NIS:
166			nis_check_passwd(user, locn);
167			break;
168		case INFO_OPEN_DIRECTORY:
169			od_check_passwd(user, locn);
170			break;
171		case INFO_PAM:
172			pam_check_passwd(user);
173			break;
174	}
175
176	exit(0);
177}
178
179