/* remote yppasswd type program * lets you change username, password, gecos and/or shell * remotely via the yppasswd daemon. * (note daemon may not accept all of your changes) * * cc source.c -lrpcsvc * progname ypmaster ypdomain */ #include #include #include #include #include #include #define TIMEOUT 15 extern char *get_yp_map(); char *split(s) char *s; { while(*s!='\0' && *s!=':') s++; if(*s =='\0') return s; *s='\0'; return(s+1); } changes(p) struct passwd *p; { int done=0,choice; char s[100],s2[100]; while(!done) { printf("0. quit\n"); printf("1. name\n"); printf("2. password\n"); printf("3. gecos\n"); printf("4. shell\n"); printf("choice> "); fflush(stdout); scanf("%d",&choice); switch(choice) { case 0: done++; break; case 1: printf("New name: "); fflush(stdout); scanf("%s",p->pw_name); break; case 2: printf("New pass: "); fflush(stdout); scanf("%s",s); s[8]='\0'; /* so we dont have a random salt.. who cares */ strcpy(p->pw_passwd,crypt(s,"AE")); break; case 3: printf("New finger info: "); scanf("%*c"); /* get rid of previous \n still in buffer */ strcpy(p->pw_gecos,gets(s)); break; case 4: printf("New shell: "); fflush(stdout); scanf("%s",s); strcpy(p->pw_shell,s); break; default: printf("Invalid Choice.\n"); break; } } } getpw(p,st) /* put string st into passwd structure */ struct passwd *p; char *st; { char *s,*t; s=split(st); strcpy(p->pw_name, st); t=split(s); strcpy(p->pw_passwd,s); s = split(t); p->pw_uid = atoi(t); t = split(s); p->pw_gid = atoi(s); s = split(t); strcpy(p->pw_gecos,t); t = split(s); strcpy(p->pw_dir,s); s=split(t); strcpy(p->pw_shell,t); p->pw_age = NULL; p->pw_comment = NULL; } void timeout(); char *getpass(); main(argc,argv) char **argv; int argc; { struct yppasswd yppasswd; struct passwd p; int len,ok,ans; enum clnt_stat errcode; char temp[100],a[100],b[20],c[100],d[100],e[50]; char space[100]; char *s; struct ypreq_key key; struct ypresp_val answer; char *domain,*master; char *pass; if(argc!=3) { printf("Usage: %s server domain\n",argv[0]); exit(1); } master=argv[1]; domain=argv[2]; answer.valdat.dptr = space; /* where our answer will be */ p.pw_name = a; /* we need space! */ p.pw_passwd = b; p.pw_gecos = c; p.pw_dir = d; p.pw_shell = e; printf("Enter account name : "); scanf("%s",temp); key.domain = domain; key.map = "passwd.byname"; key.keydat.dptr = temp; key.keydat.dsize = strlen(temp); signal(SIGALRM,timeout); alarm(TIMEOUT); errcode = callrpc( master,YPPROG, YPVERS, YPPROC_MATCH, xdr_ypreq_key,(caddr_t) &key, xdr_ypresp_val, &answer); alarm(0); if ( errcode != RPC_SUCCESS) print_rpc_err(errcode); if (answer.status == TRUE ) { /* we have a match */ len = answer.valdat.dsize; answer.valdat.dptr[len] = '\0'; /* null terminate */ getpw(&p,answer.valdat.dptr); print_pwd(p); } else { printf("User %s not found.\n",temp); exit(1); } printf("\n\n"); pass=getpass("Password:"); /* if(strlen(p.pw_passwd)!=0) if (strcmp(crypt(pass,p.pw_passwd),p.pw_passwd)!=0) { printf("Bad password. Not even gonna bother.\n"); exit(1); } */ changes(&p); print_pwd(p); printf("Is this ok? [y/n] : "); scanf("%*c"); /* flush last */ gets(temp); if(temp[0]!='y') return; yppasswd.oldpass = pass; yppasswd.newpw = p; /* All the work is done here, now we try to actually do it */ ans = callrpc(master, YPPASSWDPROG, YPPASSWDVERS, YPPASSWDPROC_UPDATE, xdr_yppasswd, &yppasswd, xdr_int, &ok); if(ans!=0) { fprintf(stderr, "RPC call didnt go through.\n"); exit(1); } if(ok==1) { fprintf("Remote site wouldnt change pw entry (wrong pw?)\n"); } if(ok!=0) { decodeans(ok,master); exit(1); } } #define MAXMSG 17 char *msgs[]= { "No error", /*0*/ "Error from pre 4.1 version", /*1*/ "Password incorrect", /*2*/ /*really login incorrect but why say so*/ "No changeable fields were changed", /*3*/ "No password in adjunct", /*4*/ "Bad password in adjunct", /*5*/ "Inconsistency in adjunct", /*6*/ "Password incorrect", /*7*/ "Password file busy -- try again later", /*8*/ "Password temp file open error -- contact system administrator", /*9*/ "Password temp file fdopen error -- contact system administrator", /*10*/ "Password adjunct file fopen error -- contact system administrator", /*11*/ "Password file fopen error -- contact system administrator", /*12*/ "Password temp file fputs failed; disk partition may be full on NIS master! -- contact system administrator", /*13*/ "Password temp file ferror is set; disk partition may be full on NIS master! -- contact system administrator", /*14*/ "Password temp file fflush failed; disk partition may be full on NIS master! -- contact system administrator", /*15*/ "Password adjunct file rename failed; disk partition may be full on NIS master! -- contact system administrator", /*16*/ "Password file rename failed; disk partition may be full on NIS master! -- contact system administrator", /*17*/ }; decodeans(ok, master) char *master; int ok; { if (ok <0 || ok > MAXMSG ) fprintf(stderr, "Remote %s error %d\n",master, ok); else fprintf(stderr,"Error from %s: %s \n",master, msgs[ok]); } print_pwd(p) struct passwd p; { printf("%s:%s:%d:%d:%s:%s:%s\n", p.pw_name,p.pw_passwd,p.pw_uid,p.pw_gid, p.pw_gecos,p.pw_dir,p.pw_shell); } print_rpc_err(errcode) { fprintf(stderr, "%s\n",clnt_sperrno(errcode)); exit(1); } void timeout() { printf("RPC request (callrpc) timed out.\n"); exit(1); } /* www.hack.co.za [2000]*/