]>
git.saurik.com Git - apple/system_cmds.git/blob - passwd.tproj/passwd.c
2 * Copyright (c) 1999-2006 Apple Computer, 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>
26 #if !TARGET_OS_EMBEDDED
28 #define INFO_OPEN_DIRECTORY 3
32 #define _PASSWD_FILE "/etc/master.passwd"
34 #define _PASSWD_FILE "/etc/passwd"
43 #include "stringops.h"
46 #define _PASSWORD_LEN 8
49 char* progname
= "passwd";
51 static char *saltchars
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
53 extern int file_passwd(char *, char *);
54 extern int nis_passwd(char *, char *);
55 #ifdef INFO_OPEN_DIRECTORY
56 extern int od_passwd(char *, char *, char*);
60 getpasswd(char *name
, int isroot
, int minlen
, int mixcase
, int nonalpha
,
61 char *old_pw
, char **new_pw
, char **old_clear
, char **new_clear
)
63 int i
, tries
, len
, pw_ok
, upper
, lower
, alpha
, notalpha
;
66 static char obuf
[_PASSWORD_LEN
+1];
67 static char nbuf
[_PASSWORD_LEN
+1];
70 printf("Changing password for %s.\n", name
);
74 if (old_pw
== NULL
) isNull
= 1;
75 if ((isNull
== 0) && (old_pw
[0] == '\0')) isNull
= 1;
76 if ((isroot
== 0) && (isNull
== 0))
78 p
= getpass("Old password:");
79 if (strcmp(crypt(p
, old_pw
), old_pw
))
82 fprintf(stderr
, "Sorry\n");
87 snprintf( obuf
, sizeof(obuf
), "%s", p
);
93 p
= getpass("New password:");
96 printf("Password unchanged.\n");
106 for (i
= 0; i
< len
; i
++)
108 if (isupper(p
[i
])) upper
++;
109 if (islower(p
[i
])) lower
++;
110 if (isalpha(p
[i
])) alpha
++;
116 if (len
< minlen
) pw_ok
= 0;
117 if ((mixcase
== 1) && ((upper
== 0) || (lower
== 0))) pw_ok
= 0;
118 if ((nonalpha
== 1) && (notalpha
== 0)) pw_ok
= 0;
121 * An insistent root may override security options.
123 if ((isroot
== 1) && (tries
> 2)) pw_ok
= 1;
126 * A very insistent user may override security options.
128 if (tries
> 4) pw_ok
= 1;
133 printf("Password must be at least %d characters long.\n", minlen
);
134 if ((mixcase
== 1) && ((upper
== 0) || (lower
== 0)))
135 printf("Password must contain both upper and lower case characters.\n");
136 if ((nonalpha
== 1) && (notalpha
== 0))
137 printf("Password must contain non-alphabetic characters.\n");
142 snprintf( nbuf
, sizeof(nbuf
), "%s", p
);
144 if (!strcmp(nbuf
, getpass("Retype new password:"))) break;
146 printf("Mismatch; try again, EOF to quit.\n");
150 * Create a random salt
152 srandom((int)time((time_t *)NULL
));
153 salt
[0] = saltchars
[random() % strlen(saltchars
)];
154 salt
[1] = saltchars
[random() % strlen(saltchars
)];
156 *new_pw
= crypt(nbuf
, salt
);
166 fprintf(stderr
, "usage: %s [-i infosystem] [-l location] [-u authname] [name]\n", progname
);
167 fprintf(stderr
, " infosystem:\n");
168 fprintf(stderr
, " file\n");
169 fprintf(stderr
, " NIS\n");
170 fprintf(stderr
, " OpenDirectory\n");
171 fprintf(stderr
, " location (for infosystem):\n");
172 fprintf(stderr
, " file location is path to file (default is %s)\n", _PASSWD_FILE
);
173 fprintf(stderr
, " NIS location is NIS domain name\n");
174 fprintf(stderr
, " OpenDirectory location is directory node name\n");
179 main(int argc
, char *argv
[])
187 #ifdef INFO_OPEN_DIRECTORY
188 /* since OpenDirectory works for most infosystems, make it the default */
189 infosystem
= INFO_OPEN_DIRECTORY
;
191 infosystem
= INFO_FILE
;
194 while ((ch
= getopt(argc
, argv
, "i:l:u:")) != -1)
197 if (!strcasecmp(optarg
, "file")) {
198 infosystem
= INFO_FILE
;
200 } else if (!strcasecmp(optarg
, "NIS")) {
201 infosystem
= INFO_NIS
;
202 } else if (!strcasecmp(optarg
, "YP")) {
203 infosystem
= INFO_NIS
;
205 #ifdef INFO_OPEN_DIRECTORY
206 } else if (!strcasecmp(optarg
, "opendirectory")) {
207 infosystem
= INFO_OPEN_DIRECTORY
;
210 fprintf(stderr
, "%s: Unknown info system \'%s\'.\n",
231 } else if (argc
== 1) {
238 * Verify that the login name exists.
242 /* getlogin() is the wrong thing to use here because it returns the wrong user after su */
245 struct passwd
* userRec
= getpwuid(getuid());
246 if (userRec
!= NULL
&& userRec
->pw_name
!= NULL
) {
247 /* global static mem is volatile; must strdup */
248 user
= strdup(userRec
->pw_name
);
254 fprintf(stderr
, "you don't have a login name\n");
262 file_passwd(user
, locn
);
266 nis_passwd(user
, locn
);
269 #ifdef INFO_OPEN_DIRECTORY
270 case INFO_OPEN_DIRECTORY
:
271 od_passwd(user
, locn
, auth
);