]>
git.saurik.com Git - apple/system_cmds.git/blob - passwd.tproj/passwd.c
2 * Copyright (c) 1999-2016 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 #include <TargetConditionals.h>
25 #define _PASSWD_FILE "/etc/master.passwd"
36 #define _PASSWORD_LEN 8
39 char* progname
= "passwd";
41 static char *saltchars
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
44 getpasswd(char *name
, int isroot
, int minlen
, int mixcase
, int nonalpha
,
45 char *old_pw
, char **new_pw
, char **old_clear
, char **new_clear
)
47 int i
, tries
, pw_ok
, upper
, lower
, alpha
, notalpha
;
51 static char obuf
[_PASSWORD_LEN
+1];
52 static char nbuf
[_PASSWORD_LEN
+1];
55 printf("Changing password for %s.\n", name
);
59 if (old_pw
== NULL
) isNull
= 1;
60 if ((isNull
== 0) && (old_pw
[0] == '\0')) isNull
= 1;
61 if ((isroot
== 0) && (isNull
== 0))
63 p
= getpass("Old password:");
64 if (strcmp(crypt(p
, old_pw
), old_pw
))
67 fprintf(stderr
, "Sorry\n");
72 snprintf( obuf
, sizeof(obuf
), "%s", p
);
78 p
= getpass("New password:");
81 printf("Password unchanged.\n");
91 for (i
= 0; i
< len
; i
++)
93 if (isupper(p
[i
])) upper
++;
94 if (islower(p
[i
])) lower
++;
95 if (isalpha(p
[i
])) alpha
++;
101 if (len
< minlen
) pw_ok
= 0;
102 if ((mixcase
== 1) && ((upper
== 0) || (lower
== 0))) pw_ok
= 0;
103 if ((nonalpha
== 1) && (notalpha
== 0)) pw_ok
= 0;
106 * An insistent root may override security options.
108 if ((isroot
== 1) && (tries
> 2)) pw_ok
= 1;
111 * A very insistent user may override security options.
113 if (tries
> 4) pw_ok
= 1;
118 printf("Password must be at least %d characters long.\n", minlen
);
119 if ((mixcase
== 1) && ((upper
== 0) || (lower
== 0)))
120 printf("Password must contain both upper and lower case characters.\n");
121 if ((nonalpha
== 1) && (notalpha
== 0))
122 printf("Password must contain non-alphabetic characters.\n");
127 snprintf( nbuf
, sizeof(nbuf
), "%s", p
);
129 if (!strcmp(nbuf
, getpass("Retype new password:"))) break;
131 printf("Mismatch; try again, EOF to quit.\n");
135 * Create a random salt
137 srandom((int)time((time_t *)NULL
));
138 salt
[0] = saltchars
[random() % strlen(saltchars
)];
139 salt
[1] = saltchars
[random() % strlen(saltchars
)];
141 *new_pw
= crypt(nbuf
, salt
);
151 fprintf(stderr
, "usage: %s [-i infosystem] -l location]] [-u authname] [name]\n", progname
);
152 fprintf(stderr
, " infosystem:\n");
153 fprintf(stderr
, " file\n");
154 fprintf(stderr
, " NIS\n");
155 fprintf(stderr
, " OpenDirectory\n");
156 fprintf(stderr
, " PAM\n");
157 fprintf(stderr
, " location (for infosystem):\n");
158 fprintf(stderr
, " file location is path to file (default is %s)\n", _PASSWD_FILE
);
159 fprintf(stderr
, " NIS location is NIS domain name\n");
160 fprintf(stderr
, " OpenDirectory location is directory node name\n");
161 fprintf(stderr
, " PAM location is not used\n");
166 main(int argc
, char *argv
[])
175 infosystem
= INFO_PAM
;
177 #ifdef INFO_OPEN_DIRECTORY
178 infosystem
= INFO_OPEN_DIRECTORY
;
180 infosystem
= INFO_FILE
;
184 #ifdef INFO_OPEN_DIRECTORY
185 /* PAM is the default infosystem, but we still want to use OpenDirectory directly when run by root */
187 infosystem
= INFO_OPEN_DIRECTORY
;
190 while ((ch
= getopt(argc
, argv
, "i:l:u:")) != -1)
193 if (!strcasecmp(optarg
, "file")) {
194 infosystem
= INFO_FILE
;
196 } else if (!strcasecmp(optarg
, "NIS")) {
197 infosystem
= INFO_NIS
;
198 } else if (!strcasecmp(optarg
, "YP")) {
199 infosystem
= INFO_NIS
;
201 #ifdef INFO_OPEN_DIRECTORY
202 } else if (!strcasecmp(optarg
, "opendirectory")) {
203 infosystem
= INFO_OPEN_DIRECTORY
;
206 } else if (!strcasecmp(optarg
, "PAM")) {
207 infosystem
= INFO_PAM
;
210 fprintf(stderr
, "%s: Unknown info system \'%s\'.\n",
231 } else if (argc
== 1) {
236 if (INFO_PAM
== infosystem
&& NULL
!= locn
)
243 * Verify that the login name exists.
247 /* getlogin() is the wrong thing to use here because it returns the wrong user after su */
250 struct passwd
* userRec
= getpwuid(getuid());
251 if (userRec
!= NULL
&& userRec
->pw_name
!= NULL
) {
252 /* global static mem is volatile; must strdup */
253 user
= strdup(userRec
->pw_name
);
259 fprintf(stderr
, "you don't have a login name\n");
267 file_passwd(user
, locn
);
271 nis_passwd(user
, locn
);
274 #ifdef INFO_OPEN_DIRECTORY
275 case INFO_OPEN_DIRECTORY
:
276 od_passwd(user
, locn
, auth
);