diff options
Diffstat (limited to 'system_cmds/chkpasswd.tproj')
-rw-r--r-- | system_cmds/chkpasswd.tproj/chkpasswd.8 | 59 | ||||
-rw-r--r-- | system_cmds/chkpasswd.tproj/chkpasswd.pam | 5 | ||||
-rw-r--r-- | system_cmds/chkpasswd.tproj/file_passwd.c | 276 | ||||
-rw-r--r-- | system_cmds/chkpasswd.tproj/nis_passwd.c | 210 | ||||
-rw-r--r-- | system_cmds/chkpasswd.tproj/od_passwd.c | 105 | ||||
-rw-r--r-- | system_cmds/chkpasswd.tproj/pam_passwd.c | 81 | ||||
-rw-r--r-- | system_cmds/chkpasswd.tproj/passwd.c | 174 | ||||
-rw-r--r-- | system_cmds/chkpasswd.tproj/passwd.h | 5 | ||||
-rw-r--r-- | system_cmds/chkpasswd.tproj/stringops.c | 261 | ||||
-rw-r--r-- | system_cmds/chkpasswd.tproj/stringops.h | 39 |
10 files changed, 1215 insertions, 0 deletions
diff --git a/system_cmds/chkpasswd.tproj/chkpasswd.8 b/system_cmds/chkpasswd.tproj/chkpasswd.8 new file mode 100644 index 0000000..fd6c4f2 --- /dev/null +++ b/system_cmds/chkpasswd.tproj/chkpasswd.8 @@ -0,0 +1,59 @@ +.Dd July 20, 2004 +.Dt CHKPASSWD 8 +.Os Darwin +.Sh NAME +.Nm chkpasswd +.Nd verifies user password against various systems +.Sh SYNOPSIS +.Nm chkpasswd +.Op Fl i Ar infosystem Op Fl l Ar location +.Op Fl c +.Op Ar name +.Sh DESCRIPTION +.Nm chkpasswd +verifies a supplied username and password against file, NIS, +or OpenDirectory infosystems. +.Pp +The options are as follows: +.Bl -tag -width Ds +.\" ========== +.It Fl c +The supplied password is compared verbatim without first being encrypted. +.\" ========== +.It Fl i Ar infosystem +Specify the system against which to check the password +(default is PAM). Valid systems: +.Bl -tag -width "opendirectory" +.It Ar file +File-based passwords +.It Ar nis +NIS/YP authentication +.It Ar opendirectory +OpenDirectory (Directory Services) authentication. +If no +.Fl l +option is specified, the search node is used. +.It Ar PAM +Pluggable Authentication Modules +.El +.Pp +.\" ========== +.It Fl l Ar location +Specify a location; varies based on infosystem type: +.Bl -tag -width "for opendirectory" +.It for file +Filename (default: /etc/master.passwd). +.It for nis +NIS domainname. +.It for opendirectory +A directory node name such as /Local/Default. +.It for PAM +Unused. +.El +.Pp +.El +.Ar name +username +.Sh SEE ALSO +.Xr dscl 1 , +.Xr passwd 5 diff --git a/system_cmds/chkpasswd.tproj/chkpasswd.pam b/system_cmds/chkpasswd.tproj/chkpasswd.pam new file mode 100644 index 0000000..18404e6 --- /dev/null +++ b/system_cmds/chkpasswd.tproj/chkpasswd.pam @@ -0,0 +1,5 @@ +# chkpasswd: auth account +auth required pam_opendirectory.so +account required pam_opendirectory.so +password required pam_permit.so +session required pam_permit.so diff --git a/system_cmds/chkpasswd.tproj/file_passwd.c b/system_cmds/chkpasswd.tproj/file_passwd.c new file mode 100644 index 0000000..90f54f2 --- /dev/null +++ b/system_cmds/chkpasswd.tproj/file_passwd.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 1999-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights + * Reserved. 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 1.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.apple.com/publicsource 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, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License." + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <pwd.h> +#include <errno.h> +#include <string.h> +#include "stringops.h" + +#define TEMP_FILE "/tmp/.pwtmp" + +#define _PASSWD_FILE "/etc/master.passwd" +#define _COMPAT_FILE "/etc/passwd" +#define _PASSWD_FIELDS 10 +#define BUFSIZE 8192 + +#include "passwd.h" + +static char * +_getline(FILE *fp) +{ + static char s[BUFSIZE]; + size_t len; + + s[0] = '\0'; + + fgets(s, BUFSIZE, fp); + if (s[0] == '\0') return NULL; + + if (s[0] == '#') return s; + + len = strlen(s) - 1; + s[len] = '\0'; + + return s; +} + +static struct passwd * +parse_user(char *line) +{ + static struct passwd pw = {0}; + char **tokens; + int i, len; + + if (pw.pw_name != NULL) free(pw.pw_name); + pw.pw_name = NULL; + if (pw.pw_passwd != NULL) free(pw.pw_passwd); + pw.pw_passwd = NULL; + if (pw.pw_gecos != NULL) free(pw.pw_gecos); + pw.pw_gecos = NULL; + if (pw.pw_dir != NULL) free(pw.pw_dir); + pw.pw_dir = NULL; + if (pw.pw_shell != NULL) free(pw.pw_shell); + pw.pw_shell = NULL; + + if (pw.pw_class != NULL) free(pw.pw_class); + pw.pw_class = NULL; + + if (line == NULL) return (struct passwd *)NULL; + tokens = explode(line, ':'); + len = listLength(tokens); + + if (len != _PASSWD_FIELDS) + { + freeList(tokens); + return (struct passwd *)NULL; + } + + i = 0; + pw.pw_name = tokens[i++]; + pw.pw_passwd = tokens[i++]; + pw.pw_uid = atoi(tokens[i]); + free(tokens[i++]); + pw.pw_gid = atoi(tokens[i]); + free(tokens[i++]); + pw.pw_class = tokens[i++]; + pw.pw_change = atoi(tokens[i]); + free(tokens[i++]); + pw.pw_expire = atoi(tokens[i]); + free(tokens[i++]); + pw.pw_gecos = tokens[i++]; + pw.pw_dir = tokens[i++]; + pw.pw_shell = tokens[i++]; + + return &pw; +} + +static struct passwd * +find_user(char *uname, FILE *fp) +{ + char *line; + struct passwd *pw; + + rewind(fp); + + while (NULL != (line = _getline(fp))) + { + if (line[0] == '#') continue; + pw = parse_user(line); + if (pw == (struct passwd *)NULL) continue; + if (!strcmp(uname, pw->pw_name)) return pw; + } + + pw = parse_user(NULL); + return (struct passwd *)NULL; +} + +#if 0 +static void +rewrite_file(char *pwname, FILE *fp, struct passwd *newpw) +{ + char *line; + struct passwd *pw; + FILE *tfp, *cfp; + char fname[256]; + + sprintf(fname, "%s.%d", TEMP_FILE, getpid()); + + tfp = fopen(fname, "w+"); + if (tfp == NULL) + { + fprintf(stderr, "can't write temporary file \"%s\": ", fname); + perror(""); + exit(1); + } + + cfp = NULL; + if (!strcmp(pwname, _PASSWD_FILE)) + { + cfp = fopen(_COMPAT_FILE, "w"); + if (cfp == NULL) + { + fprintf(stderr, "warning: can't write compatability file \"%s\": ", + _COMPAT_FILE); + perror(""); + } + } + + if (cfp != NULL) + { + fprintf(cfp, "#\n"); + fprintf(cfp, "# 4.3BSD-compatable User Database\n"); + fprintf(cfp, "#\n"); + fprintf(cfp, "# Note that this file is not consulted for login.\n"); + fprintf(cfp, "# It only exisits for compatability with 4.3BSD utilities.\n"); + fprintf(cfp, "#\n"); + fprintf(cfp, "# This file is automatically re-written by various system utilities.\n"); + fprintf(cfp, "# Do not edit this file. Changes will be lost.\n"); + fprintf(cfp, "#\n"); + } + + rewind(fp); + + while (NULL != (line = _getline(fp))) + { + if (line[0] == '#') + { + fprintf(tfp, "%s", line); + continue; + } + + pw = parse_user(line); + if (pw == (struct passwd *)NULL) + { + fprintf(stderr, "warning: bad format for entry: \"%s\"\n", line); + fprintf(tfp, "%s\n", line); + if (cfp != NULL) fprintf(cfp, "%s\n", line); + continue; + } + + if (strcmp(newpw->pw_name, pw->pw_name)) + { + fprintf(tfp, "%s\n", line); + if (cfp != NULL) fprintf(cfp, "%s\n", line); + continue; + } + + fprintf(tfp, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n", + newpw->pw_name, newpw->pw_passwd, newpw->pw_uid, newpw->pw_gid, + newpw->pw_class, newpw->pw_change, newpw->pw_expire, + newpw->pw_gecos, newpw->pw_dir, newpw->pw_shell); + if (cfp != NULL) + { + fprintf(cfp, "%s:",newpw->pw_name); + if ((newpw->pw_passwd == NULL) || (newpw->pw_passwd[0] == '\0')) + fprintf(cfp, ":"); + else + fprintf(cfp, "*:"); + fprintf(cfp, "%d:%d:%s:%s:%s\n", + newpw->pw_uid, newpw->pw_gid, newpw->pw_gecos, + newpw->pw_dir, newpw->pw_shell); + } + } + + if (cfp != NULL) fclose(cfp); + fclose(fp); + if (unlink(pwname) < 0) + { + fprintf(stderr, "can't update \"%s\": ", pwname); + perror(""); + } + + rewind(tfp); + + fp = fopen(pwname, "w"); + if (fp == NULL) + { + fprintf(stderr, "ERROR: lost file \"%s\"\n", pwname); + fprintf(stderr, "new passwd file is \"%s\"\n", fname); + perror("open"); + exit(1); + } + + while (NULL != (line = _getline(tfp))) + { + fprintf(fp, "%s", line); + if (line[0] != '#') fprintf(fp, "\n"); + } + fclose(fp); + fclose(tfp); + unlink(fname); +} +#endif /* 0 */ + +int +file_check_passwd(char *uname, char *locn) +{ + FILE *fp; + char *fname; + struct passwd *pw; + + fname = _PASSWD_FILE; + if (locn != NULL) fname = locn; + + if (access(fname,R_OK) || (fp = fopen(fname, "r")) == NULL) + { + fprintf(stderr, "can't read file \"%s\": ", fname); + perror(""); + exit(1); + } + + + pw = find_user(uname, fp); + if (pw == (struct passwd *)NULL) + { + fprintf(stderr, "user %s not found in file %s\n", uname, fname); + exit(1); + } + + checkpasswd(uname, pw->pw_passwd); + fclose(fp); + + return 0; +} diff --git a/system_cmds/chkpasswd.tproj/nis_passwd.c b/system_cmds/chkpasswd.tproj/nis_passwd.c new file mode 100644 index 0000000..c2e6e4f --- /dev/null +++ b/system_cmds/chkpasswd.tproj/nis_passwd.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 1999-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights + * Reserved. 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 1.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.apple.com/publicsource 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, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License." + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1998 by Apple Computer, Inc. + * Portions Copyright (c) 1988 by Sun Microsystems, Inc. + * Portions Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +/* update a user's password in NIS. This was based on the Sun implementation + * we used in NEXTSTEP, although I've added some stuff from OpenBSD. And + * it uses the API to support Rhapsody's proprietry infosystem switch. + * lukeh + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <pwd.h> +#include <netinet/in.h> +#include <rpc/rpc.h> +#include <rpc/xdr.h> +#include <rpc/pmap_clnt.h> +#include <rpcsvc/yp_prot.h> +#include <rpcsvc/ypclnt.h> +#include <rpcsvc/yppasswd.h> +#include <netdb.h> +#include <sys/socket.h> +#include <sys/file.h> +#include <errno.h> + +#include "passwd.h" + +static struct passwd *ypgetpwnam(char *name, char *domain); + +int +nis_check_passwd(char *uname, char *domain) +{ + int port; + char *master; + struct passwd *pwd; + + if (domain == NULL) + { + if (yp_get_default_domain(&domain) != 0) + { + (void)fprintf(stderr, "can't get domain\n"); + exit(1); + } + } + + if (yp_master(domain, "passwd.byname", &master) != 0) + { + (void)fprintf(stderr, "can't get master for passwd file\n"); + exit(1); + } + + port = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, + IPPROTO_UDP); + if (port == 0) + { + (void)fprintf(stderr, "%s is not running yppasswd daemon\n", + master); + exit(1); + } + if (port >= IPPORT_RESERVED) + { + (void)fprintf(stderr, + "yppasswd daemon is not running on privileged port\n"); + exit(1); + } + + pwd = ypgetpwnam(uname, domain); + if (pwd == NULL) + { + (void)fprintf(stderr, "user %s not found\n", uname); + exit(1); + } + + checkpasswd(uname, pwd->pw_passwd); + return(0); +} + +static char * +pwskip(register char *p) +{ + while (*p && *p != ':' && *p != '\n') + ++p; + if (*p) + *p++ = 0; + return (p); +} + +static struct passwd * +interpret(struct passwd *pwent, char *line) +{ + register char *p = line; + + pwent->pw_passwd = "*"; + pwent->pw_uid = 0; + pwent->pw_gid = 0; + pwent->pw_gecos = ""; + pwent->pw_dir = ""; + pwent->pw_shell = ""; +#ifndef __SLICK__ + pwent->pw_change = 0; + pwent->pw_expire = 0; + pwent->pw_class = ""; +#endif + + /* line without colon separators is no good, so ignore it */ + if(!strchr(p, ':')) + return(NULL); + + pwent->pw_name = p; + p = pwskip(p); + pwent->pw_passwd = p; + p = pwskip(p); + pwent->pw_uid = (uid_t)strtoul(p, NULL, 10); + p = pwskip(p); + pwent->pw_gid = (gid_t)strtoul(p, NULL, 10); + p = pwskip(p); + pwent->pw_gecos = p; + p = pwskip(p); + pwent->pw_dir = p; + p = pwskip(p); + pwent->pw_shell = p; + while (*p && *p != '\n') + p++; + *p = '\0'; + return (pwent); +} + +static struct passwd * +ypgetpwnam(char *nam, char *domain) +{ + static struct passwd pwent; + char *val; + int reason, vallen; + static char *__yplin = NULL; + + reason = yp_match(domain, "passwd.byname", nam, (int)strlen(nam), + &val, &vallen); + switch(reason) { + case 0: + break; + default: + return (NULL); + break; + } + val[vallen] = '\0'; + if (__yplin) + free(__yplin); + __yplin = (char *)malloc(vallen + 1); + strcpy(__yplin, val); + free(val); + + return(interpret(&pwent, __yplin)); +} diff --git a/system_cmds/chkpasswd.tproj/od_passwd.c b/system_cmds/chkpasswd.tproj/od_passwd.c new file mode 100644 index 0000000..2ea724f --- /dev/null +++ b/system_cmds/chkpasswd.tproj/od_passwd.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1998-2016 Apple Inc. All rights reserved. + * Portions Copyright (c) 1988 by Sun Microsystems, Inc. + * Portions Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <pwd.h> +#include <netinet/in.h> +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/rpc.h> +#include <rpcsvc/yp_prot.h> +#include <rpcsvc/ypclnt.h> +#include <rpcsvc/yppasswd.h> +#include <netdb.h> +#include <sys/socket.h> +#include <sys/file.h> +#include <errno.h> + +#include <OpenDirectory/OpenDirectory.h> + +#include "passwd.h" + +//------------------------------------------------------------------------------------- +// od_check_passwd +//------------------------------------------------------------------------------------- + +int +od_check_passwd(const char *uname, const char *domain) +{ + int authenticated = 0; + + ODSessionRef session = NULL; + ODNodeRef node = NULL; + ODRecordRef rec = NULL; + CFStringRef user = NULL; + CFStringRef location = NULL; + CFStringRef password = NULL; + + if (uname) user = CFStringCreateWithCString(NULL, uname, kCFStringEncodingUTF8); + if (domain) location = CFStringCreateWithCString(NULL, domain, kCFStringEncodingUTF8); + + if (user) { + printf("Checking password for %s.\n", uname); + char* p = getpass("Password:"); + if (p) password = CFStringCreateWithCString(NULL, p, kCFStringEncodingUTF8); + } + + if (password) { + session = ODSessionCreate(NULL, NULL, NULL); + if (session) { + if (location) { + node = ODNodeCreateWithName(NULL, session, location, NULL); + } else { + node = ODNodeCreateWithNodeType(NULL, session, kODNodeTypeAuthentication, NULL); + } + if (node) { + rec = ODNodeCopyRecord(node, kODRecordTypeUsers, user, NULL, NULL); + } + if (rec) { + authenticated = ODRecordVerifyPassword(rec, password, NULL); + } + } + } + + if (!authenticated) { + fprintf(stderr, "Sorry\n"); + exit(1); + } + + return 0; +} diff --git a/system_cmds/chkpasswd.tproj/pam_passwd.c b/system_cmds/chkpasswd.tproj/pam_passwd.c new file mode 100644 index 0000000..07d9919 --- /dev/null +++ b/system_cmds/chkpasswd.tproj/pam_passwd.c @@ -0,0 +1,81 @@ +/* + * 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, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * 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 <stdio.h> + +#include <security/pam_appl.h> +#include <security/openpam.h> /* for openpam_ttyconv() */ + +#include "passwd.h" + +extern char* progname; +static pam_handle_t *pamh; +static struct pam_conv pamc; + +//------------------------------------------------------------------------------------- +// pam_check_passwd +//------------------------------------------------------------------------------------- + +int +pam_check_passwd(char* uname) +{ + int retval = PAM_SUCCESS; + + /* Initialize PAM. */ + pamc.conv = &openpam_ttyconv; + pam_start(progname, uname, &pamc, &pamh); + + printf("Checking password for %s.\n", uname); + + /* Authenticate. */ + if (PAM_SUCCESS != (retval = pam_authenticate(pamh, 0))) + goto pamerr; + + /* Authorize. */ + if (PAM_SUCCESS != (retval = pam_acct_mgmt(pamh, 0)) && PAM_NEW_AUTHTOK_REQD != retval) + goto pamerr; + + /* Change the password. */ + if (PAM_NEW_AUTHTOK_REQD == retval && PAM_SUCCESS != (retval = pam_chauthtok(pamh, 0))) + goto pamerr; + + /* Set the credentials. */ + if (PAM_SUCCESS != (retval = pam_setcred(pamh, PAM_ESTABLISH_CRED))) + goto pamerr; + + /* Open the session. */ + if (PAM_SUCCESS != (retval = pam_open_session(pamh, 0))) + goto pamerr; + + /* Close the session. */ + if (PAM_SUCCESS != (retval = pam_close_session(pamh, 0))) + goto pamerr; + +pamerr: + /* Print an error, if needed. */ + if (PAM_SUCCESS != retval) + fprintf(stderr, "Sorry\n"); + + /* Terminate PAM. */ + pam_end(pamh, retval); + return retval; +} diff --git a/system_cmds/chkpasswd.tproj/passwd.c b/system_cmds/chkpasswd.tproj/passwd.c new file mode 100644 index 0000000..bff8280 --- /dev/null +++ b/system_cmds/chkpasswd.tproj/passwd.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 1999-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights + * Reserved. 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 1.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.apple.com/publicsource 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, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License." + * + * @APPLE_LICENSE_HEADER_END@ + */ +#define INFO_FILE 1 +#define INFO_NIS 2 +#define INFO_OPEN_DIRECTORY 3 +#define INFO_PAM 4 + +#ifndef __SLICK__ +#define _PASSWD_FILE "/etc/master.passwd" +#else +#define _PASSWD_FILE "/etc/passwd" +#endif + +#include <stdio.h> +#include <errno.h> +#include <pwd.h> +#include <libc.h> +#include <ctype.h> +#include <string.h> +#include <pwd.h> +#include "stringops.h" + +#ifdef __SLICK__ +#define _PASSWORD_LEN 8 +#endif + +#include "passwd.h" + +const char* progname = "chkpasswd"; + +static int literal = 0; + +void +checkpasswd(char *name, char *old_pw) +{ + int isNull; + char *p; + + printf("Checking password for %s.\n", name); + + p = ""; + isNull = 0; + if (old_pw == NULL) isNull = 1; + if ((isNull == 0) && (old_pw[0] == '\0')) isNull = 1; + if (isNull == 0) + { + p = getpass("Password:"); + sleep(1); // make sure this doesn't go too quickly + if (strcmp(literal ? p : crypt(p, old_pw), old_pw)) + { + errno = EACCES; + fprintf(stderr, "Sorry\n"); + exit(1); + } + } + return; +} + +static void +usage(void) +{ + fprintf(stderr, "usage: chkpasswd [-i infosystem] [-l location] [-c] [name]\n"); + fprintf(stderr, " infosystem:\n"); + fprintf(stderr, " file\n"); + fprintf(stderr, " NIS\n"); + fprintf(stderr, " OpenDirectory\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, " -c: supplied password is compared verbatim without first\n"); + fprintf(stderr, " being crypted\n"); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + char* user = NULL; + char* locn = NULL; + int infosystem, ch; + + infosystem = INFO_PAM; + + while ((ch = getopt(argc, argv, "ci:l:")) != -1) { + switch(ch) { + case 'i': + if (!strcasecmp(optarg, "file")) { + infosystem = INFO_FILE; + } else if (!strcasecmp(optarg, "NIS")) { + infosystem = INFO_NIS; + } else if (!strcasecmp(optarg, "YP")) { + infosystem = INFO_NIS; + } else if (!strcasecmp(optarg, "opendirectory")) { + infosystem = INFO_OPEN_DIRECTORY; + } else if (!strcasecmp(optarg, "PAM")) { + infosystem = INFO_PAM; + } else { + fprintf(stderr, "%s: Unknown info system \'%s\'.\n", + progname, optarg); + usage(); + } + break; + case 'l': + locn = optarg; + break; + case 'c': + literal++; + break; + case '?': + default: + usage(); + break; + } + } + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + } else if (argc == 1) { + user = argv[0]; + } + + if (user == NULL) { + struct passwd* pw = getpwuid(getuid()); + if (pw != NULL && pw->pw_name != NULL) { + user = strdup(pw->pw_name); + } + if (user == NULL) { + fprintf(stderr, "you don't have a login name\n"); + exit(1); + } + } + + switch (infosystem) + { + case INFO_FILE: + file_check_passwd(user, locn); + break; + case INFO_NIS: + nis_check_passwd(user, locn); + break; + case INFO_OPEN_DIRECTORY: + od_check_passwd(user, locn); + break; + case INFO_PAM: + pam_check_passwd(user); + break; + } + + exit(0); +} diff --git a/system_cmds/chkpasswd.tproj/passwd.h b/system_cmds/chkpasswd.tproj/passwd.h new file mode 100644 index 0000000..692722b --- /dev/null +++ b/system_cmds/chkpasswd.tproj/passwd.h @@ -0,0 +1,5 @@ +int file_check_passwd(char *, char *); +int nis_check_passwd(char *, char *); +int od_check_passwd(const char *, const char *); +int pam_check_passwd(char *); +void checkpasswd(char *, char *); diff --git a/system_cmds/chkpasswd.tproj/stringops.c b/system_cmds/chkpasswd.tproj/stringops.c new file mode 100644 index 0000000..960ce19 --- /dev/null +++ b/system_cmds/chkpasswd.tproj/stringops.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 1999-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights + * Reserved. 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 1.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.apple.com/publicsource 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, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License." + * + * @APPLE_LICENSE_HEADER_END@ + */ +#import <string.h> +#import <stdlib.h> +#import <stdio.h> +#import <stdarg.h> +#import "stringops.h" + +char * +copyString(char *s) +{ + size_t len; + char *t; + + if (s == NULL) return NULL; + + len = strlen(s) + 1; + t = malloc(len); + bcopy(s, t, len); + return t; +} + +char * +concatString(char *s, char *t) +{ + size_t len; + + if (t == NULL) return s; + + len = strlen(s) + strlen(t) + 1; + s = realloc(s, len); + strcat(s, t); + return s; +} + +char ** +insertString(char *s, char **l, unsigned int x) +{ + int i, len; + + if (s == NULL) return l; + if (l == NULL) + { + l = (char **)malloc(2 * sizeof(char *)); + l[0] = copyString(s); + l[1] = NULL; + return l; + } + + for (i = 0; l[i] != NULL; i++); + len = i + 1; /* count the NULL on the end of the list too! */ + + l = (char **)realloc(l, (len + 1) * sizeof(char *)); + + if ((x >= (len - 1)) || (x == IndexNull)) + { + l[len - 1] = copyString(s); + l[len] = NULL; + return l; + } + + for (i = len; i > x; i--) l[i] = l[i - 1]; + l[x] = copyString(s); + return l; +} + +char ** +appendString(char *s, char **l) +{ + return insertString(s, l, IndexNull); +} + +void +freeList(char **l) +{ + int i; + + if (l == NULL) return; + for (i = 0; l[i] != NULL; i++) + { + if (l[i] != NULL) free(l[i]); + l[i] = NULL; + } + if (l != NULL) free(l); +} + +void +freeString(char *s) +{ + if (s == NULL) return; + free(s); +} + +unsigned int +listLength(char **l) +{ + int i; + + if (l == NULL) return 0; + for (i = 0; l[i] != NULL; i++); + return i; +} + +unsigned int +listIndex(char *s,char **l) +{ + int i; + + if (l == NULL) return IndexNull; + for (i = 0; l[i] != NULL; i++) + { + if (strcmp(s, l[i]) == 0) return i; + } + return IndexNull; +} + +char * +prefix(char *s, char c) +{ + int i; + char *t; + + if (s == NULL) return NULL; + + for (i = 0; ((s[i] != '\0') && (s[i] != c)); i++); + if (i == 0) return NULL; + if (s[i] == '\0') return copyString(s); + + t = malloc(i + 1); + bcopy(s, t, i); + t[i] = '\0'; + return t; +} + +char * +postfix(char *s, char c) +{ + int i; + size_t len; + char *t; + + if (s == NULL) return NULL; + + for (i = 0; ((s[i] != '\0') && (s[i] != c)); i++); + if (s[i] == '\0') return NULL; + len = strlen(s) - i; + if (len == 1) return NULL; + + t = malloc(len); + len--; + bcopy((s + i + 1), t, len); + t[len] = '\0'; + return t; +} + +char * +presuffix(char *s, char c) +{ + ssize_t i; + size_t len; + char *t; + + if (s == NULL) return NULL; + + len = strlen(s); + for (i = len - 1; ((i >= 0) && (s[i] != c)); i--); + if (i == 0) return NULL; + if (s[0] == '\0') return NULL; + + t = malloc(i + 1); + bcopy(s, t, i); + t[i] = '\0'; + return t; +} + +char * +suffix(char *s, char c) +{ + ssize_t i; + size_t len; + char *t; + + if (s == NULL) return NULL; + + len = strlen(s); + for (i = len - 1; ((i >= 0) && (s[i] != c)); i--); + if (i == 0) return NULL; + len -= i; + if (len == 1) return NULL; + t = malloc(len); + len--; + bcopy((s + i + 1), t, len); + t[len] = '\0'; + return t; +} + +char * +lowerCase(char *s) +{ + int i; + char *t; + + if (s == NULL) return NULL; + t = malloc(strlen(s) + 1); + + for (i = 0; s[i] != '\0'; i++) + { + if ((s[i] >= 'A') && (s[i] <= 'Z')) t[i] = s[i] + 32; + else t[i] = s[i]; + } + t[i] = '\0'; + return t; +} + +char ** +explode(char *s, char c) +{ + char **l = NULL; + char *p, *t; + int i, n; + + if (s == NULL) return NULL; + + p = s; + while (p[0] != '\0') + { + for (i = 0; ((p[i] != '\0') && p[i] != c); i++); + n = i; + t = malloc(n + 1); + for (i = 0; i < n; i++) t[i] = p[i]; + t[n] = '\0'; + l = appendString(t, l); + free(t); + t = NULL; + if (p[i] == '\0') return l; + if (p[i + 1] == '\0') l = appendString("", l); + p = p + i + 1; + } + return l; +} diff --git a/system_cmds/chkpasswd.tproj/stringops.h b/system_cmds/chkpasswd.tproj/stringops.h new file mode 100644 index 0000000..776adf6 --- /dev/null +++ b/system_cmds/chkpasswd.tproj/stringops.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1999-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights + * Reserved. 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 1.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.apple.com/publicsource 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, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License." + * + * @APPLE_LICENSE_HEADER_END@ + */ +#define streq(A, B) (strcmp(A, B) == 0) +#define IndexNull (unsigned int)-1 +char *copyString(char *); +char *concatString(char *, char *); +char **insertString(char *, char **, unsigned int); +char **appendString(char *, char **); +void freeList(char **); +void freeString(char *); +unsigned int listLength(char **); +unsigned int listIndex(char *,char **); +char *prefix(char *, char); +char *postfix(char *, char); +char *presuffix(char *, char); +char *suffix(char *, char); +char *lowerCase(char *); +char **explode(char *, char); |