hesupd.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 433 行
C
433 行
#ifndef lintstatic char *sccsid = "@(#)hesupd.c 4.2 ULTRIX 2/14/91";#endif lint/************************************************************************ * * * Copyright (c) 1989 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * * hesupd - hesiod update daemon * * * * Description: The hesiod receives hesiod database update requests* * from a TCP socket connection. The updates are parsed and if they* * are valid they are applied to the database. A response is sent * * back to the requestor indicating success or failure. * * * * Since the old password is sent across the network this presents * * a potential for a breakin (unless you use DESNCs).To reduce this* * risk the entire mesage is jumbled by passwd and unjumbled here. * * * * * ************************************************************************/#include <sys/param.h>#include <sys/mount.h>#include <sys/types.h>#include <sys/fs.h>#include <sys/file.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/socketvar.h>#include <sys/un.h>#include <sys/wait.h>#include <sys/time.h>#include <sys/stat.h>#include <sys/resource.h>#include <sys/lock.h>#include <sys/svcinfo.h>#include <netinet/in.h>#include <errno.h>#include <syslog.h>#include <signal.h>#include <stdio.h>#include <netdb.h>#include <krb.h>#include <auth.h>#define PASSCHG 1#define HESUPD_PORT 800#define HESUPDACK 6#define HESUPDNAK 9struct hesupdmsg { char newcrypt[64]; int opcode; int hesuid; char oldpwd[32]; };extern struct passwd *getpwuid(), *getpwuid_bind();char *index();extern FILE *heslog;int newsock, authtype, auth_bind;char defhome[] = "/var/dss/namedb/src";char bindmaster[] = "bindmaster";FILE *heslog = NULL;char *homebase = defhome;char namebuf[ANAME_SZ];char *ptr;main (argc,argv) int argc; char *argv[];{ static struct sockaddr sock, sock2; static struct hesupdmsg hupmsg; char * mytime(); int s, socklen, amount, i, rfds, nfound, t, j; int on=1; char hesupdbuf[sizeof(struct hesupdmsg)]; char *arg, *seclass; short hesupd_port; int pid; struct sigvec vec; int res, fd, cmd; extern int errno; struct svcinfo *svcp; struct servent *sp; struct hostent *hp; struct hostent mhp; /* bind master hostent */ struct hostent lhp; /* local host hostent */ struct sockaddr_in sin; char host[32]; int hlen = 32; struct timeval timeout; int ret; int looplim; int ackmsg=HESUPDACK; int nakmsg=HESUPDNAK; /* * must be superuser to run */ if (geteuid() != 0){ (void) fprintf(stderr, "hesupd: must be super user\n"); (void) fflush(stderr); exit(1); } /* hesupd can only be run on a master bind server */ gethostname(host, hlen); hp = gethostbyname(host); if(hp == 0) { fprintf(stderr,"hesupd cant lookup %s\n",host); exit(1); } hp = gethostbyname(bindmaster); if(hp == 0) { fprintf(stderr,"hesupd cant lookup %s\n",bindmaster); exit(1); } if(strcmp(host,hp->h_name)) { fprintf(stderr,"hesupd can only be run on a bind primary\n"); exit(0); } sp=getservbyname("hesupd","tcp"); if(sp == 0) { fprintf(stderr,"hesupd is a unknown tcp service\n"); exit(1); } /* initialize my log file */ heslog= fopen("/usr/adm/hesupd.log","a+"); if(heslog == NULL) { fprintf(stderr,"Hesupd: Cant open log file\n"); exit(0); } if((svcp = getsvc()) == NULL) { fprintf(stderr,"Hesupd: Cannot access security type\n"); exit(0); } authtype=svcp->svcauth.seclevel; for (i = 0, auth_bind = 0; svcp->svcpath[SVC_AUTH][i] != SVC_LAST; i++) if (svcp->svcpath[SVC_AUTH][i] == SVC_BIND) { auth_bind = 1; break; }/* NO ARGUMENTS IMPLEMENTED* Process arguments * -d hesupd home directory** while (argc > 1 && argv[1][0] == '-') {* argc--;* arg = *++argv;* switch (arg[1]) {* case 'd': * if (arg[2])* homebase = &arg[2];* else if (argc > 1) {* argc--;* homebase = *++argv;* }* break;* }* }*/ if (chdir(homebase) < 0) { fprintf(stderr, "hesupd: can't chdir to %s\n",homebase); exit(1); } /**** do fork of daemon */ close(heslog); pid = fork(); if (pid < 0) { perror("hesupd fork problem"); exit(1); } if (pid != 0) exit(0); for (t = 0; t < 20; t++) (void) close(t); open("/", 0); dup2(0, 1); dup2(0, 2); sigsetmask(0); sp=getservbyname("hesupd","tcp"); if(sp == 0) { fprintf(heslog,"hesupd is a unknown tcp service\n"); exit(1); } hp = gethostbyname(bindmaster); if(hp == 0) { fprintf(stderr,"hesupd cant lookup %s\n",bindmaster); exit(1); } /* initialize my log file */ heslog= fopen("/usr/adm/hesupd.log","a+"); if(heslog == NULL) { fprintf(heslog,"Hesupd: Cant open log file\n"); exit(0); } fprintf(heslog,"bindmaster=%s\n",hp->h_name); fflush(heslog); fprintf(heslog,"Allocating socket\n"); fflush(heslog); if ((s=socket(AF_INET, SOCK_STREAM, 0)) < 0) { fprintf(heslog, "server: could not create a socket\n"); fflush(heslog); exit(1); } bzero((char *)&sin, sizeof(sin)); bcopy(hp->h_addr,(char *)&sin.sin_addr,hp->h_length); sin.sin_family = AF_INET; sin.sin_port = sp->s_port; fprintf(heslog,"port=%x\n",sin.sin_port); fprintf(heslog,"addr=%s\n",inet_ntoa(sin.sin_addr)); fprintf(heslog,"Setting socket options\n"); /*setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));*/ ret = bind(s, (char *) &sin, sizeof(struct sockaddr_in)); if (ret < 0) { (void)close(s); fprintf(heslog,"hesupd bind error = %d\n",errno); fprintf(heslog, "server: could not bind a name to a socket\n"); fflush(heslog); exit(1); } fprintf(heslog,"InitiaL listen on socket\n"); if (listen(s,25) < 0) { fprintf(heslog, "server: could not listen to a socket!\n"); fflush(heslog); exit(1); } if(authtype >= SEC_UPGRADE && auth_bind) { if(gethostname(namebuf, sizeof(namebuf)) == -1) { fprintf(heslog,"gethostname failure\n"); } if((ptr = index(namebuf, '.')) != (char *)0) *ptr = '\0'; if(krb_svc_init("hesiod", namebuf, (char *)NULL, 0, (char *)NULL, "/var/dss/kerberos/tkt/tkt.hesupd") != RET_OK) { fprintf(heslog,"Kerberos initialization failure\n", 2); } } socklen = sizeof(sock2);/****************************** accept connections forever ********************/ while(1) { fprintf(heslog,"hesupd waiting for a connection\n"); fflush(heslog); newsock = accept(s, &sock2, &socklen); if(newsock < 0 ) { fprintf(heslog, "hesupd: failed connection accept!\n"); fflush(heslog); exit(1); } fprintf(heslog, "hesupd: Accepted a connection on the socket %d\n", newsock); fflush(heslog);/******************* receive hesiod update request ****************************/ bzero((char *)&hupmsg, sizeof(struct hesupdmsg)); amount = recv (newsock, (char *)&hupmsg, sizeof(struct hesupdmsg), 0); if (amount != sizeof(struct hesupdmsg)) { fprintf(heslog, "hesupd: recv error! received %d bytes\n",amount); fflush(heslog); } else { /* reread the svc.conf file if it has changed */ if((svcp = getsvc()) == NULL) { fprintf(stderr, "Hesupd: Cannot access security type\n"); exit(0); } authtype = svcp->svcauth.seclevel; /* check to see if bind must be kerberos authenticated */ for (i = 0, auth_bind = 0; svcp->svcpath[SVC_AUTH][i] != SVC_LAST; i++) if (svcp->svcpath[SVC_AUTH][i] == SVC_BIND) { auth_bind = 1; break; } /* if bind is kerberos authenticated, re-init kerberos */ if(authtype >= SEC_UPGRADE && auth_bind) { if(gethostname(namebuf, sizeof(namebuf)) == -1) { fprintf(heslog,"gethostname failure\n"); } if((ptr = index(namebuf, '.')) != (char *)0) *ptr = '\0'; /* krb_svc_init will not reinit our cred if our tgt has not expired */ if(krb_svc_init("hesiod", namebuf, (char *)NULL, 0, (char *)NULL, "/var/dss/kerberos/tkt/tkt.hesupd") != RET_OK) { fprintf(heslog, "Kerberos initialization failure\n", 2); } } if(procmsg(&hupmsg)) amount=send(newsock,(char *)&ackmsg,4,0); else amount=send(newsock,(char *)&nakmsg,4,0); if(amount < 0) { fprintf(heslog, "hesupd: send error!\n"); fflush(heslog); } } close(newsock); }}intprocmsg(hup)struct hesupdmsg *hup;{ struct passwd *hesiod_pwuid; int retval=0; unmix(hup); /************* check if this uid is being served by hesiod ******************/ if(hup->opcode != PASSCHG) return(0); hesiod_pwuid = getpwuid_bind( (int) hup->hesuid); if(hesiod_pwuid == NULL) return(0); fflush(heslog); switch(hup->opcode) { case PASSCHG: switch(authtype) { case SEC_BSD: fprintf(heslog,"SEC_BSD\n"); retval=chpw_bsd(hup->hesuid,hup->oldpwd,hup->newcrypt); break; case SEC_UPGRADE: fprintf(heslog,"SEC_UPGRADE\n"); retval=chpw_trans(hup->hesuid,hup->oldpwd,hup->newcrypt); break; case SEC_ENHANCED: fprintf(heslog,"SEC_ENHANCED\n"); retval=chpw_c2(hup->hesuid,hup->oldpwd,hup->newcrypt); break; } if(retval) fprintf(heslog,"good password update for uid %d\n",hup->hesuid); else fprintf(heslog,"bad password update for uid %d\n",hup->hesuid); fflush(heslog); return(retval); default: fprintf(heslog, "hesupd: bad opcode error!\n"); fflush(heslog); return(0); }}/**** unshake and unstir ****/unmix(hup)struct hesupdmsg *hup;{ unsigned char *hesbuf= (unsigned char *) hup; unsigned char tmp=0; int i,j,len; len = sizeof(struct hesupdmsg) - 1; for (i=0,j=3; i <=len; i++,j++) hesbuf[i]-= j % 5; tmp= (( hesbuf[len] << 3 ) | (hesbuf[0] >> 5)); for (i=0;i < len; i++) { hesbuf[i]= (( hesbuf[i] << 3 ) | (hesbuf[i+1] >> 5)); } hesbuf[len]=tmp; for (i=0,j=11; i <=len; i++,j++) hesbuf[i]-= j % 15;}AUTHORIZATION *getauthuid_hesiod(uid)int uid;{ static AUTHORIZATION auth; char uidbuf[10], **pp; AUTHORIZATION *_auth = (AUTHORIZATION *) NULL; setent_bind(0); sprintf(uidbuf, "%u", uid); pp = (char **) hes_auth_resolve(uidbuf, "auth"); endent_bind(); if(pp != NULL) if(*pp) { binauth(*pp, &auth); while(*pp) free(*pp++); _auth = &auth; } else return(NULL); return _auth;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?