summaryrefslogtreecommitdiffstats
path: root/usr.bin/passwd/yp_passwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/passwd/yp_passwd.c')
-rw-r--r--usr.bin/passwd/yp_passwd.c256
1 files changed, 130 insertions, 126 deletions
diff --git a/usr.bin/passwd/yp_passwd.c b/usr.bin/passwd/yp_passwd.c
index fc6b0e4..b83e9f1 100644
--- a/usr.bin/passwd/yp_passwd.c
+++ b/usr.bin/passwd/yp_passwd.c
@@ -45,137 +45,141 @@
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/yppasswd.h>
#include <pw_yp.h>
-
-extern char *prog_name;
-uid_t uid;
+#include "yppasswd_comm.h"
extern char *getnewpasswd __P(( struct passwd * , int ));
-char *
-getserver( void )
-{
- char *domainname, *master;
- int port, err;
- int getrpcport();
-
- if ((err = yp_get_default_domain(&domainname)) != 0) {
- fprintf(stderr, "%s: can't get local yp domain: %s\n",
- prog_name, yperr_string(err));
- return NULL;
- }
-
- if ((err = yp_master(domainname, "passwd.byname", &master)) != 0) {
- fprintf(stderr, "%s: can't find the master ypserver: %s\n",
- prog_name, yperr_string(err));
- return NULL;
- }
- port = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP);
- if (port==0) {
- fprintf (stderr, "%s: yppasswdd not running on NIS master host\n",
- prog_name);
- return NULL;
- }
- if (port >= IPPORT_RESERVED) {
- fprintf (stderr, "%s: yppasswd daemon running on illegal port.\n",
- prog_name);
- return NULL;
- }
- return master;
-}
-
int
yp_passwd(char *user)
{
- struct timeval timeout;
- struct yppasswd yppasswd;
- struct passwd *pw;
- CLIENT *clnt;
- char *master;
- int err, status;
- char *s;
-
- if ((master = getserver()) == NULL) {
- exit(1);
- }
-
- /* Obtain the passwd struct for the user whose password is to be changed.
- */
- uid = getuid();
- if (user == NULL) {
- if ((pw = getpwuid(uid)) == NULL) {
- fprintf ( stderr, "%s: unknown user (uid=%d).\n",
- prog_name, (int)uid );
- exit(1);
- }
- } else {
- if ((pw = getpwnam(user)) == NULL) {
- fprintf ( stderr, "%s: unknown user: %s.\n", prog_name, user );
- exit(1);
- }
- if (pw->pw_uid != uid && uid != 0) {
- fprintf ( stderr, "%s: Only root may change account information "
- "for others\n", prog_name );
- exit(1);
- }
- }
-
- /* Use the correct password */
- pw = (struct passwd *)&yp_password;
-
- /* Initialize password information */
- yppasswd.newpw.pw_passwd = pw->pw_passwd;
- yppasswd.newpw.pw_name = pw->pw_name;
- yppasswd.newpw.pw_uid = pw->pw_uid;
- yppasswd.newpw.pw_gid = pw->pw_gid;
- yppasswd.newpw.pw_gecos = pw->pw_gecos;
- yppasswd.newpw.pw_dir = pw->pw_dir;
- yppasswd.newpw.pw_shell = pw->pw_shell;
- yppasswd.oldpass = NULL;
-
- printf("Changing NIS password for %s on %s.\n", pw->pw_name, master);
-
- /* Get old password */
- if(pw->pw_passwd[0]) {
-
- s = getpass ("Old password: ");
- if( strcmp(crypt(s, pw->pw_passwd), pw->pw_passwd)) {
- fprintf(stderr, "Sorry.\n");
- exit (1);
- }
- yppasswd.oldpass = strdup(s);
- } else
- yppasswd.oldpass = "";
-
- if ((s = getnewpasswd(pw, 1)) == NULL)
- exit (1);
- yppasswd.newpw.pw_passwd = s;
-
- /* The yppasswd.x file said `unix authentication required',
- * so I added it. This is the only reason it is in here.
- * My yppasswdd doesn't use it, but maybe some others out there
- * do. --okir
- */
- clnt = clnt_create( master, YPPASSWDPROG, YPPASSWDVERS, "udp" );
- clnt->cl_auth = authunix_create_default();
- bzero( (char*)&status, sizeof(status) );
- timeout.tv_sec = 25; timeout.tv_usec = 0;
- err = clnt_call( clnt, YPPASSWDPROC_UPDATE,
- xdr_yppasswd, (char*)&yppasswd,
- xdr_int, (char*)&status,
- &timeout );
-
- if (err) {
- clnt_perrno(err);
- fprintf( stderr, "\n" );
- } else if (status) {
- fprintf( stderr, "Error while changing NIS password.\n");
- }
-
- printf("\nNIS password has%s been changed on %s.\n",
- (err || status)? " not" : "", master);
-
- auth_destroy( clnt->cl_auth );
- clnt_destroy( clnt );
- exit ((err || status) != 0);
+ struct timeval timeout;
+ struct yppasswd yppasswd;
+ struct master_yppasswd master_yppasswd;
+ struct passwd *pw;
+ CLIENT *clnt;
+ struct rpc_err err;
+ char *master;
+ int *status = NULL;
+ uid_t uid;
+
+ _use_yp = 1;
+
+ uid = getuid();
+
+ if ((master = get_yp_master(1)) == NULL) {
+ warnx("failed to find NIS master server");
+ return(1);
+ }
+
+ /*
+ * It is presumed that by the time we get here, use_yp()
+ * has been called and that we have verified that the user
+ * actually exists. This being the case, the yp_password
+ * stucture has already been filled in for us.
+ */
+
+ /* Use the correct password */
+ pw = (struct passwd *)&yp_password;
+
+ if (pw->pw_uid != uid && uid != 0) {
+ warnx("Only the super-user may change account information \
+for other users");
+ return(1);
+ }
+
+ /* Initialize password information */
+ if (suser_override) {
+ master_yppasswd.newpw.pw_passwd = strdup(pw->pw_passwd);
+ master_yppasswd.newpw.pw_name = strdup(pw->pw_name);
+ master_yppasswd.newpw.pw_uid = pw->pw_uid;
+ master_yppasswd.newpw.pw_gid = pw->pw_gid;
+ master_yppasswd.newpw.pw_expire = pw->pw_expire;
+ master_yppasswd.newpw.pw_change = pw->pw_change;
+ master_yppasswd.newpw.pw_fields = pw->pw_fields;
+ master_yppasswd.newpw.pw_gecos = strdup(pw->pw_gecos);
+ master_yppasswd.newpw.pw_dir = strdup(pw->pw_dir);
+ master_yppasswd.newpw.pw_shell = strdup(pw->pw_shell);
+ master_yppasswd.newpw.pw_class = strdup(pw->pw_class);
+ master_yppasswd.oldpass = "";
+ master_yppasswd.domain = yp_domain;
+ } else {
+ yppasswd.newpw.pw_passwd = strdup(pw->pw_passwd);
+ yppasswd.newpw.pw_name = strdup(pw->pw_name);
+ yppasswd.newpw.pw_uid = pw->pw_uid;
+ yppasswd.newpw.pw_gid = pw->pw_gid;
+ yppasswd.newpw.pw_gecos = strdup(pw->pw_gecos);
+ yppasswd.newpw.pw_dir = strdup(pw->pw_dir);
+ yppasswd.newpw.pw_shell = strdup(pw->pw_shell);
+ yppasswd.oldpass = "";
+ }
+
+ if (suser_override)
+ printf("Changing NIS password for %s on %s in domain %s.\n",
+ pw->pw_name, master, yp_domain);
+ else
+ printf("Changing NIS password for %s on %s.\n",
+ pw->pw_name, master);
+
+ /* Get old password */
+
+ if(pw->pw_passwd[0] && !suser_override) {
+ yppasswd.oldpass = strdup(getpass("Old Password: "));
+ if (strcmp(crypt(yppasswd.oldpass, pw->pw_passwd),
+ pw->pw_passwd)) {
+ errx(1, "Sorry.");
+ }
+
+ }
+
+ if (suser_override) {
+ if ((master_yppasswd.newpw.pw_passwd = getnewpasswd(pw, 1)) == NULL)
+ return(1);
+ } else {
+ if ((yppasswd.newpw.pw_passwd = getnewpasswd(pw, 1)) == NULL)
+ return(1);
+ }
+
+ if (suser_override) {
+ if (senddat(&master_yppasswd)) {
+ warnx("failed to send request to rpc.yppasswdd");
+ return(1);
+ }
+ status = getresp();
+ } else {
+ if ((clnt = clnt_create(master, YPPASSWDPROG,
+ YPPASSWDVERS, "udp")) == NULL) {
+ warnx("failed to contact rpc.yppasswdd on host %s: %s",
+ master, clnt_spcreateerror(""));
+ return(1);
+ }
+ /*
+ * The yppasswd.x file said `unix authentication required',
+ * so I added it. This is the only reason it is in here.
+ * My yppasswdd doesn't use it, but maybe some others out there
+ * do. --okir
+ */
+ clnt->cl_auth = authunix_create_default();
+
+ status = yppasswdproc_update_1(&yppasswd, clnt);
+ clnt_geterr(clnt, &err);
+
+ auth_destroy(clnt->cl_auth);
+ clnt_destroy(clnt);
+ }
+
+ if ((!suser_override && err.re_status != RPC_SUCCESS) ||
+ status == NULL || *status) {
+ errx(1, "Failed to change NIS password: %s",
+ (err.re_status != RPC_SUCCESS && !suser_override) ?
+ clnt_sperrno(err.re_status) :
+ "rpc.yppasswdd returned error status");
+ }
+
+ printf("\nNIS password has%s been changed on %s.\n",
+ ((err.re_status != RPC_SUCCESS && !suser_override)
+ || status == NULL || *status) ?
+ " not" : "", master);
+
+ return ((err.re_status || status == NULL || *status));
}
#endif /* YP */
OpenPOWER on IntegriCloud