/*
- * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2016 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include <TargetConditionals.h>
-#define INFO_FILE 1
-#define INFO_NIS 2
-#if !TARGET_OS_EMBEDDED
-#define INFO_OPEN_DIRECTORY 3
-#endif
-
-#ifndef __SLICK__
#define _PASSWD_FILE "/etc/master.passwd"
-#else
-#define _PASSWD_FILE "/etc/passwd"
-#endif
#include <stdio.h>
#include <errno.h>
#include <libc.h>
#include <ctype.h>
#include <string.h>
-#include "stringops.h"
+#include "passwd.h"
#ifdef __SLICK__
#define _PASSWORD_LEN 8
static char *saltchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
-extern int file_passwd(char *, char *);
-extern int nis_passwd(char *, char *);
-#ifdef INFO_OPEN_DIRECTORY
-extern int od_passwd(char *, char *, char*);
-#endif
-
void
getpasswd(char *name, int isroot, int minlen, int mixcase, int nonalpha,
char *old_pw, char **new_pw, char **old_clear, char **new_clear)
{
- int i, tries, len, pw_ok, upper, lower, alpha, notalpha;
+ int i, tries, pw_ok, upper, lower, alpha, notalpha;
+ size_t len;
int isNull;
char *p;
static char obuf[_PASSWORD_LEN+1];
}
//strcpy(obuf, p);
snprintf( obuf, sizeof(obuf), "%s", p );
-
+
tries = 0;
nbuf[0] = '\0';
for (;;)
* An insistent root may override security options.
*/
if ((isroot == 1) && (tries > 2)) pw_ok = 1;
-
+
/*
* A very insistent user may override security options.
*/
if (tries > 4) pw_ok = 1;
-
+
if (pw_ok == 0)
{
if (len < minlen)
//strcpy(nbuf, p);
snprintf( nbuf, sizeof(nbuf), "%s", p );
-
+
if (!strcmp(nbuf, getpass("Retype new password:"))) break;
printf("Mismatch; try again, EOF to quit.\n");
return;
}
-void
-usage()
+static void
+usage(void)
{
- fprintf(stderr, "usage: %s [-i infosystem] [-l location] [-u authname] [name]\n", progname);
+ fprintf(stderr, "usage: %s [-i infosystem] -l location]] [-u authname] [name]\n", progname);
fprintf(stderr, " infosystem:\n");
fprintf(stderr, " file\n");
fprintf(stderr, " NIS\n");
fprintf(stderr, " OpenDirectory\n");
+ fprintf(stderr, " PAM\n");
fprintf(stderr, " location (for infosystem):\n");
fprintf(stderr, " file location is path to file (default is %s)\n", _PASSWD_FILE);
fprintf(stderr, " NIS location is NIS domain name\n");
fprintf(stderr, " OpenDirectory location is directory node name\n");
+ fprintf(stderr, " PAM location is not used\n");
exit(1);
}
char* auth = NULL;
int infosystem, ch;
int free_user = 0;
-
+
+#ifdef INFO_PAM
+ infosystem = INFO_PAM;
+#else
#ifdef INFO_OPEN_DIRECTORY
- /* since OpenDirectory works for most infosystems, make it the default */
infosystem = INFO_OPEN_DIRECTORY;
#else
infosystem = INFO_FILE;
#endif
-
+#endif
+
+#ifdef INFO_OPEN_DIRECTORY
+ /* PAM is the default infosystem, but we still want to use OpenDirectory directly when run by root */
+ if (0 == getuid())
+ infosystem = INFO_OPEN_DIRECTORY;
+#endif
+
while ((ch = getopt(argc, argv, "i:l:u:")) != -1)
switch(ch) {
case 'i':
if (!strcasecmp(optarg, "file")) {
infosystem = INFO_FILE;
+#ifdef INFO_NIS
} else if (!strcasecmp(optarg, "NIS")) {
infosystem = INFO_NIS;
} else if (!strcasecmp(optarg, "YP")) {
infosystem = INFO_NIS;
+#endif
#ifdef INFO_OPEN_DIRECTORY
} else if (!strcasecmp(optarg, "opendirectory")) {
infosystem = INFO_OPEN_DIRECTORY;
+#endif
+#ifdef INFO_PAM
+ } else if (!strcasecmp(optarg, "PAM")) {
+ infosystem = INFO_PAM;
#endif
} else {
fprintf(stderr, "%s: Unknown info system \'%s\'.\n",
user = argv[0];
}
+#ifdef INFO_PAM
+ if (INFO_PAM == infosystem && NULL != locn)
+ usage();
+#endif
+
if (user == NULL)
{
/*
* Verify that the login name exists.
* lukeh 24 Dec 1997
*/
-
+
/* getlogin() is the wrong thing to use here because it returns the wrong user after su */
/* sns 5 Jan 2005 */
-
+
struct passwd * userRec = getpwuid(getuid());
if (userRec != NULL && userRec->pw_name != NULL) {
/* global static mem is volatile; must strdup */
user = strdup(userRec->pw_name);
free_user = 1;
}
-
+
if (user == NULL)
{
fprintf(stderr, "you don't have a login name\n");
exit(1);
}
}
-
+
switch (infosystem)
{
case INFO_FILE:
file_passwd(user, locn);
break;
+#ifdef INFO_NIS
case INFO_NIS:
nis_passwd(user, locn);
break;
+#endif
#ifdef INFO_OPEN_DIRECTORY
case INFO_OPEN_DIRECTORY:
od_passwd(user, locn, auth);
break;
+#endif
+#ifdef INFO_PAM
+ case INFO_PAM:
+ pam_passwd(user);
+ break;
#endif
}
-
+
if (free_user == 1)
free(user);
-
+
exit(0);
}
-