/* * Copyright (c) 1992/3 Theo de Raadt * Copyright (c) 1994 Olaf Kirch * Copyright (c) 1995 Bill Paul * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifdef YP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "yppasswd_comm.h" extern char *getnewpasswd __P(( struct passwd * , int )); int yp_passwd(char *user) { 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 */