admin.c 10.1 KB
Newer Older
Linus Tolke Y's avatar
Linus Tolke Y committed
1
/*
Per Cederqvist's avatar
Per Cederqvist committed
2
 * $Id: admin.c,v 0.40 1999/06/03 22:11:04 ceder Exp $
3
 * Copyright (C) 1991, 1993-1999  Lysator Academic Computer Association.
Linus Tolke Y's avatar
Linus Tolke Y committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * This file is part of the LysKOM server.
 * 
 * LysKOM is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 1, or (at your option) 
 * any later version.
 * 
 * LysKOM is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with LysKOM; see the file COPYING.  If not, write to
 * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
 * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
 * MA 02139, USA.
 *
 * Please mail bug reports to bug-lyskom@lysator.liu.se. 
 */
Per Cederqvist's avatar
Per Cederqvist committed
25
26
27
28
29
/*
 * admin.c
 *
 * Administrative calls.
 */
Per Cederqvist's avatar
Per Cederqvist committed
30

David Byers's avatar
David Byers committed
31
32
33
34
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

35
static const char *
Per Cederqvist's avatar
Per Cederqvist committed
36
rcsid = "$Id: admin.c,v 0.40 1999/06/03 22:11:04 ceder Exp $";
37
38
#include "rcs.h"
USE(rcsid);
Per Cederqvist's avatar
Per Cederqvist committed
39

Per Cederqvist's avatar
Per Cederqvist committed
40
41
#include <stdio.h>
#include <setjmp.h>
42
43
#include <sys/types.h>
#include <time.h>
44
#include <malloc.h>
45
#include <signal.h>
Per Cederqvist's avatar
Per Cederqvist committed
46
47

#include "misc-types.h"
48
#include "s-string.h"
Per Cederqvist's avatar
Per Cederqvist committed
49
#include "kom-types.h"
Per Cederqvist's avatar
Per Cederqvist committed
50
#include "com.h"
51
#include "async.h"
Per Cederqvist's avatar
Per Cederqvist committed
52
#include "connections.h"
David Byers's avatar
Server  
David Byers committed
53
#include "manipulate.h"
Per Cederqvist's avatar
Per Cederqvist committed
54
55
#include "kom-errno.h"
#include "cache.h"
David Byers's avatar
David Byers committed
56
#include "kom-config.h"
Per Cederqvist's avatar
Per Cederqvist committed
57
58
#include "log.h"
#include "send-async.h"
59
#include "param.h"
60
#include "string-malloc.h"
61
62
#include "services.h"
#include "version-info.h"
63
#include "aux-items.h"
64
#include "unused.h"
Per Cederqvist's avatar
Per Cederqvist committed
65
#include "sigflags.h"
Per Cederqvist's avatar
Per Cederqvist committed
66

Per Cederqvist's avatar
Per Cederqvist committed
67
68
69
70
71
72
/* All of the fields in this structure except the version number
   is set from the configuration file at startup (see ramkomd.c).
   The default values are also set in ramkomd.c; the values below are
   never used.  The defaults are as of this writing (1994-01-11
   19:57:22) equal to the values below, but don't trust that that is
   so when you read this. */
73

74
75
/* Actually, these values are (except for the server compatibility
   version number) stored in the database */
76

Per Cederqvist's avatar
Per Cederqvist committed
77
78
79
80
81
82
83
84
Info kom_info = 
{
#include "version.incl"
    ,				/* version */
    1,				/* conf_pres_conf */
    2,				/* pers_pres_conf */
    3,				/* motd_conf */
    4,				/* kom_news_conf */
85
86
87
    0,				/* motd_of_lyskom */
    0,                          /* highest_aux_no */
    { 0, NULL }                 /* aux_item_list */
Per Cederqvist's avatar
Per Cederqvist committed
88
89
90
91
};

/*
 * Return info about this server. This can (and should) be done
92
 * before logging in. motd_of_lyskom should be displayed before
Per Cederqvist's avatar
Per Cederqvist committed
93
94
 * prompting for username if it isn't 0.
 */
95
96
97
98
99
100
101
extern Success
get_info_old( Info *result )
{
    *result = kom_info;
    return OK;
}

Per Cederqvist's avatar
Per Cederqvist committed
102
103
104
extern Success
get_info( Info *result )
{
105
106
    Aux_item_list   filtered;

David Byers's avatar
Server  
David Byers committed
107
    CHK_CONNECTION(FAILURE);
Per Cederqvist's avatar
Per Cederqvist committed
108
    *result = kom_info;
109
110
    filter_aux_item_list(&result->aux_item_list,
                         &filtered,
David Byers's avatar
Server  
David Byers committed
111
                         active_connection);
112
    result->aux_item_list = filtered;
Per Cederqvist's avatar
Per Cederqvist committed
113
114
115
    return OK;
}

116
117
118
119
120
121
122
123
124
125
extern Success
get_version_info( Version_info *result )
{
    /* Allowed before login. */
    result->protocol_version = kom_version_info.protocol_version;
    result->server_name = s_fcrea_str(kom_version_info.server_name);
    result->server_version = s_fcrea_str(kom_version_info.server_version);
    return OK;
}

David Byers's avatar
David Byers committed
126
127
128
129
130
131
132
133
134
/* /// */
extern Success
set_info(Info *info)
{
    Conference     *conf;
    Text_stat      *text;
    Success         tmp;

    CHK_LOGIN(FAILURE);
David Byers's avatar
Server  
David Byers committed
135
    if ( !ENA(admin, 1) )       /* OK -- in an RPC call */
David Byers's avatar
David Byers committed
136
    {
137
        err_stat = 0;
David Byers's avatar
David Byers committed
138
139
140
141
142
143
	kom_errno = KOM_PERM;
	return FAILURE;
    }

    /* Check that everything mentioned exists */

144
145
146
147
148
    if (info->motd_of_lyskom != 0)
    {
	GET_T_STAT(text, info->motd_of_lyskom, FAILURE);
    }

David Byers's avatar
David Byers committed
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    GET_C_STAT(conf, info->conf_pres_conf, FAILURE);
    GET_C_STAT(conf, info->pers_pres_conf, FAILURE);
    GET_C_STAT(conf, info->motd_conf, FAILURE);
    GET_C_STAT(conf, info->kom_news_conf, FAILURE);

    if ((tmp = set_motd_of_lyskom(info->motd_of_lyskom)) != OK)
        return tmp;

    kom_info.conf_pres_conf = info->conf_pres_conf;
    kom_info.pers_pres_conf = info->pers_pres_conf;
    kom_info.motd_conf = info->motd_conf;
    kom_info.kom_news_conf = info->kom_news_conf;

    return OK;
}

Per Cederqvist's avatar
Per Cederqvist committed
165
166
167
168
169
170
171
172
173
/* /// */
extern Success
set_motd_of_lyskom (Text_no motd)
{
    Text_stat *old_motd = NULL;
    Text_stat *new_motd = NULL;

    CHK_LOGIN(FAILURE);

David Byers's avatar
Server  
David Byers committed
174
    if ( !ENA(admin, 1) )       /* OK -- In an RPC call */
Per Cederqvist's avatar
Per Cederqvist committed
175
    {
176
        err_stat = 0;
Per Cederqvist's avatar
Per Cederqvist committed
177
178
179
180
181
182
183
184
185
	kom_errno = KOM_PERM;
	return FAILURE;
    }
    
    /* Check that the new motd exists before deleting the old*/

    if ( motd != 0 )
    {
	GET_T_STAT(new_motd, motd, FAILURE);
186
	if ( new_motd->no_of_marks >= param.max_marks_text )
Per Cederqvist's avatar
Per Cederqvist committed
187
	{
David Byers's avatar
David Byers committed
188
	    kom_log("LIMIT: set_motd_of_lyskom(%lu): New motd has %d marks.\n",
189
		(unsigned long)motd, new_motd->no_of_marks);
190
            err_stat = motd;
191
	    kom_errno = KOM_MARK_LIMIT;
Per Cederqvist's avatar
Per Cederqvist committed
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
	    return FAILURE;
	}
    }
    
    /* Unmark the previous motd if it exists. */

    if ( kom_info.motd_of_lyskom != 0
	&& (old_motd = cached_get_text_stat(kom_info.motd_of_lyskom)) != NULL)
    {
	if ( old_motd->no_of_marks > 0 )
	{
	    --old_motd->no_of_marks;
	    mark_text_as_changed( kom_info.motd_of_lyskom );
	}
	else
	{
David Byers's avatar
David Byers committed
208
	    kom_log("ERROR: do_set_motd(): Old motd not marked\n");
Per Cederqvist's avatar
Per Cederqvist committed
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
	}
    }

    /* Mark the new motd */

    if ( motd != 0 )
    {
	++new_motd->no_of_marks;
	mark_text_as_changed( motd );
    }
    
    kom_info.motd_of_lyskom = motd;

    return OK;
}




/*
 * Force all clients to read a message.
 * Sends an asynchronous message. This is obsoleted by send_message.
 */
extern Success
233
broadcast (const String message)
Per Cederqvist's avatar
Per Cederqvist committed
234
{
235
    return send_message(0, message);
Per Cederqvist's avatar
Per Cederqvist committed
236
237
238
239
240
241
}

/*
 * Send a message
 */
extern Success
242
send_message (Conf_no recipient,
Per Cederqvist's avatar
Per Cederqvist committed
243
244
	      const String message)
{
245
246
247
248
249
    Conference *conf_c;
    unsigned short end;
    unsigned short ix;
    Success retval;

David Byers's avatar
Server  
David Byers committed
250
    CHK_CONNECTION(FAILURE);
Per Cederqvist's avatar
Per Cederqvist committed
251
252
    CHK_LOGIN(FAILURE);

David Byers's avatar
David Byers committed
253
254
    /* Check that the message is not too long */

255
    if (s_strlen(message) > param.broadcast_len)
256
    {
257
        err_stat = param.broadcast_len;
258
259
260
261
	kom_errno = KOM_LONG_STR;
	return FAILURE;
    }

David Byers's avatar
David Byers committed
262
263
264
    /* If the recipient is not everyone, send it to all members */

    if (recipient != 0)
265
    {
David Byers's avatar
David Byers committed
266
267
268
269
        GET_C_STAT(conf_c, recipient, FAILURE);

        /* Check that the conference is not secret */

David Byers's avatar
Server  
David Byers committed
270
        if (access_perm(recipient, conf_c, active_connection) <= none)
David Byers's avatar
David Byers committed
271
272
273
274
275
276
277
        {
            err_stat = recipient;
            kom_errno = KOM_UNDEF_CONF;
            return FAILURE;
        }
        
        /* Conference is not secret. Traverse its members */
Per Cederqvist's avatar
Per Cederqvist committed
278

279
280
	end = conf_c->members.no_of_members;
	retval = FAILURE;
David Byers's avatar
David Byers committed
281
282
283
        err_stat = 0;
        kom_errno = KOM_MESSAGE_NOT_SENT;
        
284
285
	for (ix = 0; ix < end; ix++)
	{
David Byers's avatar
David Byers committed
286
287
            /* Don't send messages to passive members */

288
289
290
            if (conf_c->members.members[ix].type.passive)
                continue;

David Byers's avatar
David Byers committed
291
292
            /* Send message to appropriate sessions */

293
	    if (async_send_group_message(conf_c->members.members[ix].member,
294
295
296
					 recipient,
                                         ACTPERS,
                                         message,
David Byers's avatar
Server  
David Byers committed
297
                                         ENA(admin, 1)) == OK)
298
299
300
301
302
	    {
		retval = OK;
	    }
	}
    }
David Byers's avatar
David Byers committed
303
304
305
306
307
308
309
310
311
    else
    {
        /* Attempting to broadcast */

        retval =  async_send_message(recipient, ACTPERS,
                                     message, ENA(admin, 1));
    }

    return retval;
312
}
Per Cederqvist's avatar
Per Cederqvist committed
313
314
315
316
317
318


/*
 * Make LysKOM sync its files.
 */
extern Success
Per Cederqvist's avatar
Per Cederqvist committed
319
sync_kom (void) 
Per Cederqvist's avatar
Per Cederqvist committed
320
{
David Byers's avatar
David Byers committed
321
322
323
    if (!param.permissive_sync)
    {
        CHK_LOGIN(FAILURE);
David Byers's avatar
Server  
David Byers committed
324
        if ( !ENA(admin, 1) )   /* OK -- In an RPC call */
David Byers's avatar
David Byers committed
325
        {
326
            err_stat = 0;
David Byers's avatar
David Byers committed
327
328
329
330
331
            kom_errno = KOM_PERM;
            return FAILURE;
        }
    }

Per Cederqvist's avatar
Per Cederqvist committed
332
333
334
335
336
337
338
339
340
    cache_sync_all();
    dump_statistics();
    return OK;
}

/*
 * Close LysKOM. exit_val is (currently) not used. The database is synced.
 */
extern Success
341
shutdown_kom (int UNUSED(exit_val))
Per Cederqvist's avatar
Per Cederqvist committed
342
{
343
344
345
346
    char *name;
    char *user;
    char *host;

David Byers's avatar
Server  
David Byers committed
347
    CHK_CONNECTION(FAILURE);
Per Cederqvist's avatar
Per Cederqvist committed
348
    CHK_LOGIN(FAILURE);
David Byers's avatar
Server  
David Byers committed
349
    if ( !ENA(admin, 1) )       /* OK -- In an RPC call */
Per Cederqvist's avatar
Per Cederqvist committed
350
    {
351
        err_stat = 0;
Per Cederqvist's avatar
Per Cederqvist committed
352
353
354
355
	kom_errno = KOM_PERM;
	return FAILURE;
    }

356
357
358
    name = s_crea_c_str (active_connection->username);
    user = s_crea_c_str (active_connection->ident_user);
    host = s_crea_c_str (active_connection->hostname);
David Byers's avatar
David Byers committed
359
    kom_log("shutdown initiated by person %d (%s) via %s@%s.\n", 
David Byers's avatar
Server  
David Byers committed
360
            ACTPERS, name, user, host);
361
362
363
364
    string_free(host);
    string_free(user);
    string_free(name);
    
365
    go_and_die = 1;
Per Cederqvist's avatar
Per Cederqvist committed
366
367
    return OK;
}
368
369
370
371
372

extern Success
modify_server_info(Number_list      *items_to_delete,
                   Aux_item_list    *items_to_add)
{
David Byers's avatar
Server  
David Byers committed
373
    CHK_CONNECTION(FAILURE);
374
    CHK_LOGIN(FAILURE);
David Byers's avatar
David Byers committed
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389

    if (items_to_delete->length > param.max_delete_aux)
    {
        kom_errno = KOM_LONG_ARRAY;
        err_stat = param.max_delete_aux;
        return FAILURE;
    }

    if (items_to_add->length > param.max_add_aux)
    {
        kom_errno = KOM_LONG_ARRAY;
        err_stat = param.max_add_aux;
        return FAILURE;
    }

David Byers's avatar
Server  
David Byers committed
390
    if ( !ENA(admin, 1) )       /* OK -- in an RPC call */
391
392
393
394
395
396
    {
        err_stat = 0;
	kom_errno = KOM_PERM;
	return FAILURE;
    }

397
    prepare_aux_item_list(items_to_add, ACTPERS);
398
399
400
401

    if (check_delete_aux_item_list(items_to_delete,
                                   &kom_info.aux_item_list)!=OK)
        return FAILURE;
402
403
    delete_aux_item_list(items_to_delete,
                         &kom_info.aux_item_list,
David Byers's avatar
David Byers committed
404
                         INFO_OBJECT_TYPE,
405
                         0, NULL);
406
407
408

    if (system_check_add_aux_item_list(&kom_info, items_to_add, ACTPERS) != OK)
    {
409
        undelete_aux_item_list(items_to_delete, &kom_info.aux_item_list,
David Byers's avatar
David Byers committed
410
                                   INFO_OBJECT_TYPE,
411
                                   0, NULL);
412
413
414
415
        return FAILURE;
    }

    system_add_aux_item_list(&kom_info, items_to_add, ACTPERS);
David Byers's avatar
David Byers committed
416
    commit_aux_item_list(&kom_info.aux_item_list);
417
418
419
420
421
422
423
424
425

    return OK;
}



extern Success
get_collate_table (String * result)
{
David Byers's avatar
Server  
David Byers committed
426
    CHK_CONNECTION(FAILURE);
427
428
429
430
    result->string = DEFAULT_COLLAT_TAB;
    result->len = COLLAT_TAB_SIZE;
    return OK;
}