/* *-------------------- DD_ACCESS ------------------------------- * * name: DD_Access.c V4.0 * author: Alexander Grigoriev , Andrei Fedorov * Insitution: IKI RAN lab.546 aug@afed.iki.rssi.ru * Description: Set of function for access to DD system * Last revision: Oct 10, 2002 * List of revisions: * March 1999 V1.0 * 20 Oct 1999 ; ShowTicket was corrected. V2.0 * 28 Oct 1999 ; Added LOGINS,ddcheck V3.0 * Oct 10, 2002 - revised by A. Fedorov V 4.0 */ /*#define _XOPEN_SOURCE*/ /* for crypt function */ #define _XOPEN_SOURCE #include #include #include #include #include #include /*=========== Global Variables ===============================*/ size_t CashStart[2]={0L,0L}; size_t CashCount[2]={1, MAXHOSTLENGTH}; size_t CashCountInt[2]={1, 1}; extern int Verbose; /*############################################################################*/ /*----------------GETTICKET------------------------------------*/ /* Description: This function find the user data in user_cash.nc * If O'k rewrite the line with new time. * In case of a new user, remove the first line with * older time data then a current time + 4.5 hours. * Take 3 arguments: UserId, IP-address(string,like "193.232.6.60\0") DD_user_id(can see in user_info.nc) Returns 0 if O'k or NOPERMISSION if error If DD_log_name equal NULL searching for UserId, IP-address If DD_log_name nonequal NULL searching for IP-address,DD_log_name* * */ int GetTicket(int UID, char *HostName, int DD_user_id) { char *ddbase; char refname[PATHLENGTH]; int TicketID, Comp=1, Flag,OldFlag=0, Find=0, dltt; int CurIDID,HostID,TimeID, DD_id_ID; /* Variable IDs in the NC ticket file */ int TimeFinish; int Clock; char CurHostName[MAXHOSTLENGTH]; int CurID, CurTime,DD_id, MemTime,OldestStart; /* Values to read and write to ticket file */ size_t CurCashStart[2]={0,0}; size_t HostCount[2] = {1,MAXHOSTLENGTH}; int ACCESS = NOPERMISSION; int status; /* Return value of any NC routine */ if(Verbose) fprintf(stderr,"GetTicket: UID = %d, HostName <%s>, DD_user_id = <%d> is going to work\n",UID, HostName,DD_user_id); /*------------- OpenUserNC ---------------------------------*/ if((ddbase = getenv("DDBASE")) == NULL) { if(Verbose) fprintf(stderr,"GETTICKET: No DDBASE environment.\n"); return(ENVIRERROR); } strcpy(refname,ddbase); strcat(refname,TICKET_PATH); if(Verbose) fprintf(stderr,"GETTICKET: TICKET_PATH is %s \n",refname); if((status = nc_open(refname, NC_WRITE,&TicketID)) != NC_NOERR) { if(Verbose) fprintf(stderr,"GETTICKET: %s\n", nc_strerror(status)); return(NOUSERSFILE); } /*------------------ Working with -------------------------------*/ status = nc_inq_varid(TicketID,"id",&CurIDID); status = nc_inq_varid(TicketID,"host",&HostID); status = nc_inq_varid(TicketID,"time",&TimeID); status = nc_inq_varid(TicketID,"DD_id",&DD_id_ID); status = nc_sync(TicketID); Clock = (int)time(NULL); // TimeFinish = Clock+16200; // 4.5 hours TimeFinish = Clock+172800; // 48 hours HostName[strlen(HostName)] = '\0'; CashStart[0]=0; OldestStart = 0; do { status = nc_get_var1_int(TicketID, CurIDID, CashStart,&CurID); nc_get_var1_int(TicketID, DD_id_ID, CashStart,&DD_id); nc_get_vara_text(TicketID, HostID,CashStart,HostCount,CurHostName); nc_get_var1_int(TicketID, TimeID,CashStart,&CurTime); if(CashStart[0] == 0) MemTime=CurTime; Comp=strcmp(CurHostName,HostName); if((CurID == UID)&&(Comp == 0)&&(DD_id == DD_user_id)) { CurCashStart[0]=CashStart[0]; Find = 1; } dltt = (CurTime - MemTime); if((dltt < 0) && (CurHostName[0] != '\0')) { OldestStart=CashStart[0]; MemTime = CurTime; } CashStart[0]++; } while((Find != 1) && (CurHostName[0] != '\0') && (CashStart[0] < USERCASHLEN)); if(Verbose) fprintf(stderr,"FINISH TIME : %ld\n",TimeFinish); CashStart[0]--; if(MemTime < Clock) { OldFlag = 1; } if(Find == 1) { nc_put_var1_int(TicketID,TimeID,CurCashStart,&TimeFinish); if(Verbose) fprintf(stderr,"User: ID = %d, DD_id = %d, HostName <%s> continue work.\n ",UID,DD_user_id,HostName); ACCESS = 0; } else if(OldFlag == 1) { CashStart[0]=OldestStart; nc_put_var1_int(TicketID,CurIDID, CashStart,&UID); nc_put_var1_int(TicketID,DD_id_ID, CashStart,&DD_user_id); nc_put_vara_text(TicketID,HostID,CashStart,HostCount,HostName); nc_put_var1_int(TicketID,TimeID,CashStart,&TimeFinish); if(Verbose) fprintf(stderr,"User: ID = %d, DD_id = %d, \n HostName <%s> started work.\n ",UID,DD_user_id,HostName); ACCESS = 0; } else if((CashStart[0] started work.\n ",UID,DD_user_id,HostName); ACCESS = 0; } else {fprintf(stderr,"Too many members!\n");ACCESS = NOPERMISSION;} /*if((CurID == UID)&&(Comp == 0)) fprintf(stderr,"Exists...\n");*/ nc_sync(TicketID); nc_close(TicketID); return((int)ACCESS); } /*############################################################################*/ /*-------------------CHECK TICKET-----------------------*/ /* Description: This function check the user for accessability * in user_info.nc file. Returns DD_id if O'k. * Returns NOPERMISSION in case of unaccessability, neagative value (DD_access.h) * in case of error. */ int CheckTicket(char *NameUsr, char *Ticket) { int i=0; int DD_id; int Right = NOPERMISSION; char salt[2],newkey[USRLENGTH]; int UsrRefID; /* ID of reference file which consists description of all users */ char *ddbase; char refname[PATHLENGTH]; int UserDimID,UserLenDimID,PasLenDimID; /* ID of dimensions in NC file */ int MemID, PasID; /* ID of variables in NC file */ size_t MaxRecords, UserLength, PasswdLength; /* Dimensions */ size_t start[2] = {0,0}, UserCount[2] = {1,0}, PasswdCount[2] = {1,0}; static char UserDimName[] = "user", UserLenDimName[] = "UserLength"; /* Dimensions names */ static char PasLenDimName[] = "PasswdLength"; /* Dimensions names */ static char MemName[] = "member", PasName[] = "passwd"; /* Variable Names */ char PasChar[USRLENGTH],MemChar[USRLENGTH]; int status; /* Return of any NC call */ /*------------- Open User reference NC ---------------------------------*/ if((ddbase = getenv("DDBASE")) == NULL) { if(Verbose) fprintf(stderr,"CHECKTICKET: No DDBASE environment.\n"); return(ENVIRERROR); } strcpy(refname,ddbase); strcat(refname,USERREFNAME); if(Verbose) fprintf(stderr," CHECHTICKET: PATH is %s \n",refname); // sleep(40); if((status = nc_open(refname, NC_WRITE,&UsrRefID)) != NC_NOERR) { if(Verbose) fprintf(stderr,"CHECHTICKET: %s\n", nc_strerror(status)); return(NOUSERSFILE); } /*------------------ Define all dimensions -------------------------------*/ status = nc_inq_dimid(UsrRefID,UserDimName,&UserDimID); status = nc_inq_dimlen(UsrRefID, UserDimID, &MaxRecords); status = nc_inq_dimid(UsrRefID,UserLenDimName,&UserLenDimID); status = nc_inq_dimlen(UsrRefID, UserLenDimID, &UserLength); UserCount[1] = UserLength; status = nc_inq_dimid(UsrRefID,PasLenDimName,&PasLenDimID); status = nc_inq_dimlen(UsrRefID, PasLenDimID, &PasswdLength); PasswdCount[1] = PasswdLength; /*fprintf(stderr,"CheckTicket:Rec: %d %d %d\n",MaxRecords,UserLength,PasswdLength);*/ /*------------------ Define all variables ID -------------------------------*/ status = nc_inq_varid(UsrRefID, MemName,&MemID); status = nc_inq_varid(UsrRefID, PasName,&PasID); for(i=0;i Clock) Time_is = 1; if((Find == 1) && (Time_is == 1)) { fprintf(stderr,"User: ID = %d, DD_id = %d, host %s, timework=%d, is connected. \n",CurID,DD_user_id,hostname,Time_is); ServerReply = 0; } else { fprintf(stderr,"User: ID = %d, DD_id = %d, host %s, timework=%d, Permission denied!. \n",CurID,DD_user_id,hostname,Time_is); ServerReply=NOPERMISSION; } nc_sync(TicketID); nc_close(TicketID); return ServerReply; } /* *------------------------ SETUSER -------------------------------*/ /* * Description: Library function for client-server using. * Send ID, HostName to server. * Compares the information with your {id,hostname}. * Returns 1 if O'k, or a negative value in case * of "NOPERMISSION". * */ int SetUser(int UserID, char *HostName, char *LogName) { int SocketID = -1; /* Global socket id for this communication session */ static DD_data_t dd = {DD_CHAR,0,NULL,0,NULL}; static caddr_t buf = NULL; static XDR xdrs; int cc,i, hostlen, ticketlen, userlen; int op = SHOWTICKETREQ; int SHOW_ACCESS; SHOW_ACCESS = NOPERMISSION; /* fprintf(stderr,"after CLIENT int SetUser: SocketID = %d\n",SocketID); fprintf(stderr,"after CLIENT int SetUser: User = %d Host %s\n",UserID,HostName); */ /*------------------CONNECTION to SERVER---------------------------*/ /* * If no connection, connect to server, try to order data set and return * ID if OK or ErrorNumber if not */ /* fprintf(stderr,"Try to connect Server\n");*/ /* If there is no connection, try to get it */ if(SocketID < 0) if((SocketID = GetSocket()) < 0) return(NOCONNECTION); /* fprintf(stderr,"Server3 connected\n");*/ /*---------------------REQUEST TO SERVER-----------------------------*/ /* Check the HostName length */ if(strlen(HostName) > MAXHOSTLENGTH) hostlen = MAXHOSTLENGTH; else hostlen = strlen(HostName); if(strlen(LogName) > USRLENGTH) userlen = USRLENGTH; else userlen = strlen(LogName); /* Allocation memory and stream */ buf = (caddr_t)malloc(REQUESTLENGTH); xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE); /* Encoding the request */ xdr_int(&xdrs,&op); xdr_int(&xdrs,&UserID); xdr_string(&xdrs, &HostName, hostlen); xdr_string(&xdrs, &LogName, userlen); /* fprintf(stderr,"UserID, HostName just more : %d %s\n",UserID,HostName);*/ /* Send request */ if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0) { perror("DD_GetTicket:"); free(buf); xdr_destroy(&xdrs); return(REQSENDERR); } free(buf); xdr_destroy(&xdrs); /* Get reply header */ buf = (caddr_t)malloc(REPLYLENGTH); i =0; while(((cc = recv(SocketID,buf,REPLYLENGTH,0)) < 0) && (i < TRY)) i++; if(cc < 0) { perror("DD_SetUser:"); free(buf); return(REPLYRECERR); } xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE); xdr_int(&xdrs,&SHOW_ACCESS); free(buf); xdr_destroy(&xdrs); shutdown(SocketID,2); close(SocketID); /*SocketID = -1;*/ /* fprintf(stderr,"SetUser,End; UserID, HostName just more : %d %s\n",UserID,HostName); fprintf(stderr,"SHOW_ACCES %d \n",SHOW_ACCESS); */ if(Verbose) fprintf(stderr,"SetUser: ACCES = %d \n",SHOW_ACCESS); return((int)SHOW_ACCESS); } /*############################################################################*/ /*-------------------CHECK ID-----------------------*/ /* Description: This function check the user name in user_info.nc file. * Returns DD_id if exists. * Returns OK, or NOPERMISSION, or an ERROR */ int CheckID(char *NameUsr) { int i=0,Find=0; int DD_id = NOPERMISSION; int UsrRefID; /* ID of NC file */ char *ddbase; char refname[PATHLENGTH]; int UserDimID,UserLenDimID; /* Dimennsions ID */ int MemID; /* Variable ID */ size_t MaxRecords, UserLength; /* Dimensions */ size_t start[2]= {0,0}; size_t UserCount[2] = {1,0}; char UserDimName[] = "user", UserLenDimName[] = "UserLength"; /* Dimensions names */ char MemName[] = "member"; /* Variable name */ char MemChar[USRLENGTH]; int status; /*------------- Open User Reference file ---------------------------------*/ if((ddbase = getenv("DDBASE")) == NULL) { if(Verbose) fprintf(stderr,"CHECKID: No DDBASE environment.\n"); return(ENVIRERROR); } strcpy(refname,ddbase); strcat(refname,USERREFNAME); if(Verbose) fprintf(stderr," CHECKID: PATH is %s \n",refname); if((status = nc_open(refname, NC_WRITE,&UsrRefID)) != NC_NOERR) { if(Verbose) fprintf(stderr,"CHECKID: %s\n", nc_strerror(status)); return(NOUSERSFILE); } /*------------------ Define all dimensions -------------------------------*/ status = nc_inq_dimid(UsrRefID,UserDimName,&UserDimID); status = nc_inq_dimlen(UsrRefID, UserDimID, &MaxRecords); status = nc_inq_dimid(UsrRefID,UserLenDimName,&UserLenDimID); status = nc_inq_dimlen(UsrRefID, UserLenDimID, &UserLength); UserCount[1] = UserLength; /*fprintf(stderr,"CheckTicket:Rec: %d %d %d\n",MaxRecords,UserLength,PasswdLength);*/ /*------------------ Define all variables ID -------------------------------*/ status = nc_inq_varid(UsrRefID, MemName,&MemID); while((i=0) fprintf(log,"%s\t%s\t%u %s\t%s",Host,LogName,UID,right,ctime(&Clock)); else fprintf(log,"%s\t%s\t%u %s\t%s",Host,LogName,UID,noright,ctime(&Clock)); fclose(log); return; } /*---------------------LOGINS----------------------------------*/ /* Description: This function uses by ddcheck */ /* Compare two passwords */ int LOGINS(char *password) { char salt[3],newkey[13]; char pas[80]; char PName[]="Administrator password: "; int ACCESS_ = 0; /*--------------Password----------------------------*/ strncpy(salt,password,2); salt[2]='\0'; strcpy(pas,getpass(PName)); pas[strlen(pas)] = '\0'; strcpy(newkey,(char *)crypt(pas,salt)); newkey[strlen(newkey)] = '\0'; if(strcmp(newkey, password) == 0) ACCESS_=1; return ACCESS_; } /*---------------------DDCHECK----------------------------------*/ /* Description: This function check user for dd administrator access to DD_System * Require only dd password from you. * Returns 0 if o'k or -1 in case of unaccessability. * */ int ddcheck() { int FL=1,coun,i; char lines[256],ref[40]; FILE *files; /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ files=fopen("/etc/passwd","r"); while(FL != 0) { if(fgets(lines, 255, files) != NULL) { coun=(strlen(lines)-strlen(strchr(lines,':'))); strncpy(ref,lines,coun); ref[(strlen(lines)-strlen(strchr(lines,':')))]='\0'; if(strcmp(ref,"dd") == 0) { coun=(strlen(&(lines[0])+3)-strlen(strchr(&(lines[0])+3,':'))); strncpy(ref,&lines[0]+3,coun); ref[coun]='\0'; i=LOGINS(ref); } } else FL=0; } fclose(files); if(i == 0) return(-1); return(0); } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/