1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
|
/*
* Program: $RCSfile: list.c,v $ $Revision: 4.6 $
*
* Author: K.Agusa agusa@nuie.nagoya-u.ac.jp
* S.Yamamoto yamamoto@nuie.nagoya-u.ac.jp
*
* Date: 1993/07/24
* Modified: $Date: 1994/12/12 14:49:12 $
* 19964/9/28
*
* Copyright: K.Agusa and S.Yamamoto 1993 - 94
*
* The X Consortium, and any party obtaining a copy of these files from
* the X Consortium, directly or indirectly, is granted, free of charge,
* a full and unrestricted irrevocable, world-wide, paid up, royalty-free,
* nonexclusive right and license to deal in this software and documentation
* files (the "Software"), including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons who receive copies from any such
* party to do so. This license includes without limitation a license to do
* the foregoing actions under any patents of the party supplying this
* software to the X Consortium.
*/
#ifndef lint
static char rcsid[] =
"$Id: list.c,v 4.6 1994/12/12 14:49:12 yamamoto Exp $";
#endif /* not lint */
#include <sys/param.h>
#include <netinet/in.h>
#include <netdb.h> /* For gethostbyname() and gethostbyaddr(). */
#include <pwd.h> /* For getpwuid(). */
#include <stdio.h>
#include "youbin.h"
#include "server.h"
#if defined(sun)
#define BUGGY_RUSEROK /* To avoid modificaion of uid by ruserok(). */
#endif
extern SockAddr ca;
extern char *NAK_reason;
typedef struct list_buff *ListP;
struct list_buff {
ListP next_list;
User users[MAX_USER];
State states[MAX_STATE];
};
ListP TopList = NULL;
UserP UserAlist; /* User availabe list. */
User UserList; /* User list. Note not pointer. */
StateP StateAlist; /* State available list. */
/*
* User sturucture.
*/
void
init_users()
{
ListP ptr;
while( TopList != NULL ){
ptr = TopList->next_list; /* save pointer */
free( TopList ); /* free the list */
TopList = ptr; /* restore pointer */
}
UserAlist = NULL;
StateAlist = NULL;
UserList.next = NULL;
}
alloc_list_buff()
{
ListP ptr;
int i;
if(( ptr =(ListP) malloc( sizeof ( struct list_buff ))) == NULL ){
return FALSE;
}
ptr -> next_list = TopList; /* for ID check */
TopList = ptr;
for (i = 0; i < MAX_USER - 1; i++) {
ptr -> users[i].next = &( ptr -> users[i + 1] );
}
ptr -> users[MAX_USER - 1].next = UserAlist;
UserAlist = ptr -> users;
/* Initialize states. */
for (i = 0; i < MAX_STATE - 1; i++) {
ptr -> states[i].next = &( ptr -> states[i + 1] );
ptr -> states[i].state = NOT_USED;
}
ptr -> states[MAX_STATE - 1].state = NOT_USED;
ptr -> states[MAX_STATE - 1].next = StateAlist;
StateAlist = ptr -> states;
return TRUE;
}
StateP
make_user(char *uname, enum a_mode auth_mode)
{
/* If this function return NULL then reason shows why it fails. */
State dummy;
StateP sp, spp, spx;
UserP up;
if((sp = new_state()) == NULL) { /* Get state space */
strcpy( NAK_reason, "No space for State" );
return (NULL);
}
/* Check user list. */
if((up = find_user(uname)) != NULL) { /* Already registered. */
for (dummy.next = up->stat, spp = &dummy;
(spx = spp->next) != NULL; spp = spx) {
if (check_ca(&(spx->ca)) != FALSE) { /* Existing state. */
dispose_state(sp);
return (spx);
}
}
spp->next = sp; /* link state at the last */
} else { /* New user. Make user entry. */
if((up = new_user(uname)) == NULL) { /* Fail to create user. */
strcpy( NAK_reason, "No space for User" );
dispose_state(sp);
return (NULL);
}
up->stat = sp; /* link state at the top */
}
sp->ca = ca; /* Save port address. */
sp->parent = up;
sp->mode.auth_mode = auth_mode;
#ifdef VER2_BC
sp->option.ver2_user = 0; /* Anyway clear & set by ver2_proc */
#endif
return (sp);
}
UserP
find_user(name)
char *name;
{
UserP up;
for (up = UserList.next; up != NULL; up = up->next) {
if (strcmp(up->name, name) == 0) {
return (up); /* Find. */
}
}
return (NULL);
}
UserP
new_user(name)
char *name;
{
UserP new;
while((new = UserAlist) == NULL) {
if( alloc_list_buff() == FALSE ){
warn_log("No more space for User\n");
return NULL;
}
}
UserAlist = new->next;
strcpy(new->name, name);
new->next = UserList.next;
UserList.next = new;
return (new);
}
void
dispose_user(up)
UserP up;
{
up->next = UserAlist;
UserAlist = up;
}
/*
* State sturucture.
*/
StateP
new_state()
{
StateP new;
while((new = StateAlist) == NULL) {
if( alloc_list_buff() == FALSE ){
warn_log("No more space for State\n");
return NULL;
}
}
StateAlist = new->next;
new->next = NULL;
new->state = PW1;
return (new);
}
void
dispose_state(sp)
StateP sp;
{
sp->state = NOT_USED;
sp->next = StateAlist;
StateAlist = sp;
}
void
del_state(id)
StateP id;
{
State dummy;
StateP s, sp;
UserP u, up, user;
user = id->parent;
dummy.next = user->stat;
for (sp = &dummy; (s = sp->next) != NULL; sp = s) {
if (s == id) {
sp->next = s->next;
dispose_state(s);
if ((user->stat = dummy.next) == NULL) {
for (up = &UserList; (u = up->next) != NULL; up = u) {
if (u == user) {
up->next = u->next;
dispose_user(u);
return;
}
}
warn_log("Can not find user: [%ld]\n", (long)id);
}
return;
}
}
warn_log("Can not find user: [%ld]\n", (long)id);
}
StateP
get_id(buff)
char *buff;
{
StateP sp;
ListP lp;
/* Note, should check ca. */
sp = (StateP)atol(buff);
for( lp = TopList; lp != NULL; lp = lp -> next_list ){
if( sp < lp->states || &(lp->states[MAX_STATE - 1]) < sp )
continue;
if((((long)sp - (long)lp->states) % sizeof(State)) == 0 &&
sp->state != NOT_USED) {
return sp;
} else {
return (NULL);
}
}
return ( NULL );
}
|