4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 * University Copyright- Copyright (c) 1982, 1986, 1988
31 * The Regents of the University of California
34 * University Acknowledgment- Portions of this document are derived from
35 * software developed by the University of California, Berkeley, and its
47 #include <sys/types.h>
50 #include <rpc/key_prot.h>
51 #include <rpcsvc/nis.h>
52 #include <rpcsvc/nis_dhext.h>
53 #include <rpcsvc/ypclnt.h>
60 #define CURMECH mechs[mcount]
61 #define DESCREDPASSLEN sizeof (des_block)
63 static char CRED_TABLE
[] = "cred.org_dir";
64 static char PKMAP
[] = "publickey.byname";
65 static char PKFILE
[] = "/etc/publickey";
66 #define MAXHOSTNAMELEN 256
68 #define ROOTKEY_FILE "/etc/.rootkey"
69 #define ROOTKEY_FILE_BACKUP "/etc/.rootkey.bak"
70 #define MAXROOTKEY_LINE_LEN 4224 /* Good upto 16384-bit keys */
71 #define MAXROOTKEY_LEN 4096
73 /* Should last up to 16384-bit keys */
74 #define MAXPKENTLEN 8500
76 bool_t makenew
= TRUE
; /* Make new keys or reencrypt existing */
77 bool_t specmech
= FALSE
; /* Specific mechs requested */
79 int dest_service
= 0; /* To which nameservice do we store key(s) */
83 mechanism_t
**mechs
= NULL
; /* List of DH mechanisms */
84 char **plist
= NULL
; /* List of public key(s) */
85 char **slist
= NULL
; /* List of secret key(s) */
86 char **clist
= NULL
; /* List of encrypted secret key(s) */
87 int numspecmech
= 0; /* Number of mechanisms specified */
89 struct passwd
*pw
= NULL
; /* passwd entry of user */
90 struct spwd
*spw
= NULL
; /* shadow entry of user */
92 char *netname
= NULL
; /* RPC netname of user */
93 char local_domain
[MAXNETNAMELEN
+ 1];
94 char *sec_domain
= NULL
;
96 char **rpc_pws
= NULL
; /* List of S-RPC passwords */
97 int rpc_pw_count
= 0; /* Number of passwords entered by user */
98 char *login_pw
= NULL
; /* Unencrypted login password */
99 char short_login_pw
[DESCREDPASSLEN
+ 1];
100 /* Short S-RPC password, which has first 8 chars of login_pw */
102 static int add_cred_obj(nis_object
*, char *);
103 static void cmp_passwd();
104 static void encryptkeys();
105 static void error_msg();
106 static char *fgets_ignorenul();
107 static void getpublics();
108 static void getrpcpws();
109 static void getsecrets();
110 static void initkeylist(bool_t
);
111 static void keylogin(keylen_t
, algtype_t
);
112 static void keylogin_des();
113 static void makenewkeys();
114 static int modify_cred_obj(nis_object
*, char *);
115 static void storekeys();
117 static void write_rootkey();
119 extern nis_object
*init_entry();
120 extern int get_pk_source(char *);
121 extern int localupdate(char *, char *, uint_t
, char *);
122 extern int xencrypt();
123 extern int xencrypt_g();
124 extern int __gen_dhkeys();
125 extern int key_setnet();
126 extern int key_setnet_g();
127 extern int key_secretkey_is_set_g();
128 extern int __getnetnamebyuid();
129 extern int getdomainname();
130 extern int ldap_update(char *, char *, char *, char *, char *);
136 if (sec_domain
&& *sec_domain
&&
137 strcasecmp(sec_domain
, local_domain
)) {
139 "The system default domain '%s' is different from the Secure RPC\n\
140 domain %s where the key is stored. \n", local_domain
, sec_domain
);
149 fprintf(stderr
, "usage: %s [-p] [-s ldap | nis | files] \n",
155 /* Encrypt secret key(s) with login_pw */
159 int mcount
, ccount
= 0;
162 for (mcount
= 0; CURMECH
; mcount
++) {
165 if (!xencrypt_g(slist
[mcount
], CURMECH
->keylen
,
166 CURMECH
->algtype
, short_login_pw
, netname
,
168 /* Could not crypt key */
172 clist
[mcount
] = crypt
;
178 (char *)malloc(HEXKEYBYTES
+ KEYCHECKSUMSIZE
+ 1))) {
179 fprintf(stderr
, "%s: Malloc failure.\n", program_name
);
183 (void) memcpy(crypt
, slist
[0], HEXKEYBYTES
);
184 (void) memcpy(crypt
+ HEXKEYBYTES
, slist
[0], KEYCHECKSUMSIZE
);
185 crypt
[HEXKEYBYTES
+ KEYCHECKSUMSIZE
] = 0;
186 xencrypt(crypt
, short_login_pw
);
193 fprintf(stderr
, "%s: Could not encrypt any secret keys.\n",
200 /* Initialize the array of public, secret, and encrypted secret keys */
202 initkeylist(bool_t nomech
)
207 assert(mechs
&& mechs
[0]);
208 for (mcount
= 0; CURMECH
; mcount
++)
213 if (!(plist
= (char **)malloc(sizeof (char *) * mcount
))) {
214 fprintf(stderr
, "%s: Malloc failure.\n", program_name
);
217 if (!(slist
= (char **)malloc(sizeof (char *) * mcount
))) {
218 fprintf(stderr
, "%s: Malloc failure.\n", program_name
);
221 if (!(clist
= (char **)malloc(sizeof (char *) * mcount
))) {
222 fprintf(stderr
, "%s: Malloc failure.\n", program_name
);
228 /* Retrieve public key(s) */
236 for (mcount
= 0; CURMECH
; mcount
++) {
240 hexkeylen
= ((CURMECH
->keylen
/ 8) * 2) + 1;
241 if (!(public = (char *)malloc(hexkeylen
))) {
242 fprintf(stderr
, "%s: Malloc failure.\n",
246 if (!getpublickey_g(netname
, CURMECH
->keylen
,
247 CURMECH
->algtype
, public,
249 /* Could not get public key */
251 "Could not get %s public key.\n",
252 VALID_ALIAS(CURMECH
->alias
) ?
253 CURMECH
->alias
: "");
259 plist
[mcount
] = public;
264 if (!(public = (char *)malloc(HEXKEYBYTES
+ 1))) {
265 fprintf(stderr
, "%s: Malloc failure.\n", program_name
);
268 if (!getpublickey(netname
, public)) {
278 fprintf(stderr
, "%s: cannot get any public keys for %s.\n",
279 program_name
, pw
->pw_name
);
282 "Make sure that the public keys are stored in the domain %s.\n",
289 /* Generate a new set of public/secret key pair(s) */
296 for (mcount
= 0; CURMECH
; mcount
++) {
297 char *public, *secret
;
302 hexkeylen
= ((CURMECH
->keylen
/ 8) * 2) + 1;
304 if (!(public = malloc(hexkeylen
))) {
305 fprintf(stderr
, "%s: Malloc failure.\n",
309 if (!(secret
= malloc(hexkeylen
))) {
310 fprintf(stderr
, "%s: Malloc failure.\n",
315 if (!(__gen_dhkeys_g(public, secret
, CURMECH
->keylen
,
316 CURMECH
->algtype
, short_login_pw
))) {
317 /* Could not generate key pair */
319 "WARNING Could not generate key pair %s\n",
320 VALID_ALIAS(CURMECH
->alias
) ?
321 CURMECH
->alias
: "");
328 plist
[mcount
] = public;
329 slist
[mcount
] = secret
;
332 char *public, *secret
;
335 if (!(public = malloc(HEXKEYBYTES
+ 1))) {
336 fprintf(stderr
, "%s: Malloc failure.\n", program_name
);
339 if (!(secret
= malloc(HEXKEYBYTES
+ 1))) {
340 fprintf(stderr
, "%s: Malloc failure.\n", program_name
);
344 __gen_dhkeys(public, secret
, short_login_pw
);
353 * Make sure that the entered Secure-RPC password(s) match the login
359 char baseprompt
[] = "Please enter the login password for";
361 char *en_login_pw
= spw
->sp_pwdp
;
362 char short_en_login_pw
[DESCREDPASSLEN
+ 1];
363 char *try_en_login_pw
;
364 bool_t pwmatch
= FALSE
;
365 int done
= 0, tries
= 0, pcount
;
367 snprintf(prompt
, BUFSIZ
, "%s %s:", baseprompt
, pw
->pw_name
);
369 (void) strlcpy(short_en_login_pw
, en_login_pw
,
370 sizeof (short_en_login_pw
));
372 if (en_login_pw
&& (strlen(en_login_pw
) != 0)) {
373 for (pcount
= 0; pcount
< rpc_pw_count
; pcount
++) {
376 try_en_rpc_pw
= crypt(rpc_pws
[pcount
], short_en_login_pw
);
377 if (strcmp(try_en_rpc_pw
, short_en_login_pw
) == 0) {
378 login_pw
= rpc_pws
[pcount
];
379 (void) strlcpy(short_login_pw
, login_pw
,
380 sizeof (short_login_pw
));
389 login_pw
= getpassphrase(prompt
);
390 (void) strlcpy(short_login_pw
, login_pw
,
391 sizeof (short_login_pw
));
392 if (login_pw
&& strlen(login_pw
)) {
393 /* pw was not empty */
394 try_en_login_pw
= crypt(login_pw
,
396 /* compare the pw's */
397 if (!(strcmp(try_en_login_pw
,
422 "%s: key-pair(s) unchanged for %s.\n",
427 /* Need a password */
428 snprintf(prompt
, BUFSIZ
,
429 "Need a password. %s %s:",
441 "%s: no passwd found for %s in the shadow passwd entry.\n",
442 program_name
, pw
->pw_name
);
448 /* Prompt the user for a Secure-RPC password and store it in a cache. */
450 getrpcpws(char *flavor
)
453 char prompt
[BUFSIZ
+ 1];
456 snprintf(prompt
, BUFSIZ
,
457 "Please enter the %s Secure-RPC password for %s:",
458 flavor
, pw
->pw_name
);
460 snprintf(prompt
, BUFSIZ
,
461 "Please enter the Secure-RPC password for %s:",
464 cur_pw
= getpass(prompt
);
467 fprintf(stderr
, "%s: key-pair(s) unchanged for %s.\n",
468 program_name
, pw
->pw_name
);
474 reallocarray(rpc_pws
, rpc_pw_count
, sizeof (char *)))) {
475 fprintf(stderr
, "%s: Realloc failure.\n", program_name
);
478 rpc_pws
[rpc_pw_count
- 1] = cur_pw
;
482 /* Retrieve the secret key(s) for the user and attempt to decrypt them */
486 int mcount
, scount
= 0;
492 for (mcount
= 0; CURMECH
; mcount
++) {
497 hexkeylen
= ((CURMECH
->keylen
/ 8) * 2) + 1;
498 if (!(secret
= (char *)calloc(hexkeylen
,
500 fprintf(stderr
, "%s: Malloc failure.\n",
505 for (pcount
= 0; pcount
< rpc_pw_count
; pcount
++) {
506 if (!getsecretkey_g(netname
, CURMECH
->keylen
,
507 CURMECH
->algtype
, secret
,
519 getsecrets_tryagain_g
:
520 if (secret
[0] == 0) {
523 * No existing pw can decrypt
526 getrpcpws(CURMECH
->alias
);
527 if (!getsecretkey_g(netname
,
539 goto getsecrets_abort
;
542 if (secret
[0] == 0) {
543 /* Still no go, ask again */
544 free(rpc_pws
[pcount
]);
547 printf("Try again. ");
549 goto getsecrets_tryagain_g
;
554 "%s: key-pair unchanged for %s.\n",
555 program_name
, pw
->pw_name
);
562 slist
[mcount
] = secret
;
567 if (!(secret
= (char *)malloc(HEXKEYBYTES
+ 1))) {
568 fprintf(stderr
, "%s: Malloc failure.\n", program_name
);
572 if (!getsecretkey(netname
, secret
, rpc_pws
[0])) {
574 "%s: could not get secret key for '%s'\n",
575 program_name
, netname
);
579 if (secret
[0] == 0) {
584 printf("Try again. ");
587 goto getsecrets_tryagain
;
590 "%s: key-pair unchanged for %s.\n",
591 program_name
, pw
->pw_name
);
601 (void) fprintf(stderr
,
602 "%s: could not get nor decrypt any secret keys for '%s'\n",
603 program_name
, netname
);
610 /* Register AUTH_DES secret key with keyserv */
614 char *secret
= slist
[0];
615 struct key_netstarg netst
;
618 * try to revoke the existing key/credentials, assuming
619 * one exists. this will effectively mark "stale" any
620 * cached credientials...
622 if (key_setsecret(secret
) < 0) {
628 * it looks like a credential already existed, so try and
629 * revoke any lingering Secure-NFS privledges.
632 nra
.authtype
= AUTH_DES
;
635 if (_nfssys(NFS_REVAUTH
, &nra
) < 0)
636 perror("Warning: NFS credentials not destroyed");
637 #endif /* NFS_AUTH */
639 (void) memcpy(netst
.st_priv_key
, secret
, HEXKEYBYTES
);
641 netst
.st_pub_key
[0] = '\0';
642 netst
.st_netname
= strdup(netname
);
644 /* do actual key login */
645 if (key_setnet(&netst
) < 0) {
646 fprintf(stderr
, "Could not set %s's secret key\n", netname
);
647 fprintf(stderr
, "May be the keyserv is down?\n");
652 /* Register a secret key with the keyserv */
654 keylogin(keylen_t keylen
, algtype_t algtype
)
659 for (mcount
= 0; CURMECH
; mcount
++) {
660 if (keylen
== CURMECH
->keylen
&&
661 algtype
== CURMECH
->algtype
) {
662 if (key_setnet_g(netname
, slist
[mcount
],
668 "Could not set %s's %s secret key\n",
670 VALID_ALIAS(CURMECH
->alias
) ?
671 CURMECH
->alias
: "");
675 if (keylen
== 192 && algtype
== 0)
682 * fgets is "broken" in that if it reads a NUL character it will
683 * always return EOF for all reads, even when there is data left in
684 * the file. This replacement can deal with NUL's in a calm, rational
688 fgets_ignorenul(char *s
, int n
, FILE *stream
)
690 int fildes
= fileno(stream
);
699 rs
= read(fildes
, &c
, 1);
729 /* Write unencrypted secret key into root key file */
731 write_rootkey(char *secret
, char *flavor
, keylen_t keylen
, algtype_t algtype
)
733 char line
[MAXROOTKEY_LINE_LEN
];
734 char keyent
[MAXROOTKEY_LEN
];
736 int rootfd
, bakfd
, hexkeybytes
;
737 bool_t lineone
= TRUE
;
738 bool_t gotit
= FALSE
;
739 FILE *rootfile
, *bakfile
;
741 unlink(ROOTKEY_FILE_BACKUP
);
742 if ((rename(ROOTKEY_FILE
, ROOTKEY_FILE_BACKUP
)) < 0) {
743 if ((bakfd
= creat(ROOTKEY_FILE_BACKUP
, 0600)) < 0) {
744 perror("Could not create /etc/.rootkey.bak");
750 if ((rootfd
= open(ROOTKEY_FILE
, O_WRONLY
+O_CREAT
, 0600)) < 0) {
751 perror("Could not open /etc/.rootkey for writing");
753 "Attempting to restore original /etc/.rootkey\n");
754 rename(ROOTKEY_FILE_BACKUP
, ROOTKEY_FILE
);
757 if (!(rootfile
= fdopen(rootfd
, "w"))) {
758 perror("Could not open /etc/.rootkey for writing");
760 "Attempting to restore original /etc/.rootkey\n");
762 unlink(ROOTKEY_FILE
);
763 rename(ROOTKEY_FILE_BACKUP
, ROOTKEY_FILE
);
766 if (!(bakfile
= fopen(ROOTKEY_FILE_BACKUP
, "r"))) {
767 perror("Could not open /etc/.rootkey.bak for reading");
769 "Attempting to restore original /etc/.rootkey\n");
771 unlink(ROOTKEY_FILE
);
772 rename(ROOTKEY_FILE_BACKUP
, ROOTKEY_FILE
);
776 hexkeybytes
= ((keylen
+ 7) / 8) * 2;
778 while (fgets_ignorenul(line
, MAXROOTKEY_LINE_LEN
, bakfile
)) {
779 if (sscanf(line
, "%s %d", keyent
, &atent
) < 2) {
781 * No encryption algorithm found in the file
782 * (atent) so default to DES.
784 atent
= AUTH_DES_ALGTYPE
;
787 * 192-bit keys always go on the first line
793 fprintf(rootfile
, "%s\n", secret
);
795 fprintf(rootfile
, "%s", line
);
798 if ((strlen(keyent
) == hexkeybytes
) &&
799 (atent
== algtype
)) {
801 * Silently remove lines with the same
809 fprintf(rootfile
, "%s %d\n", secret
, algtype
);
811 fprintf(rootfile
, "%s", line
);
816 /* Append key to rootkey file */
819 fprintf(rootfile
, "%s\n", secret
);
822 fprintf(rootfile
, "\n");
823 fprintf(rootfile
, "%s %d\n", secret
, algtype
);
829 unlink(ROOTKEY_FILE_BACKUP
);
833 fprintf(stderr
, "WARNING: Could not write %s key to /etc/.rootkey\n",
837 /* Store new key information in the specified name service */
841 int mcount
, ucount
= 0;
842 char *ypmaster
, *ypdomain
= NULL
, pkent
[MAXPKENTLEN
];
847 switch (dest_service
) {
851 yp_get_default_domain(&ypdomain
);
852 if (yp_master(ypdomain
, PKMAP
, &ypmaster
) != 0) {
854 "%s: cannot find master of NIS publickey database\n",
859 "Sending key change request to %s ...\n", ypmaster
);
862 if (geteuid() != 0) {
864 "%s: non-root users cannot change their key-pair in %s\n",
865 program_name
, PKFILE
);
871 "could not update; database %d unknown\n",
877 for (mcount
= 0; CURMECH
; mcount
++) {
878 char authtype
[MECH_MAXATNAME
];
880 if (!plist
[mcount
] && !clist
[mcount
])
883 __nis_mechalias2authtype(CURMECH
->alias
, authtype
,
887 "Could not generate auth_type for %s.\n",
892 snprintf(pkent
, MAXPKENTLEN
, "%s:%s:%d",
893 plist
[mcount
], clist
[mcount
],
896 switch (dest_service
) {
898 if (ldap_update(CURMECH
->alias
, netname
,
899 plist
[mcount
], clist
[mcount
],
902 "%s: unable to update %s key in LDAP database\n",
903 program_name
, authtype
);
909 /* Should never get here. */
913 /* Should never get here. */
920 assert(plist
[0] && clist
[0]);
921 snprintf(pkent
, MAXPKENTLEN
, "%s:%s", plist
[0], clist
[0]);
923 switch (dest_service
) {
925 if (ldap_update("dh192-0", netname
,
929 "%s: unable to update %s key in LDAP database\n",
936 if (status
= yp_update(ypdomain
, PKMAP
,
938 strlen(netname
), pkent
,
941 "%s: unable to update NIS database (%u): %s\n",
942 program_name
, status
,
943 yperr_string(status
));
949 if (localupdate(netname
, PKFILE
, YPOP_STORE
, pkent
)) {
951 "%s: hence, unable to update publickey database\n",
958 /* Should never get here */
964 fprintf(stderr
, "%s: unable to update any key-pairs for %s.\n",
965 program_name
, pw
->pw_name
);
971 addmechtolist(char *mechtype
)
973 mechanism_t
**realmechlist
;
976 if (realmechlist
= __nis_get_mechanisms(FALSE
)) {
977 /* Match requested mech with list */
978 for (i
= 0; realmechlist
[i
]; i
++) {
979 if (realmechlist
[i
]->alias
)
980 if (strcmp(realmechlist
[i
]->alias
, mechtype
)
983 * Match, add it to the mechs.
984 * Don't worry about qop or
985 * secserv since they are not
990 reallocarray(mechs
, numspecmech
+ 1,
991 sizeof (mechanism_t
*))) == NULL
) {
992 perror("Can not change keys");
996 if ((mechs
[numspecmech
- 1] =
997 (mechanism_t
*)malloc(
998 sizeof (mechanism_t
))) == NULL
) {
999 perror("Can not change keys");
1002 if (realmechlist
[i
]->mechname
)
1003 mechs
[numspecmech
- 1]->mechname
=
1004 strdup(realmechlist
[i
]->mechname
);
1005 if (realmechlist
[i
]->alias
)
1006 mechs
[numspecmech
- 1]->alias
=
1007 strdup(realmechlist
[i
]->alias
);
1008 mechs
[numspecmech
- 1]->keylen
=
1009 realmechlist
[i
]->keylen
;
1010 mechs
[numspecmech
- 1]->algtype
=
1011 realmechlist
[i
]->algtype
;
1012 mechs
[numspecmech
] = NULL
;
1013 __nis_release_mechanisms(realmechlist
);
1019 "WARNING: Mechanism '%s' not configured, skipping...\n",
1021 __nis_release_mechanisms(realmechlist
);
1025 "WARNING: Mechanism '%s' not configured, skipping...\n",
1031 main(int argc
, char **argv
)
1036 char *service
= NULL
;
1037 program_name
= argv
[0];
1039 mechs
= __nis_get_mechanisms(FALSE
);
1041 while ((c
= getopt(argc
, argv
, "fps:m:")) != -1) {
1045 * Not documented as of on1093.
1046 * Temporarily supported
1055 service
= strdup(optarg
);
1060 if (mechs
&& specmech
== FALSE
) {
1061 __nis_release_mechanisms(mechs
);
1065 addmechtolist(optarg
);
1075 dest_service
= get_pk_source(service
);
1077 if (!(netname
= malloc(MAXNETNAMELEN
+ 1))) {
1078 fprintf(stderr
, "%s: Malloc failure.\n", program_name
);
1081 if (!__getnetnamebyuid(netname
, uid
= getuid())) {
1082 fprintf(stderr
, "%s: cannot generate netname for uid %d\n",
1086 sec_domain
= strdup(strchr(netname
, '@') + 1);
1087 getdomainname(local_domain
, MAXNETNAMELEN
);
1090 fprintf(stdout
, "Generating new key for '%s'.\n", netname
);
1092 fprintf(stdout
, "Reencrypting key for '%s'.\n", netname
);
1095 if (dest_service
== PK_YP
|| dest_service
== PK_FILES
) {
1097 "%s: can not add non-DES public keys to %s, skipping.\n",
1098 program_name
, service
);
1099 __nis_release_mechanisms(mechs
);
1108 orig_euid
= geteuid();
1110 /* Get password information */
1111 if ((pw
= getpwuid(uid
)) == NULL
) {
1113 "%s: Can not find passwd information for %d.\n",
1118 /* Set eUID to user */
1121 /* Obtain a list of decrypted secret keys */
1124 /* Keylogin user if not already done */
1128 for (mcount
= 0; CURMECH
; mcount
++) {
1129 keylen_t keylen
= CURMECH
->keylen
;
1130 algtype_t algtype
= CURMECH
->algtype
;
1132 if (!key_secretkey_is_set_g(keylen
, algtype
) &&
1134 keylogin(CURMECH
->keylen
, CURMECH
->algtype
);
1135 if ((uid
== 0) && (makenew
== FALSE
))
1136 write_rootkey(slist
[mcount
],
1137 VALID_ALIAS(CURMECH
->alias
) ?
1145 if (!key_secretkey_is_set()) {
1147 if ((uid
== 0) && (makenew
== FALSE
))
1148 write_rootkey(slist
[0], "des", 192, 0);
1152 /* Set eUID back to root */
1153 (void) seteuid(orig_euid
);
1156 * Call getspnam() after the keylogin has been done so we have
1157 * the best chance of having read access to the encrypted pw.
1159 * The eUID must be 0 for the getspnam() so the name service
1160 * switch can handle the following eUID sensitive cases:
1162 * files/compat: read /etc/shadow
1165 if ((spw
= getspnam(pw
->pw_name
)) == 0) {
1167 /* Set eUID back to user */
1168 (void) seteuid(uid
);
1170 (void) fprintf(stderr
,
1171 "%s: cannot find shadow entry for %s.\n",
1172 program_name
, pw
->pw_name
);
1176 /* Set eUID back to user */
1177 (void) seteuid(uid
);
1179 if (strcmp(spw
->sp_pwdp
, NOPWDRTR
) == 0) {
1180 (void) fprintf(stderr
,
1181 "%s: do not have read access to the passwd field for %s\n",
1182 program_name
, pw
->pw_name
);
1187 * force will be only supported for a while
1188 * -- it is NOT documented as of s1093
1191 char *prompt
= "Please enter New password:";
1193 login_pw
= getpassphrase(prompt
);
1194 (void) strlcpy(short_login_pw
, login_pw
,
1195 sizeof (short_login_pw
));
1196 if (!login_pw
|| !(strlen(login_pw
))) {
1197 fprintf(stderr
, "%s: key-pair(s) unchanged for %s.\n",
1198 program_name
, pw
->pw_name
);
1203 * Reconsile rpc_pws and login_pw.
1205 * This function will either return with login_pw == rpc_pw
1206 * (and thus, the new pw to encrypt keys) or it will exit.
1223 for (mcount
= 0; CURMECH
; mcount
++) {
1226 write_rootkey(slist
[mcount
],
1233 write_rootkey(slist
[0], "des", 192, 0);
1237 for (mcount
= 0; CURMECH
; mcount
++)
1238 keylogin(CURMECH
->keylen
,