aboutsummaryrefslogtreecommitdiffstats
path: root/system_cmds/chkpasswd.tproj/file_passwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'system_cmds/chkpasswd.tproj/file_passwd.c')
-rw-r--r--system_cmds/chkpasswd.tproj/file_passwd.c276
1 files changed, 276 insertions, 0 deletions
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;
+}