1 /* vi:ai:et:ts=8 sw=2
2 */
3 /*
4 * wzdftpd - a modular and cool ftp server
5 * Copyright (C) 2002-2004 Pierre Chifflier
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * As a special exemption, Pierre Chifflier
22 * and other respective copyright holders give permission to link this program
23 * with OpenSSL, and distribute the resulting executable, without including
24 * the source code for OpenSSL in the source distribution.
25 */
26
27 #include "wzd_all.h"
28
29 #ifndef WZD_USE_PCH
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36
37 #ifdef WIN32
38 #include <winsock2.h>
39 #else
40 #include <unistd.h>
41
42 #include <sys/types.h>
43 #include <sys/socket.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
46
47 #include <pthread.h>
48 #endif
49
50 #include <errno.h>
51 #include <signal.h>
52
53 #include "wzd_structs.h"
54
55 #include "wzd_configfile.h"
56 #include "wzd_fs.h"
57 #include "wzd_group.h"
58 #include "wzd_log.h"
59 #include "wzd_misc.h"
60 #include "wzd_messages.h"
61 #include "wzd_site.h"
62 #include "wzd_site_group.h"
63 #include "wzd_user.h"
64
65 #include "wzd_debug.h"
66
67 #endif /* WZD_USE_PCH */
68
69
70 /* prototypes */
71 void do_site_help(const char *site_command, wzd_context_t * context);
72
73
74
do_site_help_grpadd(UNUSED wzd_string_t * cname,UNUSED wzd_string_t * command_line,wzd_context_t * context)75 int do_site_help_grpadd(UNUSED wzd_string_t *cname, UNUSED wzd_string_t *command_line, wzd_context_t * context)
76 {
77 send_message_with_args(501,context,"site grpadd <group> [<backend>]");
78 return 0;
79 }
80
81 /** site grpadd: adds a new group
82 *
83 * grpadd <group> [<backend>]
84 */
do_site_grpadd(wzd_string_t * cname,wzd_string_t * command_line,wzd_context_t * context)85 int do_site_grpadd(wzd_string_t *cname, wzd_string_t *command_line, wzd_context_t * context)
86 {
87 wzd_string_t *groupname;
88 int err;
89 wzd_user_t *me;
90 wzd_group_t *newgroup;
91 short is_gadmin;
92
93 me = GetUserByID(context->userid);
94 is_gadmin = (me->flags && strchr(me->flags,FLAG_GADMIN)) ? 1 : 0;
95
96 groupname = str_tok(command_line," \t\r\n");
97 if (!groupname) {
98 return do_site_help_grpadd(cname,command_line,context);
99 }
100
101 /* Gadmin ? */
102 if (is_gadmin)
103 {
104 err = send_message_with_args(501,context,"Gadmins can't add groups!");
105 str_deallocate(groupname);
106 return 0;
107 }
108
109 newgroup = group_create(str_tochar(groupname),context,mainConfig,&err);
110 if (newgroup == NULL) {
111 switch (err) {
112 case E_PARAM_NULL:
113 case E_PARAM_BIG:
114 err = send_message_with_args(501,context,"Invalid name or parameter");
115 break;
116 case E_PARAM_EXIST:
117 err = send_message_with_args(501,context,"A group already exists with this name");
118 break;
119 default:
120 err = send_message_with_args(501,context,"Error occured while creating group");
121 break;
122 }
123 str_deallocate(groupname);
124 return 0;
125 }
126
127 /* add it to backend */
128 err = backend_mod_group(mainConfig->backends->filename,0,newgroup,_GROUP_CREATE);
129
130 str_deallocate(groupname);
131
132 if (err) {
133 err = send_message_with_args(501,context,"Could not commit new group to backend");
134 group_free(newgroup);
135 } else {
136 err = send_message_with_args(200,context,"Group added");
137 /* do not free group, it is stored in registry */
138 }
139 return 0;
140 }
141
do_site_help_grpdel(UNUSED wzd_string_t * cname,UNUSED wzd_string_t * command_line,wzd_context_t * context)142 int do_site_help_grpdel(UNUSED wzd_string_t *cname, UNUSED wzd_string_t *command_line, wzd_context_t * context)
143 {
144 send_message_with_args(501,context,"site grpdel <group> [<backend>]");
145 return 0;
146 }
147
148
149 /** site grpdel: delete group
150 *
151 * grpdel <group>
152 */
do_site_grpdel(wzd_string_t * cname,wzd_string_t * command_line,wzd_context_t * context)153 int do_site_grpdel(wzd_string_t *cname, wzd_string_t *command_line, wzd_context_t * context)
154 {
155 wzd_string_t * groupname;
156 int ret;
157 wzd_user_t *me, *user;
158 short is_gadmin;
159 unsigned int gid;
160 int i;
161 /* int users_maingroup_changed[HARD_DEF_USER_MAX];*/
162 /* int num_users_maingroup_changed=0;*/
163 /* int users_without_group[HARD_DEF_USER_MAX];*/
164 /* int num_users_without_group=0;*/
165 char buffer[256];
166 int * uid_list;
167
168 me = GetUserByID(context->userid);
169 is_gadmin = (me->flags && strchr(me->flags,FLAG_GADMIN)) ? 1 : 0;
170
171 groupname = str_tok(command_line," \t\r\n");
172 if (!groupname) {
173 return do_site_help_grpdel(cname,command_line,context);
174 }
175 /* TODO read backend */
176
177 /* check if group already exists */
178 if ( (gid=GetGroupIDByName(str_tochar(groupname))) == (unsigned int)-1 ) {
179 ret = send_message_with_args(501,context,"Group does not exist");
180 str_deallocate(groupname);
181 return 0;
182 }
183 str_deallocate(groupname);
184
185 /* GAdmin ? */
186 if (is_gadmin)
187 {
188 ret = send_message_with_args(501,context,"Gadmin can't delete groups");
189 return 0;
190 }
191
192 send_message_raw("200-\r\n",context);
193 /* iterate through user list and delete all references to group */
194 uid_list = (int*)backend_get_user(GET_USER_LIST);
195 if (uid_list) {
196 for (i=0; uid_list[i] >= 0; i++)
197 {
198 user = GetUserByID(uid_list[i]);
199 if (!user || user->username[0]=='\0') continue;
200 if (is_user_in_group(user,gid))
201 {
202 /* warn for users with no groups and / or primary group
203 * changed
204 */
205 if (user->groups[0] == gid) {
206 snprintf(buffer,sizeof(buffer),"200-WARNING %s main group is changed !\r\n",user->username);
207 send_message_raw(buffer,context);
208 }
209 group_remove_user(user,gid);
210 if (user->group_num == 0) {
211 snprintf(buffer,sizeof(buffer),"200-WARNING %s has no group now !\r\n",user->username);
212 send_message_raw(buffer,context);
213 }
214 }
215 }
216 wzd_free(uid_list);
217 } /* if (uid_list) */
218 /* TODO XXX FIXME delete users belonging only to this group ? */
219
220 /* commit changes to backend */
221 backend_mod_group(mainConfig->backends->filename,gid,NULL,_GROUP_ALL);
222
223 ret = send_message_raw("200 Group deleted\r\n",context);
224 return 0;
225 }
226
do_site_help_grpren(UNUSED wzd_string_t * cname,UNUSED wzd_string_t * command_line,wzd_context_t * context)227 int do_site_help_grpren(UNUSED wzd_string_t *cname, UNUSED wzd_string_t *command_line, wzd_context_t * context)
228 {
229 send_message_with_args(501,context,"site grpren <groupname> <newgroupname>");
230 return 0;
231 }
232 /** site grpren: rename group
233 *
234 * grpren oldname newname
235 */
do_site_grpren(wzd_string_t * cname,wzd_string_t * command_line,wzd_context_t * context)236 int do_site_grpren(wzd_string_t *cname, wzd_string_t *command_line, wzd_context_t * context)
237 {
238 wzd_string_t * groupname, *newgroupname;
239 int ret;
240 wzd_user_t *me;
241 wzd_group_t *oldgroup;
242 /* unsigned int ratio;*/
243 short is_gadmin;
244
245 me = GetUserByID(context->userid);
246 is_gadmin = (me->flags && strchr(me->flags,FLAG_GADMIN)) ? 1 : 0;
247
248 groupname = str_tok(command_line," \t\r\n");
249 if (!groupname) {
250 return do_site_help_grpren(cname,command_line,context);
251 }
252 newgroupname = str_tok(command_line," \t\r\n");
253 if (!newgroupname) {
254 str_deallocate(groupname);
255 return do_site_help_grpren(cname,command_line,context);
256 }
257
258 /* check if group exists */
259 oldgroup = GetGroupByName(str_tochar(groupname));
260 str_deallocate(groupname);
261 if ( !oldgroup ) {
262 ret = send_message_with_args(501,context,"Group does not exist");
263 str_deallocate(newgroupname);
264 return 0;
265 }
266
267 /* check if group exists */
268 if ( (GetGroupByName(str_tochar(newgroupname))) ) {
269 ret = send_message_with_args(501,context,"New group already exists");
270 str_deallocate(newgroupname);
271 return 0;
272 }
273
274 if (is_gadmin)
275 {
276 ret = send_message_with_args(501,context,"GAdmins can't do that!");
277 str_deallocate(newgroupname);
278 return 0;
279 }
280
281 strncpy(oldgroup->groupname,str_tochar(newgroupname),HARD_GROUPNAME_LENGTH-1);
282 str_deallocate(newgroupname);
283
284 /* add it to backend */
285 ret = backend_mod_group(mainConfig->backends->filename,oldgroup->gid,oldgroup,_GROUP_GROUPNAME);
286
287 if (ret) {
288 ret = send_message_with_args(501,context,"Problem changing value");
289 } else {
290 ret = send_message_with_args(200,context,"Group name changed");
291 }
292 return 0;
293 }
294
do_site_ginfo(UNUSED wzd_string_t * ignored,wzd_string_t * command_line,wzd_context_t * context)295 int do_site_ginfo(UNUSED wzd_string_t *ignored, wzd_string_t *command_line, wzd_context_t * context)
296 {
297 wzd_string_t * str;
298 wzd_string_t * groupname;
299 int ret;
300 wzd_group_t * group;
301
302 groupname = str_tok(command_line," \t\r\n");
303 if (!groupname) {
304 do_site_help("ginfo",context);
305 return 0;
306 }
307 /* check if group exists (note: we rely on cache to avoid memory leak here) */
308 group=GetGroupByName(str_tochar(groupname));
309 str_deallocate(groupname);
310 if ( !group ) {
311 ret = send_message_with_args(501,context,"Group does not exist");
312 return 0;
313 }
314
315 str = config_get_string(mainConfig->cfg_file,"GLOBAL","sitefile_ginfo",NULL);
316 if (!str) {
317 ret = send_message_with_args(501,context,"File [GLOBAL] / sitefile_ginfo does not exist");
318 return 0;
319 }
320
321 /* TODO XXX FIXME gadmins can see ginfo only on their primary group ? */
322 do_site_print_file(str_tochar(str),NULL,group,context);
323
324 str_deallocate(str);
325
326 return 0;
327 }
328
do_site_gsinfo(UNUSED wzd_string_t * ignored,wzd_string_t * command_line,wzd_context_t * context)329 int do_site_gsinfo(UNUSED wzd_string_t *ignored, wzd_string_t *command_line, wzd_context_t * context)
330 {
331 wzd_string_t * str;
332 wzd_string_t * groupname;
333 int ret;
334 wzd_group_t * group;
335
336 groupname = str_tok(command_line," \t\r\n");
337 if (!groupname) {
338 do_site_help("gsinfo",context);
339 return 0;
340 }
341 /* check if group exists */
342 group = GetGroupByName(str_tochar(groupname));
343 str_deallocate(groupname);
344 if ( !group ) {
345 ret = send_message_with_args(501,context,"Group does not exist");
346 return 0;
347 }
348
349 str = config_get_string(mainConfig->cfg_file,"GLOBAL","sitefile_group",NULL);
350 if (!str) {
351 ret = send_message_with_args(501,context,"File [GLOBAL] / sitefile_group does not exist");
352 return 0;
353 }
354
355 do_site_print_file(str_tochar(str),NULL,group,context);
356
357 str_deallocate(str);
358
359 return 0;
360 }
361
do_site_help_grpaddip(UNUSED wzd_string_t * cname,UNUSED wzd_string_t * command_line,wzd_context_t * context)362 int do_site_help_grpaddip(UNUSED wzd_string_t *cname, UNUSED wzd_string_t *command_line, wzd_context_t * context)
363 {
364 send_message_with_args(501,context,"site grpaddip <group> <ip>");
365 return 0;
366 }
367
368 /** site grpaddip: adds an ip to a group
369 *
370 * grpaddip <group> <ip>
371 */
do_site_grpaddip(wzd_string_t * cname,wzd_string_t * command_line,wzd_context_t * context)372 int do_site_grpaddip(wzd_string_t *cname, wzd_string_t *command_line, wzd_context_t * context)
373 {
374 wzd_string_t * groupname, *ip;
375 int ret;
376 wzd_user_t * me;
377 wzd_group_t * group;
378 short is_gadmin;
379
380 me = GetUserByID(context->userid);
381 is_gadmin = (me->flags && strchr(me->flags,FLAG_GADMIN)) ? 1 : 0;
382
383 groupname = str_tok(command_line," \t\r\n");
384 if (!groupname) {
385 return do_site_help_grpaddip(cname,command_line,context);
386 }
387
388 /* check if group exists */
389 group=GetGroupByName(str_tochar(groupname));
390 str_deallocate(groupname);
391 if ( !group ) {
392 ret = send_message_with_args(501,context,"Group does not exist");
393 return 0;
394 }
395
396 /* GAdmin ? */
397 if (is_gadmin)
398 {
399 ret = send_message_with_args(501,context,"Gadmins can't do that!");
400 return 0;
401 }
402
403 ip = str_tok(command_line," \t\r\n");
404 if (!ip) {
405 return do_site_help_grpaddip(cname,command_line,context);
406 }
407
408 ret = ip_inlist(group->ip_list, str_tochar(ip));
409 if (ret) {
410 ret = send_message_with_args(501,context,"IP address is already included in list");
411 str_deallocate(ip);
412 return 0;
413 }
414
415 ret = ip_add_check(&group->ip_list, str_tochar(ip), 1 /* is_allowed */);
416 str_deallocate(ip);
417
418 /* commit to backend */
419 backend_mod_group(mainConfig->backends->filename,group->gid,group,_GROUP_IP);
420
421 ret = send_message_with_args(200,context,"Group IP address added");
422 return 0;
423 }
424
do_site_help_grpdelip(UNUSED wzd_string_t * cname,UNUSED wzd_string_t * command_line,wzd_context_t * context)425 int do_site_help_grpdelip(UNUSED wzd_string_t *cname, UNUSED wzd_string_t *command_line, wzd_context_t * context)
426 {
427 send_message_raw("501-Usage: site grpdelip <group> <ip>\r\n",context);
428 send_message_raw("501 or: site grpdelip <grp> <slot_number> (get it with site gsinfo <group>)\r\n",context);
429 return 0;
430 }
431
432 /** site grpdelip: removes ip from group
433 *
434 * grpdelip <group> <ip>
435 *
436 * grpdelip <group> <slot_number>
437 */
do_site_grpdelip(wzd_string_t * cname,wzd_string_t * command_line,wzd_context_t * context)438 int do_site_grpdelip(wzd_string_t *cname, wzd_string_t *command_line, wzd_context_t * context)
439 {
440 char *ptr;
441 wzd_string_t * groupname, *ip;
442 int ret;
443 wzd_user_t * me;
444 wzd_group_t * group;
445 unsigned long ul;
446 short is_gadmin;
447
448 me = GetUserByID(context->userid);
449 is_gadmin = (me->flags && strchr(me->flags,FLAG_GADMIN)) ? 1 : 0;
450
451 groupname = str_tok(command_line," \t\r\n");
452 if (!groupname) {
453 return do_site_help_grpdelip(cname,command_line,context);
454 }
455 /* check if group exists */
456 group=GetGroupByName(str_tochar(groupname));
457 str_deallocate(groupname);
458 if ( !group ) {
459 ret = send_message_with_args(501,context,"Group does not exist");
460 return 0;
461 }
462
463 ip = str_tok(command_line," \t\r\n");
464 if (!ip) {
465 return do_site_help_grpdelip(cname,command_line,context);
466 }
467
468 /* GAdmin ? */
469 if (is_gadmin)
470 {
471 ret = send_message_with_args(501,context,"Gadmins can't do that!");
472 str_deallocate(ip);
473 return 0;
474 }
475
476 /* try to take argument as a slot number */
477 ul = strtoul(str_tochar(ip),&ptr,0);
478 if (*ptr=='\0') {
479 unsigned int i;
480 struct wzd_ip_list_t * current_ip;
481
482 str_deallocate(ip);
483 ul--; /* to index slot number from 1 */
484 current_ip = group->ip_list;
485 for (i=0; i<ul && current_ip != NULL; i++) {
486 current_ip = current_ip->next_ip;
487 }
488 if (current_ip == NULL) {
489 char buffer[256];
490 snprintf(buffer,256,"IP slot %lu not found",ul+1);
491 ret = send_message_with_args(501,context,buffer);
492 return 0;
493 }
494 ret = ip_remove(&group->ip_list,current_ip->regexp);
495 if (ret != 0) {
496 char buffer[256];
497 snprintf(buffer,256,"error removing IP slot %lu",ul+1);
498 ret = send_message_with_args(501,context,buffer);
499 return 0;
500 }
501 backend_mod_group(mainConfig->backends->filename,group->gid,group,_GROUP_IP);
502 ret = send_message_with_args(200,context,"Group IP address removed");
503 return 0;
504 } /* if (*ptr=='\0') */
505
506 ret = ip_remove(&group->ip_list,str_tochar(ip));
507 if (ret != 0) {
508 char buffer[256];
509 snprintf(buffer,256,"IP %s not found",str_tochar(ip));
510 ret = send_message_with_args(501,context,buffer);
511 str_deallocate(ip);
512 return 0;
513 }
514 str_deallocate(ip);
515
516 /* commit to backend */
517 backend_mod_group(mainConfig->backends->filename,group->gid,group,_GROUP_IP);
518 ret = send_message_with_args(200,context,"Group IP address removed");
519
520 return 0;
521 }
522
do_site_help_grpratio(UNUSED wzd_string_t * cname,UNUSED wzd_string_t * command_line,wzd_context_t * context)523 int do_site_help_grpratio(UNUSED wzd_string_t *cname, UNUSED wzd_string_t *command_line, wzd_context_t * context)
524 {
525 send_message_with_args(501,context,"site grpratio <group> <ratio>");
526 return 0;
527 }
528
529 /** site grpratio: change group ratio
530 *
531 * grpratio group ratio
532 */
do_site_grpratio(wzd_string_t * cname,wzd_string_t * command_line,wzd_context_t * context)533 int do_site_grpratio(wzd_string_t *cname, wzd_string_t *command_line, wzd_context_t * context)
534 {
535 char *ptr;
536 wzd_string_t * str_ratio, *groupname;
537 int ret;
538 wzd_user_t * me;
539 wzd_group_t * group;
540 unsigned int ratio;
541 short is_gadmin;
542
543 me = GetUserByID(context->userid);
544 is_gadmin = (me->flags && strchr(me->flags,FLAG_GADMIN)) ? 1 : 0;
545
546 groupname = str_tok(command_line," \t\r\n");
547 if (!groupname) {
548 return do_site_help_grpratio(cname,command_line,context);
549 }
550 /* check if group exists */
551 group=GetGroupByName(str_tochar(groupname));
552 str_deallocate(groupname);
553 if ( !group ) {
554 ret = send_message_with_args(501,context,"Group does not exist");
555 return 0;
556 }
557
558 str_ratio = str_tok(command_line," \t\r\n");
559 if (!str_ratio) {
560 return do_site_help_grpratio(cname,command_line,context);
561 }
562
563 ratio = strtoul(str_tochar(str_ratio),&ptr,0);
564 if (*ptr!='\0') {
565 str_deallocate(str_ratio);
566 return do_site_help_grpratio(cname,command_line,context);
567 }
568 str_deallocate(str_ratio);
569
570 if (is_gadmin)
571 {
572 ret = send_message_with_args(501,context,"GAdmins can't do that!");
573 return 0;
574 }
575
576 group->ratio = ratio;
577
578 /* add it to backend */
579 ret = backend_mod_group(mainConfig->backends->filename,group->gid,group,_GROUP_RATIO);
580
581 if (ret) {
582 ret = send_message_with_args(501,context,"Problem changing value");
583 } else {
584 ret = send_message_with_args(200,context,"Group ratio changed");
585 }
586 return 0;
587 }
588
589 /** site grpkill: kill all connections from a group
590 *
591 * grpkill group
592 */
do_site_grpkill(UNUSED wzd_string_t * ignored,wzd_string_t * command_line,wzd_context_t * context)593 int do_site_grpkill(UNUSED wzd_string_t *ignored, wzd_string_t *command_line, wzd_context_t * context)
594 {
595 ListElmt * elmnt;
596 wzd_context_t * loop_context;
597 wzd_string_t * groupname;
598 int ret;
599 wzd_group_t * group;
600 int found=0;
601 wzd_user_t * user, * me;
602
603 me = GetUserByID(context->userid);
604 groupname = str_tok(command_line," \t\r\n");
605 if (!groupname) {
606 do_site_help("grpkill",context);
607 return 0;
608 }
609 /* check if group exists */
610 group=GetGroupByName(str_tochar(groupname));
611 str_deallocate(groupname);
612 if ( !group ) {
613 ret = send_message_with_args(501,context,"Group does not exist");
614 return 0;
615 }
616
617 for (elmnt=list_head(context_list); elmnt; elmnt=list_next(elmnt))
618 {
619 loop_context = list_data(elmnt);
620 if (loop_context && loop_context->magic == CONTEXT_MAGIC) {
621 user = GetUserByID(loop_context->userid);
622 if (strcmp(me->username,user->username) && is_user_in_group(user,group->gid)) {
623 found=1;
624 kill_child_new(loop_context->pid_child,context);
625 }
626 }
627 }
628
629 if (!found) { ret = send_message_with_args(501,context,"No member found!"); }
630 else { ret = send_message_with_args(200,context,"KILL signal sent"); }
631
632 return 0;
633 }
634
635
do_site_help_grpchange(UNUSED wzd_string_t * cname,UNUSED wzd_string_t * command_line,wzd_context_t * context)636 int do_site_help_grpchange(UNUSED wzd_string_t *cname, UNUSED wzd_string_t *command_line, wzd_context_t * context)
637 {
638 send_message_raw("501-site grpchange <group> <field> <value>\r\n",context);
639 send_message_raw("field can be one of:\r\n",context);
640 send_message_raw(" name changes the group name\r\n",context);
641 send_message_raw(" tagline changes the group tagline\r\n",context);
642 send_message_raw(" homedir changes group's default dir\r\n",context);
643 send_message_raw(" max_idle changes idle time\r\n",context);
644 send_message_raw(" perms changes default group permissions\r\n",context);
645 send_message_raw(" max_ul changes maximum upload speed\r\n",context);
646 send_message_raw(" max_dl changes maximum download speed\r\n",context);
647 send_message_raw(" ratio changes group default ratio\r\n",context);
648 send_message_raw(" num_logins changes maximum simultaneous logins allowed\r\n",context);
649
650 send_message_raw("501 site grpchange aborted\r\n",context);
651
652 return 0;
653 }
654
655 /** site grpchange: change a field for a group
656 *
657 * grpchange <group> <field> <value>
658 */
do_site_grpchange(wzd_string_t * cname,wzd_string_t * command_line,wzd_context_t * context)659 int do_site_grpchange(wzd_string_t *cname, wzd_string_t *command_line, wzd_context_t * context)
660 {
661 char *ptr;
662 wzd_string_t * groupname, * field, * value;
663 unsigned long mod_type, ul;
664 int ret;
665 wzd_group_t * group;
666 wzd_user_t * me;
667 gid_t gid;
668
669 me = GetUserByID(context->userid);
670
671 if (!command_line) {
672 return do_site_help_grpchange(cname,command_line,context);
673 }
674 groupname = str_tok(command_line," \t\r\n");
675 if (!groupname) {
676 return do_site_help_grpchange(cname,command_line,context);
677 }
678 field = str_tok(command_line," \t\r\n");
679 if (!field) {
680 str_deallocate(groupname);
681 return do_site_help_grpchange(cname,command_line,context);
682 }
683 value = str_tok(command_line,"\r\n");
684 if (!value) {
685 str_deallocate(groupname); str_deallocate(field);
686 return do_site_help_grpchange(cname,command_line,context);
687 }
688
689 /* check if group exists */
690 if ( (group=GetGroupByName(str_tochar(groupname)))==0 ) {
691 ret = send_message_with_args(501,context,"Group does not exist");
692 str_deallocate(groupname); str_deallocate(field); str_deallocate(value);
693 return 0;
694 }
695 str_deallocate(groupname);
696 gid = group->gid;
697
698 /* find modification type */
699 mod_type = _GROUP_NOTHING;
700
701 /* groupname */
702 if (strcmp(str_tochar(field),"name")==0) {
703 mod_type = _GROUP_GROUPNAME;
704 strncpy(group->groupname,str_tochar(value),255);
705 /* NOTE: we do not need to iterate through users, group is referenced
706 * by id, not by name
707 */
708 }
709 /* tagline */
710 else if (strcmp(str_tochar(field),"tagline")==0) {
711 mod_type = _GROUP_TAGLINE;
712 strncpy(group->tagline,str_tochar(value),255);
713 }
714 /* homedir */
715 else if (strcmp(str_tochar(field),"homedir")==0) {
716 /* check if homedir exist */
717 {
718 fs_filestat_t s;
719 if (fs_file_stat(str_tochar(value),&s) || !S_ISDIR(s.mode)) {
720 ret = send_message_with_args(501,context,"Homedir does not exist");
721 str_deallocate(field); str_deallocate(value);
722 return 0;
723 }
724 }
725 mod_type = _GROUP_DEFAULTPATH;
726 strncpy(group->defaultpath,str_tochar(value),WZD_MAX_PATH);
727 }
728 /* max_idle */
729 else if (strcmp(str_tochar(field),"max_idle")==0) {
730 ul=strtoul(str_tochar(value),&ptr,0);
731 if (!*ptr) { mod_type = _GROUP_IDLE; group->max_idle_time = ul; }
732 }
733 /* perms */
734 else if (strcmp(str_tochar(field),"perms")==0) {
735 ul=strtoul(str_tochar(value),&ptr,0);
736 if (!*ptr) { mod_type = _GROUP_GROUPPERMS; group->groupperms = ul; }
737 }
738 /* max_ul */
739 else if (strcmp(str_tochar(field),"max_ul")==0) {
740 ul=strtoul(str_tochar(value),&ptr,0);
741 if (!*ptr) { mod_type = _GROUP_MAX_ULS; group->max_ul_speed = ul; }
742 }
743 /* max_dl */
744 else if (strcmp(str_tochar(field),"max_dl")==0) {
745 ul=strtoul(str_tochar(value),&ptr,0);
746 if (!*ptr) { mod_type = _GROUP_MAX_DLS; group->max_dl_speed = ul; }
747 }
748 /* num_logins */
749 else if (strcmp(str_tochar(field),"num_logins")==0) {
750 ul=strtoul(str_tochar(value),&ptr,0);
751 if (!*ptr) { mod_type = _GROUP_NUMLOGINS; group->num_logins = (unsigned short)ul; }
752 }
753 /* ratio */
754 else if (strcmp(str_tochar(field),"ratio")==0) {
755 ul=strtoul(str_tochar(value),&ptr,0);
756 if (!*ptr) {
757 if ((!me->flags || !strchr(me->flags,FLAG_SITEOP)) && ul==0) {
758 /* wants a leech access for group, but is not siteop */
759 ret = send_message_with_args(501,context,"Only siteops can do that");
760 str_deallocate(field); str_deallocate(value);
761 return 0;
762 }
763 mod_type = _GROUP_RATIO; group->ratio = ul;
764 }
765 }
766 else {
767 str_deallocate(field); str_deallocate(value);
768 ret = send_message_with_args(501,context,"Syntax error, unknown field");
769 return 0;
770 }
771
772 /* commit to backend */
773 ret = backend_mod_group(mainConfig->backends->filename,gid,group,mod_type);
774
775 str_deallocate(field); str_deallocate(value);
776
777 if (ret)
778 ret = send_message_with_args(501,context,"Problem occured when committing");
779 else
780 ret = send_message_with_args(200,context,"Group field change successful");
781
782 return 0;
783 }
784
785
do_site_help_group(UNUSED wzd_string_t * cname,UNUSED wzd_string_t * command_line,wzd_context_t * context)786 int do_site_help_group(UNUSED wzd_string_t *cname, UNUSED wzd_string_t *command_line, wzd_context_t * context)
787 {
788 send_message_raw("501-site group <action> ...\r\n",context);
789 send_message_raw("action can be one of:\r\n",context);
790 send_message_raw(" info give group info\r\n",context);
791 send_message_raw(" add add a new group\r\n",context);
792 send_message_raw(" delete delete a group\r\n",context);
793 send_message_raw(" rename rename a group\r\n",context);
794 send_message_raw(" stat give group statistic\r\n",context);
795 send_message_raw(" addip add an IP for group\r\n",context);
796 send_message_raw(" delip delete an IP for group\r\n",context);
797 send_message_raw(" ratio set group ratio\r\n",context);
798 send_message_raw(" kill kill all group connections\r\n",context);
799 send_message_raw(" change change group fields\r\n",context);
800 send_message_raw(" list list all existing groups\r\n",context);
801 send_message_raw("use site <action> for specific action help\r\n",context);
802 send_message_raw("501 site group aborted\r\n",context);
803
804 return 0;
805 }
806
807 /* regroup all group administration in one site command */
do_site_group(wzd_string_t * cname,wzd_string_t * command_line,wzd_context_t * context)808 int do_site_group(wzd_string_t *cname, wzd_string_t *command_line, wzd_context_t * context)
809 {
810
811 wzd_string_t * cmd;
812 int ret;
813
814
815 cmd = str_tok(command_line," \t\r\n");
816
817 if( cmd == NULL ) {
818 return do_site_help_group(cname,command_line,context);
819 }
820
821 if(strcmp("info", str_tochar(cmd)) == 0) {
822 do_site_gsinfo( cmd, command_line, context );
823 } else if(strcmp( "add", str_tochar(cmd)) == 0) {
824 do_site_grpadd( cmd, command_line, context );
825 } else if(strcmp( "delete", str_tochar(cmd)) == 0) {
826 do_site_grpdel( cmd, command_line, context );
827 } else if(strcmp( "rename", str_tochar(cmd)) == 0) {
828 do_site_grpren( cmd, command_line, context );
829 } else if(strcmp( "stat", str_tochar(cmd)) == 0) {
830 do_site_ginfo( cmd, command_line, context );
831 } else if(strcmp( "addip", str_tochar(cmd)) == 0) {
832 do_site_grpaddip( cmd, command_line, context );
833 } else if(strcmp( "delip", str_tochar(cmd)) == 0) {
834 do_site_grpdelip( cmd, command_line, context );
835 } else if(strcmp( "ratio", str_tochar(cmd)) == 0) {
836 do_site_grpratio( cmd, command_line, context );
837 } else if(strcmp( "kill", str_tochar(cmd)) == 0) {
838 do_site_grpkill( cmd, command_line, context );
839 } else if(strcmp( "change", str_tochar(cmd)) == 0) {
840 do_site_grpchange( cmd, command_line, context );
841 /** \todo FIXME implement SITE GROUP LIST */
842 /* } else if(strcmp( "list", str_tochar(cmd)) == 0) {
843 do_site_print_file(mainConfig->site_config.file_groups,NULL,NULL,context);*/
844 } else {
845 ret = send_message_with_args(501,context,"site group action invalid");
846 }
847
848 str_deallocate(cmd);
849
850 return 0;
851 }
852
853