]>
git.saurik.com Git - apple/system_cmds.git/blob - passwd.tproj/passwd.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
24 #define INFO_NETINFO 0
27 #define INFO_DIRECTORYSERVICES 3
30 #define _PASSWD_FILE "/etc/master.passwd"
32 #define _PASSWD_FILE "/etc/passwd"
41 #include <netinfo/ni.h>
42 #include "stringops.h"
45 #define _PASSWORD_LEN 8
48 static char *saltchars
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
50 extern int file_passwd(char *, char *);
51 extern int netinfo_passwd(char *, char *);
52 extern int nis_passwd(char *, char *);
53 extern int ds_passwd(char *, char *);
56 getpasswd(char *name
, int isroot
, int minlen
, int mixcase
, int nonalpha
,
57 char *old_pw
, char **new_pw
, char **old_clear
, char **new_clear
)
59 int i
, tries
, len
, pw_ok
, upper
, lower
, alpha
, notalpha
;
62 static char obuf
[_PASSWORD_LEN
+1];
63 static char nbuf
[_PASSWORD_LEN
+1];
66 printf("Changing password for %s.\n", name
);
70 if (old_pw
== NULL
) isNull
= 1;
71 if ((isNull
== 0) && (old_pw
[0] == '\0')) isNull
= 1;
72 if ((isroot
== 0) && (isNull
== 0))
74 p
= getpass("Old password:");
75 if (strcmp(crypt(p
, old_pw
), old_pw
))
78 fprintf(stderr
, "Sorry\n");
83 snprintf( obuf
, sizeof(obuf
), "%s", p
);
89 p
= getpass("New password:");
92 printf("Password unchanged.\n");
102 for (i
= 0; i
< len
; i
++)
104 if (isupper(p
[i
])) upper
++;
105 if (islower(p
[i
])) lower
++;
106 if (isalpha(p
[i
])) alpha
++;
112 if (len
< minlen
) pw_ok
= 0;
113 if ((mixcase
== 1) && ((upper
== 0) || (lower
== 0))) pw_ok
= 0;
114 if ((nonalpha
== 1) && (notalpha
== 0)) pw_ok
= 0;
117 * An insistent root may override security options.
119 if ((isroot
== 1) && (tries
> 2)) pw_ok
= 1;
122 * A very insistent user may override security options.
124 if (tries
> 4) pw_ok
= 1;
129 printf("Password must be at least %d characters long.\n", minlen
);
130 if ((mixcase
== 1) && ((upper
== 0) || (lower
== 0)))
131 printf("Password must contain both upper and lower case characters.\n");
132 if ((nonalpha
== 1) && (notalpha
== 0))
133 printf("Password must contain non-alphabetic characters.\n");
138 snprintf( nbuf
, sizeof(nbuf
), "%s", p
);
140 if (!strcmp(nbuf
, getpass("Retype new password:"))) break;
142 printf("Mismatch; try again, EOF to quit.\n");
146 * Create a random salt
148 srandom((int)time((time_t *)NULL
));
149 salt
[0] = saltchars
[random() % strlen(saltchars
)];
150 salt
[1] = saltchars
[random() % strlen(saltchars
)];
152 *new_pw
= crypt(nbuf
, salt
);
162 fprintf(stderr
, "usage: passwd [-i infosystem] [-l location] [name]\n");
163 fprintf(stderr
, "supported infosystems are:\n");
164 fprintf(stderr
, " netinfo\n");
165 fprintf(stderr
, " file\n");
166 fprintf(stderr
, " nis\n");
167 fprintf(stderr
, " opendirectory\n");
168 fprintf(stderr
, "for netinfo, location may be a domain name or server/tag\n");
169 fprintf(stderr
, "for file, location may be a file name (%s is the default)\n",
171 fprintf(stderr
, "for nis, location may be a NIS domainname\n");
172 fprintf(stderr
, "for opendirectory, location may be a directory node name\n");
177 main(int argc
, char *argv
[])
183 /* since DS works for most infosystems, make it the default */
184 //infosystem = INFO_NETINFO;
185 infosystem
= INFO_DIRECTORYSERVICES
;
189 for (i
= 1; i
< argc
; i
++)
191 if (!strcmp(argv
[i
], "-i"))
195 fprintf(stderr
, "no argument for -i option\n");
199 if (!strcmp(argv
[i
], "NetInfo")) infosystem
= INFO_NETINFO
;
200 else if (!strcmp(argv
[i
], "netinfo")) infosystem
= INFO_NETINFO
;
201 else if (!strcmp(argv
[i
], "File")) infosystem
= INFO_FILE
;
202 else if (!strcmp(argv
[i
], "file")) infosystem
= INFO_FILE
;
203 else if (!strcmp(argv
[i
], "NIS")) infosystem
= INFO_NIS
;
204 else if (!strcmp(argv
[i
], "nis")) infosystem
= INFO_NIS
;
205 else if (!strcmp(argv
[i
], "YP")) infosystem
= INFO_NIS
;
206 else if (!strcmp(argv
[i
], "yp")) infosystem
= INFO_NIS
;
207 else if (!strcasecmp(argv
[i
], "opendirectory")) infosystem
= INFO_DIRECTORYSERVICES
;
210 fprintf(stderr
, "unknown info system \"%s\"\n", argv
[i
]);
215 else if (!strcmp(argv
[i
], "-l"))
219 fprintf(stderr
, "no argument for -l option\n");
224 else if (user
== NULL
) user
= argv
[i
];
231 * Verify that the login name exists.
235 /* getlogin() is the wrong thing to use here because it returns the wrong user after su */
238 struct passwd
* userRec
= getpwuid(getuid());
239 if (userRec
!= NULL
&& userRec
->pw_name
!= NULL
) {
240 /* global static mem is volatile; must strdup */
241 user
= strdup(userRec
->pw_name
);
247 fprintf(stderr
, "you don't have a login name\n");
255 netinfo_passwd(user
, locn
);
258 file_passwd(user
, locn
);
261 nis_passwd(user
, locn
);
263 case INFO_DIRECTORYSERVICES
:
264 ds_passwd(user
, locn
);