prva verzija za lenny
[sysadmin-cn.git] / sysadmin.c
1 /*
2  *
3  *      CARNet System Admin Utility v1.26, 2003-12-05
4  *
5  *      v1.00, 24 Jun 1996, first release
6  *      v1.10, 17 Oct 1996, directories with ownership of specific group can be created and
7  *                          deleted, accounts 'srce' & 'admin' can be added (only)
8  *      v1.15, 30 Oct 1996, admin program is now setuid!!! it gives off privileges
9  *                          when not needed
10  *      v1.20, 30 Nov 1996, name changed, logging incorporated, access list, tty checking
11  *      v1.21, 17 Dec 1996, shutdown asks for message and grace period, fixed all
12  *                          relative paths (security!), main menu slightly rearranged
13  *      v1.22, 25 Feb 1997, Digital Unix 4.0 only: use user{add,del}(), fix checking for console
14  *      v1.23, 10 Mar 1997, Again problems with OSF/DU and console checking
15  *      v1.24, 12 Mar 1997, Rewritten code for console checking (I *hate* bloody Digital!!!)
16  *      v1.25, 2002-04-28, Initial port to Debian GNU/Linux, limited functionality
17  *      v1.26, 2003-12-05, quota for Linux.  Only new style quotactl() on i386.
18  *
19  *      Written by Zlatko Calusic
20  *      Linux port Zoran Dzelajlija
21  *
22  *      SRCE, University Computing Centre, Croatia
23  *      CARNet, Croatian Academic and Research Network
24  *
25  */
26
27 /* prototypes */
28
29 #include "sysadmin.h"
30
31 /* globals */
32
33 char loginname[MAXLOGIN], group[MAXGROUP], username[MAXNAME], string[MAXSTR];
34 char directory[MAXDIR], command[MAXCOMMAND], message[MAXMESS];
35 int saveduid, grace;
36 FILE *logfile;
37 int conscheck = 1;
38
39 char *authdir, *group_fallback_dir;
40
41
42 /* body */
43
44 void logger(char *fmt, ...)
45 {
46     char *cptr, *whenptr;
47     va_list arg;
48     time_t when;
49
50     time(&when);
51     whenptr = ctime(&when);
52     if ((cptr = strchr(whenptr, '\n')))
53         *cptr = 0;
54     fprintf(logfile, "%s  ", whenptr);
55     va_start(arg, fmt);
56     while (*fmt)
57     {
58         while (*fmt && *fmt != '%')
59             fputc(*fmt++, logfile);
60         fmt++;
61         switch(*fmt++)
62         {
63             case 's':
64                 fprintf(logfile, "%s", va_arg(arg, char *));
65                 break;
66             case 'd':
67                 fprintf(logfile, "%d", va_arg(arg, int));
68                 break;
69             default:
70                 goto donefmt;
71         }
72     }   
73   donefmt:
74     va_end(arg);
75     fputc('\n', logfile);
76     fflush(logfile);
77     return;
78 }
79
80 void priv(int pvar)
81 {
82     int retval;
83
84     switch (pvar)
85     {
86         case ON:
87             retval = seteuid(0);
88             break;
89         case OFF:
90         default:
91             retval = seteuid(saveduid);
92     }
93     if (retval < 0)
94     {
95         fputs("\nInterna greska, izlazak iz programa!\n", stderr);
96         waitkey();
97         exit(0);
98     }
99     return;
100 }
101
102 int lockpw(void)
103 {
104 #if defined(ultrix)
105     if (!system("/bin/sh /etc/lockpw"))
106         return OK;
107     else
108         return ERROR;
109 #elif defined(__osf__)
110     if (!mkdir("/etc/ptmp", 0700))
111         return OK;
112     else
113         return ERROR;
114 #endif
115     return OK;
116 }
117
118 void unlockpw(void)
119 {
120 #if defined(ultrix)
121     system("/bin/sh /etc/unlockpw");
122 #elif defined(__osf__)
123     rmdir("/etc/ptmp");
124 #endif
125     return;
126 }
127
128 void consexit(void)
129 {
130     fputs("\nProgram se moze pokrenuti samo s konzole.\nIzlazak iz programa!\n", stderr);
131     exit(1);
132 }
133
134 int getch(void)
135 {
136     int ch = getchar();
137
138     if (ch != EOF && ch != '\n')
139         getchar();
140     return ch;
141 }
142
143 void clear(void)
144 {
145 #if defined(__SVR4) || defined(__osf__) || defined(__linux__)
146     system("/usr/bin/clear");
147 #elif defined(ultrix)
148     system("/usr/ucb/clear");
149 #endif
150     return;
151 }
152
153 void waitkey(void)
154 {
155     printf("\nPritisnite <RETURN> za nastavak...");
156     while (getch() != '\n');
157     return;
158 }
159
160 void enter(char *var, int size)
161 {
162     char *ptr;
163
164     fgets(var, size, stdin);
165     if ((ptr = strchr(var, '\n')))
166         *ptr = 0;
167     putchar('\n');
168     return;
169 }
170         
171 void getuser(char *text)
172 {
173     printf("%s\n\nUnesite korisnicko ime (login) > ", text);
174     enter(loginname, MAXLOGIN);
175     return;
176 }
177
178 void getgroup(char *text)
179 {
180     if (*text)
181         printf("%s\n\n", text);
182     printf("Unesite ime grupe > ");
183     enter(group, MAXGROUP);
184     return;
185 }
186
187 int getname(void)
188 {
189     int count = 0;
190
191     printf("Unesite ime i prezime korisnika > ");
192     enter(username, MAXNAME);
193     do
194     {
195         if (!isalnum(username[count]) && username[count] != ' ' && username[count] != '.' && username[count] != '-')
196         {
197             fputs("Unijeli ste nedozvoljene znakove u imenu korisnika!\n", stderr);
198             return ERROR;
199         }
200         count++;
201     } while (username[count]);
202     return OK;
203 }
204
205 int getdir(void)
206 {
207     int len;
208     printf("Unesite puni put do direktorija > ");
209     enter(directory, MAXDIR);
210     if (strchr(directory, '.') || strstr(directory, "//"))
211     {
212         fputs("Unijeli ste nedozvoljene znakove!\n", stderr);
213         return ERROR;
214     }
215     len = strlen(directory);
216     if (strstr(directory, group_fallback_dir) != directory
217         || !strcmp(directory, group_fallback_dir))
218     {
219         fprintf(stderr, "Direktorij mora biti podredjen %s direktoriju.\n",
220                 group_fallback_dir);
221         return ERROR;
222     }
223     if (directory[len] == '/')
224         directory[len] = 0;
225     return OK;
226 }
227
228 int getquota(int *soft, int *hard)
229 {
230     printf("Unesite donji limit (soft) u KB > ");
231     enter(string, MAXSTR);
232     *soft = atoi(string);
233     if (*soft < 0 || *soft > MAXQUOTA)
234         goto error;
235     if (!*soft)
236     {
237         *hard = 0;
238         return OK;
239     }
240     printf("Unesite gornji limit (hard) u KB > ");
241     enter(string, MAXSTR);
242     *hard = atoi(string);
243     if (*hard >= 0 && *hard <= MAXQUOTA)
244         return OK;
245   error:
246     fputs("Unijeli ste nedozvoljenu vrijednost!\n", stderr);
247     return ERROR;
248 }
249
250 int testuser(int flag) {
251 #if defined(__linux__)
252     char *forbidden[] = { "root", "daemon", "bin", "sys", "sync", "games", "man",
253                           "lp", "mail", "news", "uucp", "proxy", "majordom",
254                           "postgres",/* "www-data",*/ "backup", "msql", "operator",
255                           "list", "irc", "gnats", "nobody", "snort", "ntop",
256                           "mysql", "telnetd", "gdm", "freerad", "" };
257 #elif defined(__SVR4)
258     char *forbidden[] = { "root", "daemon", "bin", "sys", "adm", "lp",
259                           "smtp", "uucp", "nuucp", "listen", "nobody", "noaccess", "ftp",
260                           "gopher", "http", "" };
261 #elif defined(__osf__)
262     char *forbidden[] = { "root", "nobody", "nobodyV", "daemon", "bin",
263                           "uucp", "uucpa", "auth", "cron", "lp", "tcb", "adm", "ris", "ftp",
264                           "gopher", "http", "" };
265 #elif defined(ultrix)
266     char *forbidden[] = { "root", "field", "nobody", "operator", "ris",
267                           "daemon", "sys", "bin", "uucp", "uucpa", "sso", "news", "sccs",
268                           "ingres", "ftp", "gopher", "http", "" };
269 #endif
270     int count = 0;
271
272     if (!*loginname)
273         return ERROR;
274     if ((int) strlen(loginname) > 8) {
275         fputs("Maksimalna duzina korisnickog imena je 8 znakova!\n", stderr);
276         return ERROR;
277     }
278     do {
279         if (!islower(loginname[count]) && !isdigit(loginname[count])) {
280             fputs("Unijeli ste nedozvoljene znakove u korisnickom imenu!\n", stderr);
281             return ERROR;
282         }
283         count++;
284     } while (loginname[count]);
285     count = 0;
286     if (flag == ALL && (!strcmp(loginname, "srce") || !strcmp(loginname, "admin")))
287         goto fuckoff;
288     if (authdir) {
289         struct passwd *pwd;
290         pwd = getpwnam(loginname);
291         if (pwd && pwd->pw_dir)
292             if (strstr(pwd->pw_dir, authdir) != pwd->pw_dir)
293                 goto fuckoff;
294     }
295     while (*forbidden[count]) {
296         if (!strcmp(forbidden[count], loginname)) {
297           fuckoff:
298             fputs("Nemate ovlasti za unesenog korisnika!\n", stderr);
299             return ERROR;
300         }
301         count++;
302     }
303     return OK;
304 }               
305
306 int testgroup(void)
307 {
308 #if defined(__linux__)
309     char *forbidden[] = {"root", "daemon", "bin", "sys", "adm", "tty",
310                         "disk", "lp", "mail", "news", "uucp", "proxy",
311                         "kmem", "dialout", "fax", "voice", "cdrom", "tape",
312                         "sudo", "audio", "dip", "majordom", "postgres",
313                         "backup", "msql", "operator", "list", "irc",
314                         "gnats", "shadow", "utmp", "video", "games",
315                         "nogroup", "snort", "mysql", "telnetd", "gdm",
316                         "freerad", "viruser", "" };
317 #elif defined(__SVR4)
318     char *forbidden[] = { "root", "other", "bin", "sys", "adm", "uucp",
319                           "mail", "tty", "lp", "nuucp", "staff", "daemon", "sysadmin",
320                           "nobody", "noaccess", "wheel", "viruser", "" };
321 #elif defined(__osf__)
322     char *forbidden[] = { "system", "daemon", "uucp", "mem", "kmem", "bin",
323                           "sec", "mail", "terminal", "tty", "news", "opr", "auth", "lp", "lpr",
324                           "backup", "cron", "sysadmin", "tape", "tcb", "adm", "operator",
325                           "ris", "nobody", "nogroup", "wheel", "" };
326 #elif defined(ultrix)
327     char *forbidden[] = { "system", "daemon", "uucp", "rsrv3", "bin", "tty",
328                           "kmem", "authread", "news", "rsrv9", "staff", "ris", "guest",
329                           "operator", "admin", "nobody", "wheel", "" };
330 #endif
331     int count = 0;
332
333     if (!*group)
334         return ERROR;
335     if ((int) strlen(group) > 8) {
336         fputs("Maksimalna duzina imena grupe je 8 znakova!\n", stderr);
337         return ERROR;
338     } do {
339         if (!islower(group[count])) {
340             fputs("Unijeli ste nedozvoljene znakove u imenu grupe!\n", stderr);
341             return ERROR;
342         }
343         count++;
344     } while (group[count]);
345     count = 0;
346     while (*forbidden[count]) {
347         if (!strcmp(forbidden[count], group)) {
348             fputs("Nemate ovlasti za unesenu grupu!\n", stderr);
349             return ERROR;
350         }
351         count++;
352     }
353     if (authdir) {
354         struct group *grp = getgrnam(group);
355         if (grp && grp->gr_mem) {
356             struct passwd *pwd;
357             for (; *grp->gr_mem; grp->gr_mem++) {
358                 pwd = getpwnam(*grp->gr_mem);
359                 if (pwd && pwd->pw_dir) {
360                     if (strstr(pwd->pw_dir, authdir) != pwd->pw_dir) {
361                         fputs("Nemate ovlasti za unesenu grupu!\n", stderr);
362                         return ERROR;
363                     } else
364                         break;
365                 }
366             }
367         }
368     }
369     return OK;
370 }
371
372 int system_default_shell_check(void)
373 {
374     #ifndef __linux__
375     return 0;
376     #endif
377
378     struct stat statp;
379     statp.st_mode = 0;
380     
381     (void) stat("/etc/default/useradd", &statp);
382     /* regular file? */
383     if (! statp.st_mode) return 0;
384     if (S_ISREG(statp.st_mode)) {
385         /* XXX maybe check file contents */
386         return 1;
387     } else {
388         return 0;
389     }
390 }
391
392 void adduser(void)
393 {
394     char fullhm[200];
395     char *shellopt="";
396     int l;
397     getuser("Dodavanje korisnika:");
398     if (testuser(NOTALL) == OK && getname() == OK) {
399         strncpy(fullhm, authdir ? authdir : HM, 199);
400         l = strlen(fullhm);
401         if (fullhm[l - 1] != '/') {
402             fullhm[l] = '/';
403             fullhm[l + 1] = '\0';
404         }
405         strncat(fullhm, loginname, 199);
406         logger("USER ADD: user %s, fullname %s", loginname, username);
407 #if defined(__SVR4) || defined (__linux__)
408         if (!system_default_shell_check()) {
409             shellopt = "-s " DEFAULTSHELL;
410         }
411         sprintf(command, "/usr/sbin/useradd -m -d %s %s" \
412                 " -c \"%s\" %s", fullhm, shellopt, username, loginname);
413         printf("%s\n", command);
414         priv(ON);
415         if (!system(command)) {
416             priv(OFF);
417             #if defined (__linux__)
418             /* Avoid race */
419             sync();
420             #endif /* __linux__ */
421             sprintf(command, "/usr/bin/passwd %s", loginname);
422             priv(ON);
423             system(command);
424         }
425 #elif defined(__osf__)
426 #if defined(DU4)
427         sprintf(command, "/usr/sbin/useradd -m -s " DEFAULTSHELL \
428                 " -c \"%s\" %s", username, loginname);
429         priv(ON);
430         if (!system(command)) {
431             struct pr_passwd *pr;
432   
433             if (!(pr = getprpwnam(loginname))) {
434                 perror("getprpwnam");
435                 goto problems;
436             }
437             pr->uflg.fg_lock = 1;
438             pr->uflg.fg_min = 1;
439             pr->ufld.fd_min = 0;
440             pr->uflg.fg_expire = 1;
441             pr->ufld.fd_expire = 0;
442             pr->uflg.fg_lifetime = 1;
443             pr->ufld.fd_lifetime = 0;
444             pr->uflg.fg_max_tries = 1;
445             pr->ufld.fd_max_tries = 0;
446             if (!putprpwnam(loginname, pr)) {
447                 perror("putprpwnam");
448                 goto problems;
449             }
450             sprintf(command, "/usr/bin/passwd %s", loginname);
451             system(command);
452         }
453 #else
454         sprintf(command, "/usr/sbin/sysadm.adduser %s \"%s\"", loginname, username);
455         priv(ON);
456         system(command);
457 #endif /* DU4 */
458 #elif defined(ultrix)
459         sprintf(command, "/usr/etc/sysadm.adduser %s \"%s\"", loginname, username);
460         priv(ON);
461         system(command);
462 #endif
463 #if defined(DU4)
464       problems:
465 #endif
466         priv(OFF);
467     }
468     waitkey();
469     return;
470 }
471
472 void rmuser(void)
473 {
474     getuser("Brisanje korisnika:");
475     if (testuser(ALL) == OK) {
476         logger("USER REMOVE: user %s", loginname);
477 #if defined(__SVR4) || defined(__linux__)
478         sprintf(command, "/usr/sbin/userdel -r %s", loginname);
479 #elif defined(__osf__)
480     #if defined(DU4)
481         sprintf(command, "/usr/sbin/userdel -r %s", loginname);
482     #else       
483         sprintf(command, "/usr/sbin/sysadm.removeuser %s", loginname);
484     #endif
485 #elif defined(ultrix)
486         sprintf(command, "/usr/etc/sysadm.removeuser %s", loginname);
487 #endif
488         priv(ON);
489         system(command);
490         priv(OFF);
491     }
492     waitkey();
493     return;
494 }
495
496 void chpass(void)
497 {
498     getuser("Promjena korisnicke lozinke:");
499     if (testuser(NOTALL) == OK) {
500         logger("PASSWD CHANGE: user %s", loginname);
501         sprintf(command, "/usr/bin/passwd %s", loginname);
502         priv(ON);
503         system(command);
504         priv(OFF);
505     }
506     waitkey();
507     return;
508 }
509
510 void chquota(void)
511 {
512     int soft, hard;
513     struct passwd *pwd;
514 #if defined(__SVR4)
515     struct dqblk qval;
516     struct quotctl qstr;
517     struct stat statbuf;
518 #elif defined(ultrix)
519     struct dqblk qval;
520     struct stat statbuf;
521 #elif defined(__linux__)
522   #if defined(__i386__)
523     struct if_dqblk qval; /* sys/quota.h is wrong for 2.4.23/i386 */
524   #elif defined(__sparc__)
525     struct dqblk qval;    /* 2.4.23/sparc is different */
526   #endif
527     struct stat statbuf;
528     struct mntent *mntp;
529     FILE *fp;
530     int dev;
531     char devname[MAXDIR], mountpoint[MAXDIR], greska[MAXDIR];
532     time_t now;
533     devname[0] = '\0';
534 #endif
535
536     getuser("Promjena korisnicke quote:");
537     if (testuser(ALL) != OK) {
538         priv(OFF);
539         waitkey();
540         return;
541     }
542
543     if (!(pwd = getpwnam(loginname))) {
544         fputs("Ne postoji uneseni korisnik!\n", stderr);
545         waitkey();
546         return;
547     }
548
549 #if defined(__linux__)
550         priv(ON);
551         if (stat(pwd->pw_dir, &statbuf) < 0) {
552             priv(OFF);
553             fputs("Korisnik nema maticni direktorij!\n", stderr);
554             waitkey();
555             return;
556         } else {
557             priv(OFF);
558             dev = statbuf.st_dev;
559         }
560         
561         priv(ON);
562         if (!(fp = setmntent("/etc/mtab", "r"))) {
563             priv(OFF);
564             perror("setmntent");
565             waitkey();
566             return;
567         }       
568         while (feof(fp) == 0) {
569             mntp = getmntent(fp);
570             if (!mntp) break;
571             /* ignore special fs' like proc, devfs... */
572             if (strncmp(mntp->mnt_fsname, "/dev", 4))
573                 continue;
574             if (stat(mntp->mnt_fsname, &statbuf) < 0) {
575                 priv(OFF);
576                 perror("stat");
577                 endmntent(fp);
578                 waitkey();
579                 return;
580             }
581             if (statbuf.st_rdev == dev) {
582                 strncpy(devname, mntp->mnt_fsname, MAXDIR);
583                 strncpy(mountpoint, mntp->mnt_dir, MAXDIR);
584                 break;
585             }
586         }
587         endmntent(fp);
588         priv(OFF);
589         
590         if(! strlen(devname))
591         {
592             fputs("Nije pronadjen device na kojem je korisnikov direktorij!\n", stderr);
593             waitkey();
594             return;
595         }
596
597     #ifdef __i386__
598     /* get previous quota values and update times */
599     priv(ON);
600     if (!quotactl(QCMD(Q_GETQUOTA, USRQUOTA), devname, pwd->pw_uid, (caddr_t) &qval)) {
601         priv(OFF);
602         time(&now);
603         if (qval.dqb_bsoftlimit && (
604                                 #if defined (__i386__)
605                                 qval.dqb_curspace
606                                 #elif defined (__sparc__)
607                                 qval.dqb_curblocks
608                                 #endif
609                                     /1024) >= qval.dqb_bsoftlimit) {
610             if (!qval.dqb_btime)
611                 qval.dqb_btime = now + MAX_DQ_TIME;
612         }
613         else
614             qval.dqb_btime = 0;
615         if (qval.dqb_isoftlimit && qval.dqb_curinodes >= qval.dqb_isoftlimit) {
616             if (!qval.dqb_itime)
617                 qval.dqb_itime = now + MAX_DQ_TIME;
618         }
619         else
620                 qval.dqb_itime = 0;
621     } else {
622         priv(OFF);
623         fputs("Ne mogu utvrditi trenutne vrijednosti quote!\n", stderr);
624         waitkey();
625         return;
626     }
627     #endif
628 #endif
629
630     if (getquota(&soft, &hard) == OK) {
631         logger("QUOTA CHANGE: user %s, soft %d, hard %d", loginname, soft, hard);
632 #ifdef __SVR4
633         int i, count, fd;
634 #endif
635         if (!soft)
636             fputs("Korisnik ce imati neogranicen pristup diskovnom prostoru!\n", stderr);
637 #if defined(__linux__)
638         #if defined(__i386__)
639         /* Actually most of these are u_int64_t. */
640         qval.dqb_bsoftlimit = (u_int32_t) soft;
641         qval.dqb_bhardlimit = (u_int32_t) hard;
642         qval.dqb_isoftlimit = qval.dqb_ihardlimit = (u_int32_t) 0;
643         qval.dqb_btime = (time_t) now + MAX_DQ_TIME;
644         qval.dqb_itime = (time_t) now + MAX_IQ_TIME;
645         #if defined(__i386__)
646         /* Set limits and times */
647         qval.dqb_valid = QIF_LIMITS | QIF_TIMES;
648         #endif
649         priv(ON);
650           if (!
651           #if defined (__i386__)
652             quotactl(QCMD(Q_SETQUOTA, USRQUOTA), devname, pwd->pw_uid, (caddr_t) &qval) 
653           #elif defined (__sparc__)
654             quotactl(QCMD(Q_SETQLIM, USRQUOTA), devname, pwd->pw_uid, (caddr_t) &qval) 
655           #endif
656           )
657         #elif defined (__sparc__)
658           sprintf(command, "/usr/sbin/setquota %s -T %d %d %s", \
659                   loginname, MAX_DQ_TIME, MAX_IQ_TIME, mountpoint);
660           printf("%s\n", command);
661           priv(ON);
662           if (!system(command)) {
663             priv(OFF);
664             /* fputs("Vremensko ogranicenje quote postavljeno.\n", stderr); */
665           }
666           else {
667             priv(OFF);
668             fputs("Nije uspjelo postavljanje vremenskog ogranicenja quote!\n", stderr);
669             waitkey();
670             return;
671           }
672           sprintf(command, "/usr/sbin/setquota %s %d %d %d %d %s", \
673                   loginname, soft, hard, 0, 0, mountpoint);
674           printf("%s\n", command);
675           priv(ON);
676           if (!system(command))
677         #endif /* __sparc__ */
678         {
679             priv(OFF);
680             fputs("Quota uspjesno promijenjena.\n", stderr);
681         }
682         else {
683             priv(OFF);
684             if (errno == 3) {
685                 sprintf(greska, "Quota nije ukljucena na filesystemu %s!\n", devname);
686                 fputs(greska, stderr);
687             } else {
688                 perror("quotactl");
689             }
690         }
691 #elif defined(__SVR4)
692         qstr.uid = pwd->pw_uid;
693         for (count = 1; ; count++)
694         {
695             char *ptr;
696
697             strcpy(string, pwd->pw_dir);
698             for (i = 0; i < count; i++)
699             {
700                 ptr = strrchr(string, '/');
701                 if (ptr)
702                     *ptr = 0;
703                 else
704                     goto noquota;
705             }
706             strcat(string, "/quotas");
707             priv(ON);
708             if (!stat(string, &statbuf) && (fd = open(string, O_RDWR)) > 0)
709                 goto success;
710             priv(OFF);
711         }
712       noquota:
713         fputs("Nema quote na ovom sistemu!\n", stderr);
714         waitkey();
715         return;
716       success:
717         priv(OFF);
718         qval.dqb_bsoftlimit = (u_long) soft << 1;
719         qval.dqb_bhardlimit = (u_long) hard << 1;
720         qval.dqb_fsoftlimit = qval.dqb_fhardlimit = (u_long) 0;
721         qval.dqb_btimelimit = (u_long) DQ_BTIMELIMIT;
722         qval.dqb_ftimelimit = (u_long) DQ_FTIMELIMIT;
723         qstr.addr = (caddr_t) &qval;
724         qstr.op = Q_SETQLIM;
725         priv(ON);
726         if (!ioctl(fd, Q_QUOTACTL, &qstr))
727             fputs("Quota uspjesno promijenjena.\n", stderr);
728         else
729             perror("quotactl");
730 #elif defined(__osf__)
731         qval.dqb_bsoftlimit = (u_long) soft << 1;
732         qval.dqb_bhardlimit = (u_long) hard << 1;
733         qval.dqb_isoftlimit = qval.dqb_ihardlimit = (u_int) 0;
734         qval.dqb_btime = (time_t) MAX_DQ_TIME;
735         qval.dqb_itime = (time_t) MAX_IQ_TIME;
736         priv(ON);
737         if (!quotactl(pwd->pw_dir, QCMD(Q_SETQUOTA, USRQUOTA), pwd->pw_uid, (char *) &qval))
738             fputs("Quota uspjesno promijenjena.\n", stderr);
739         else
740             perror("quotactl");
741 #elif defined(ultrix)
742         priv(ON);
743         if (stat(pwd->pw_dir, &statbuf) < 0)
744         {
745             priv(OFF);
746             fputs("Korisnik nema maticni direktorij!\n", stderr);
747             waitkey();
748             return;
749         }
750         priv(OFF);
751         qval.dqb_bsoftlimit = (u_long) soft << 1;
752         qval.dqb_bhardlimit = (u_long) hard << 1;
753         qval.dqb_isoftlimit = qval.dqb_ihardlimit = (u_short) 0;
754         qval.dqb_bwarn = (u_char) MAX_DQ_WARN;
755         qval.dqb_iwarn = (u_char) MAX_IQ_WARN;
756         qval.dqb_curblocks = (u_long) 0;
757         qval.dqb_curinodes = (u_short) 0;
758         priv(ON);
759         if (!quota(Q_SETDLIM, pwd->pw_uid, statbuf.st_dev, (caddr_t) &qval))
760             fputs("Quota uspjesno promijenjena.\n", stderr);
761         else
762             perror("quota");
763 #endif
764     }
765     priv(OFF);
766     waitkey();
767     return;
768 }
769
770 void opgroup(void)
771 {
772     char ch;
773     int oldumask;
774
775     for (;;)
776     {
777         priv(OFF);
778         banner();
779         puts("Operacije nad grupama korisnika:\n");
780         puts("1 -- Kreiranje nove grupe");
781         puts("2 -- Dodavanje korisnika u grupu");
782         puts("3 -- Brisanje korisnika iz grupe");
783         puts("4 -- Brisanje grupe");
784         puts("5 -- Kreiranje direktorija (u koji grupa moze pisati)");
785         puts("6 -- Brisanje direktorija\n");
786         puts("7 -- Povratak u osnovni izbornik\n");
787         printf("Unesite odabir > ");
788         ch = getch();
789         clear();
790         switch(ch)
791         {
792             case '1':
793                 getgroup("Kreiranje nove grupe:");
794                 if (testgroup() == OK)
795                 {
796                     logger("GROUP CREATE: group %s", group);
797 #if defined(__SVR4) || defined(__linux__)
798                     sprintf(command, "/usr/sbin/groupadd %s", group);
799 #elif defined(__osf__)
800                     sprintf(command, "/usr/sbin/sysadm.addgroup %s", group);
801 #elif defined(ultrix)
802                     sprintf(command, "/usr/etc/sysadm.addgroup %s", group);
803 #endif
804                     priv(ON);
805                     system(command);
806                     priv(OFF);
807                 }
808                 waitkey();
809                 break;
810             case '2':
811                 getuser("Dodavanje korisnika u grupu:");
812                 if (testuser(ALL) == OK)
813                 {
814                     if (getpwnam(loginname))
815                     {
816                         getgroup("");
817                         if (testgroup() == OK)
818                         {
819                             FILE *readfp, *writefp;
820                             char line[2048];
821                             int found = 0;
822
823                             logger("ADD USER TO GROUP: user %s, group %s", loginname, group);
824                             priv(ON);
825                             if (lockpw() == ERROR)
826                             {
827                                 priv(OFF);
828 #ifdef __osf__
829                                 fputs("Probajte malo kasnije, /etc/group je u upotrebi!\n", stderr);
830 #endif
831                                 goto getout;
832                             }
833                             if (!(readfp = fopen("/etc/group", "rt")))
834                             {
835                                 priv(OFF);
836                                 fputs("Ne mogu otvoriti /etc/group datoteku!\n", stderr);
837                                 goto getout;
838                             }
839                             unlink("/tmp/group");
840                             if (!(writefp = fopen("/tmp/group", "wt")))
841                             {
842                                 fclose(readfp);
843                                 priv(OFF);
844                                 fputs("Ne mogu otvoriti privremenu datoteku!\n", stderr);
845                                 goto getout;
846                             }
847                             while (fgets(line, 2048, readfp))
848                             {
849                                 if (strstr(line, group) == line && line[strlen(group)] == ':')
850                                 {
851                                     char *ptr, left, right;
852
853                                     if ((ptr = strstr(line, loginname)))
854                                     {
855
856                                         left = *(ptr - 1);
857                                         right = *(ptr + strlen(loginname));
858                                         if ((left == ':' || left == ',') &&
859                                             (right == ',' || right == '\n'))
860                                         {
861                                             fclose(readfp);
862                                             fclose(writefp);
863                                             unlink("/tmp/group");
864                                             priv(OFF);
865                                             fputs("Korisnik je vec u unesenoj grupi!\n", stderr);
866                                             goto getout;
867                                         }
868                                     }
869                                     if ((ptr = strrchr(line, '\n')))
870                                         *ptr = 0;
871                                     else
872                                     {
873                                         fclose(readfp);
874                                         fclose(writefp);
875                                         unlink("/tmp/group");
876                                         priv(OFF);
877                                         fputs("Problem s datotekom /etc/group!\n", stderr);
878                                         goto getout;
879                                     }
880                                     if (*(ptr - 1) != ':')
881                                         strcat(line, ",");
882                                     strcat(line, loginname);
883                                     strcat(line, "\n");
884                                     found = 1;
885                                 }
886                                 fputs(line, writefp);
887                                 if (ferror(writefp))
888                                 {
889                                     fclose(readfp);
890                                     fclose(writefp);
891                                     unlink("/tmp/group");
892                                     priv(OFF);
893                                     fputs("Problem prilikom pisanja privremene datoteke!\n", stderr);
894                                     goto getout;
895                                 }
896                             }
897                             fclose(readfp);
898                             fclose(writefp);
899                             if (found)
900                             {
901                                 system("/bin/mv /tmp/group /etc/group");
902                                 priv(OFF);
903                                 fputs("Korisnik uspjesno dodan u grupu.\n", stderr);
904                             }
905                             else
906                             {
907                                 unlink("/tmp/group");
908                                 priv(OFF);
909                                 fputs("Ne postoji unesena grupa!\n", stderr);
910                             }
911                         }
912                     }
913                     else
914                         fputs("Ne postoji uneseni korisnik!\n", stderr);
915                 }
916           getout:
917                 priv(ON);
918                 unlockpw();
919                 priv(OFF);
920                 waitkey();
921                 break;
922             case '3':
923                 getuser("Brisanje korisnika iz grupe:");
924                 if (testuser(ALL) == OK)
925                 {
926                     if (getpwnam(loginname))
927                     {
928                         getgroup("");
929                         if (testgroup() == OK)
930                         {
931                             FILE *readfp, *writefp;
932                             char line[2048];
933                             int found = 0, empty = 0;
934
935                             logger("REMOVE USER FROM GROUP: user %s, group %s", loginname, group);
936                             priv(ON);
937                             if (lockpw() == ERROR)
938                             {
939                                 priv(OFF);
940 #ifdef __osf__
941                                 fputs("Probajte malo kasnije, /etc/group je u upotrebi!\n", stderr);
942 #endif
943                                 goto getout1;
944                             }
945                             if (!(readfp = fopen("/etc/group", "rt")))
946                             {
947                                 priv(OFF);
948                                 fputs("Ne mogu otvoriti /etc/group datoteku!\n", stderr);
949                                 goto getout1;
950                             }
951                             unlink("/tmp/group");
952                             if (!(writefp = fopen("/tmp/group", "wt")))
953                             {
954                                 fclose(readfp);
955                                 priv(OFF);
956                                 fputs("Ne mogu otvoriti privremenu datoteku!\n", stderr);
957                                 goto getout1;
958                             }
959                             while (fgets(line, 2048, readfp))
960                             {
961                                 if (strstr(line, group) == line && line[strlen(group)] == ':')
962                                 {
963                                     char *ptr, left, right;
964
965                                     if ((ptr = strstr(line, loginname)))
966                                     {
967                                         left = *(ptr - 1);
968                                         right = *(ptr + strlen(loginname));
969                                         if ((left == ':' || left == ',') &&
970                                             (right == ',' || right == '\n'))
971                                             goto ok;
972                                                                                         
973                                     }
974                                     fclose(readfp);
975                                     fclose(writefp);
976                                     unlink("/tmp/group");
977                                     priv(OFF);
978                                     fputs("Korisnik nije u unesenoj grupi!\n", stderr);
979                                     goto getout1;
980                                   ok:
981                                     if (right != '\n')
982                                         strcpy(ptr, ptr + strlen(loginname) + 1);
983                                     else if (left != ':')
984                                         strcpy(ptr - 1, "\n");
985                                     else
986                                     {
987                                         empty = 1;
988                                         strcpy(ptr, "\n");
989                                     }
990                                     found = 1;
991                                 }
992                                 fputs(line, writefp);
993                                 if (ferror(writefp))
994                                 {
995                                     fclose(readfp);
996                                     fclose(writefp);
997                                     unlink("/tmp/group");
998                                     priv(OFF);
999                                     fputs("Problem prilikom pisanja privremene datoteke!\n", stderr);
1000                                     goto getout1;
1001                                 }
1002                             }
1003                             fclose(readfp);
1004                             fclose(writefp);
1005                             if (found)
1006                             {
1007                                 system("/bin/mv /tmp/group /etc/group"); /* JUNK */
1008                                 priv(OFF);
1009                                 fputs("Korisnik uspjesno obrisan iz grupe.\n", stderr);
1010                                 if (empty)
1011                                     fputs("U grupi nema vise ni jednog korisnika.\n", stderr);
1012                             }
1013                             else
1014                             {
1015                                 unlink("/tmp/group");
1016                                 priv(OFF);
1017                                 fputs("Ne postoji unesena grupa!\n", stderr);
1018                             }
1019                         }
1020                     }
1021                     else
1022                         fputs("Ne postoji uneseni korisnik!\n", stderr);
1023                 }
1024           getout1:
1025                 priv(ON);
1026                 unlockpw();
1027                 priv(OFF);
1028                 waitkey();
1029                 break;
1030             case '4':
1031                 getgroup("Brisanje grupe:");
1032                 if (testgroup() == OK)
1033                 {
1034                     logger("GROUP REMOVE: group %s", group);
1035 #if defined(__SVR4) || defined(__linux__)
1036                     sprintf(command, "/usr/sbin/groupdel %s", group);
1037 #elif defined(__osf__)
1038                     sprintf(command, "/usr/sbin/sysadm.removegroup %s", group);
1039 #elif defined(ultrix)
1040                     sprintf(command, "/usr/etc/sysadm.removegroup %s", group);
1041 #endif
1042                     priv(ON);
1043                     system(command);
1044                     priv(OFF);
1045                 }
1046                 waitkey();
1047                 break;
1048             case '5':
1049                 oldumask = umask(002);
1050                 if (getdir() == OK)
1051                 {
1052                     getgroup("Grupa u cije vlasnistvo zelite staviti direktorij:");
1053                     if (testgroup() == OK)
1054                     {
1055                         struct group *grpptr;
1056                         int i, status;
1057
1058                         grpptr = getgrnam(group);
1059                         if (!grpptr)
1060                         {
1061                             fputs("Trazena grupa ne postoji!\n", stderr);
1062                             goto donedir;
1063                         }
1064                         logger("DIRECTORY CREATE: directory %s, group %s", directory, group);
1065                         for (i = 1;;i++)
1066                         {
1067                             while (directory[i] && directory[i] != '/')
1068                                 i++;
1069                             if (directory[i])
1070                             {
1071                                 directory[i] = 0;
1072                                 priv(ON);
1073                                 status = mkdir(directory, 0755);
1074                                 if (status < 0 && errno != EEXIST)
1075                                 {
1076                                     priv(OFF);
1077                                     perror("mkdir");
1078                                     goto donedir;
1079                                 }
1080                                 priv(OFF);
1081                                 directory[i] = '/';
1082                             }
1083                             else
1084                             {
1085                                 priv(ON);
1086                                 status = mkdir(directory, 0775);
1087                                 if (status < 0 && errno != EEXIST)
1088                                 {
1089                                     perror("mkdir");
1090                                     goto donedir;
1091                                 }
1092                                 errno = 0;
1093                                 if (chown(directory, (uid_t) -1, grpptr->gr_gid) < 0)
1094                                     perror("chown");
1095                                 else
1096                                     fputs("Direktorij uspjesno kreiran.\n", stderr);
1097                                 goto donedir;
1098                             }
1099                         }
1100                     }
1101                 }
1102           donedir:
1103                 priv(OFF);
1104                 umask(oldumask);
1105                 waitkey();
1106                 break;
1107             case '6':
1108                 if (getdir() == OK)
1109                 {
1110                     logger("DIRECTORY REMOVE: directory %s", directory);
1111                     priv(ON);
1112                     if (rmdir(directory) < 0)
1113                         perror("rmdir");
1114                     else
1115                         fputs("Direktorij uspjesno obrisan.\n", stderr);
1116                     priv(OFF);
1117                 }
1118                 waitkey();
1119                 break;
1120             case '7':
1121             case 'Q':
1122             case 'q':
1123                 return;
1124             default:
1125                 break;
1126         }
1127     }
1128 }
1129
1130 void shutdown(void)
1131 {
1132     int count = 0;
1133
1134     printf("Unesite poruku za korisnike > ");
1135     enter(message, MAXMESS);
1136     do
1137     {
1138         if (!isalpha(message[count]) && !isspace(message[count]) && !isdigit(message[count]) && message[count] != '.' && message[count] != ',' && message[count] != '_' && message[count] != '-' && message[count] != '=')
1139         {
1140             priv(OFF);
1141             fputs("Unijeli ste nedozvoljene znakove u poruci!\n", stderr);
1142             waitkey();
1143             return;
1144         }
1145         count++;
1146     } while (message[count]);
1147     printf("\nUnesite vrijeme kroz koje ce se racunalo zaustaviti (1 - 60 min) > ");
1148     enter(string, MAXSTR);
1149     grace = atoi(string);
1150     if (grace < MINGRACE || grace > MAXGRACE)
1151     {
1152         priv(OFF);
1153         fprintf(stderr, "Unijeli ste vrijeme koje je nula, negativno ili preveliko!\n");
1154         waitkey();
1155         return;
1156     }
1157 #if defined(__SVR4)
1158     grace *= 60;
1159 #endif
1160     puts("Pokrenuta je procedura za zaustavljanje racunala!\n");
1161     logger("SHUTDOWN!");
1162 #if defined(__SVR4)
1163     sprintf(command, "/usr/sbin/shutdown -i0 -y -g%d \"%s\"", grace, message);
1164 #elif defined(__osf__) || defined (__linux__)
1165     sprintf(command, "/sbin/shutdown -h +%d %s", grace, message);
1166 #elif defined(ultrix)
1167     sprintf(command, "/bin/shutdown -h +%d %s", grace, message);
1168 #endif
1169     priv(ON);
1170     system(command);
1171     priv(OFF);
1172   loop:
1173     sleep(10);
1174     goto loop;
1175     waitkey();
1176     return;
1177 }
1178
1179 void manual(void)
1180 {
1181     FILE* manual;
1182     char line[256];
1183     int count = 0;
1184
1185     logger("MANUAL READ");
1186     priv(ON);
1187     if (!(manual = fopen(MANFILE, "rt")))
1188     {
1189         priv(OFF);
1190         fputs("Uputstva nisu instalirana!\n", stderr);
1191         waitkey();
1192         return;
1193     }
1194     priv(OFF);
1195     while (fgets(line, 256, manual))
1196     {
1197         fputs(line, stdout);
1198         if (count++ == 21)
1199         {
1200             waitkey();
1201             clear();
1202             count = 0;
1203         }
1204     }
1205     fclose(manual);
1206     waitkey();
1207     return;
1208 }
1209
1210 void banner(void)
1211 {
1212     clear();
1213     puts(VERSION);
1214     return;
1215 }
1216
1217 void console_check(char *name)
1218 {
1219     char *cptr;
1220     int oncon = 0;
1221     struct stat statbuf;
1222     struct utmp entry;
1223     FILE *fp;
1224
1225     priv(OFF);
1226     if (isatty(0))
1227         cptr = ttyname(0);
1228     else
1229     {
1230         fprintf(stderr, "\nProblem s terminalom.\nIzlazak iz programa!\n");
1231         exit(1);
1232     }
1233     if (!cptr || strcmp(cptr, CONSOLE))
1234     {
1235         if (stat(CONSOLE, &statbuf) < 0)
1236         {
1237             fprintf(stderr, "\nNe mogu provjeriti vlasnistvo /dev/console.\nIzlazak iz programa!\n");
1238             exit(1);
1239         }
1240         if (statbuf.st_uid == saveduid)
1241             return;
1242 #if defined(__SVR4)
1243         else
1244             consexit();
1245 #endif
1246
1247 #if defined(__osf__) || defined(ultrix) || defined(__linux__)
1248         if (strstr(cptr, "/dev/") == cptr)
1249             strcpy(cptr, cptr + 5);
1250         fp = fopen(UTMP_FILE, "r");
1251         if (!fp)
1252         {
1253             priv(OFF);
1254             fprintf(stderr, "\nNe mogu otvoriti utmp datoteku.\nIzlazak iz programa!\n");
1255             exit(1);
1256         }
1257         while (fread(&entry, sizeof(entry), 1, fp))
1258         {
1259         #if defined(__linux__)
1260             entry.ut_line[UT_LINESIZE-1] = 0;
1261             entry.ut_user[UT_NAMESIZE-1] = 0;
1262             entry.ut_host[UT_HOSTSIZE-1] = 0;
1263         #else
1264             entry.ut_line[8] = 0;
1265             entry.ut_name[8] = 0;
1266             entry.ut_host[16] = 0;
1267         #endif
1268         #if defined (__linux__)
1269             if (entry.ut_type == DEAD_PROCESS)
1270                 continue;
1271             if (strncmp(entry.ut_line, cptr, UT_LINESIZE-1))
1272                 continue;
1273             if (!strncmp(entry.ut_line, "tty", 3) && \
1274                 entry.ut_line[3] >= '0' && \
1275                 entry.ut_line[3] <= '9' && \
1276                 !strncmp(entry.ut_user, name, UT_NAMESIZE-1)) {
1277                 oncon = 1;
1278                 break;
1279                 }
1280             else if (!strncmp(entry.ut_host, ":0", 2) && \
1281                      !strncmp(entry.ut_user, name, UT_NAMESIZE-1)) {
1282                 oncon = 1;
1283                 break;
1284                 }
1285             else
1286                 break; /* pravi tty, a nije na konzoli */
1287         #else
1288             if (strncmp(entry.ut_line, cptr, 8))
1289                 continue;
1290             if (!strncmp(entry.ut_line, ":0", 2) && !strncmp(entry.ut_name, name, 8))
1291                 {
1292                     oncon = 1;
1293                     break;
1294                 }
1295             if (!strncmp(entry.ut_host, ":0.0", 8) || !strncmp(entry.ut_host, "local", 8)) {
1296                     oncon = 1;
1297                     break;
1298                 }
1299         #endif /* __linux__ */
1300         }
1301         fclose(fp);
1302         if (!oncon)
1303             consexit();
1304 #endif
1305     }
1306     return;
1307 }
1308
1309
1310 int main(int argc, char **argv)
1311 {
1312     char ch, *cptr;
1313     int allowed;
1314     FILE *aclfile;
1315     FILE *conffile;
1316     struct passwd *acl = NULL;
1317     char adminlogin[64], adminfull[1024];
1318     char *p;
1319
1320 #if defined(DU4)
1321     set_auth_parameters(argc,argv);
1322 #endif
1323     umask(022);
1324     putenv("IFS=\" \"");
1325     signal(SIGINT, SIG_IGN);
1326     signal(SIGTSTP, SIG_IGN);
1327     signal(SIGQUIT, SIG_IGN);
1328     signal(SIGPIPE, SIG_IGN);
1329     saveduid = getuid();
1330     setuid(0);
1331     chmod(LOGFILE, 0600);
1332     chmod(ACLFILE, 0600);
1333     chown(LOGFILE, 0, -1);
1334     chown(ACLFILE, 0, -1);
1335     if (!(logfile = fopen(LOGFILE, "a")))
1336     {
1337         priv(OFF);
1338         perror("fopen");
1339         fprintf(stderr, "\nNe mogu otvoriti log datoteku.\nIzlazak iz programa!\n");
1340         exit(1);
1341     }
1342     if (saveduid)
1343     {
1344         if (!(aclfile = fopen(ACLFILE, "r")))
1345         {
1346             priv(OFF);
1347             perror("fopen");
1348             fprintf(stderr, "\nNe mogu otvoriti datoteku kontrole pristupa.\nIzlazak iz programa!\n");
1349             exit(1);
1350         }
1351         allowed = 0;
1352         while (fgets(string, MAXSTR, aclfile))
1353         {
1354             if (*string == '#')
1355                 continue;
1356             authdir = group_fallback_dir = NULL;
1357             for (p = string; *p && !isspace(*p); p++);
1358             cptr = p;
1359             if (*p && *p != '\n')
1360             {
1361                 while (isspace(*p))
1362                     ++p;
1363                 authdir = p;
1364                 while (*p && !isspace(*p))
1365                     ++p;
1366                 if (*p != '\n')
1367                 {
1368                     *p++ = '\0';
1369                     group_fallback_dir = p;
1370                     while (*p && !isspace(*p))
1371                         ++p;
1372                     *p = '\0';
1373                     group_fallback_dir = strdup(group_fallback_dir);
1374                 }
1375                 else
1376                     *p = '\0';
1377             }
1378             *cptr = 0;
1379             if ((acl = getpwnam(string)) && acl->pw_uid == saveduid)
1380             {
1381                 if (authdir)
1382                     authdir = strdup(authdir);
1383                 else
1384                     authdir = NULL;
1385                 allowed = 1;
1386                 break;
1387             }
1388         }
1389         fclose(aclfile);
1390         if (!group_fallback_dir)
1391             group_fallback_dir = authdir ? authdir : HM;
1392         if (!allowed)
1393         {
1394             priv(OFF);
1395             fprintf(stderr, "\nNemate dozvolu za koristenje programa.\nIzlazak iz programa!\n");
1396             exit(1);
1397         }
1398         priv(ON);
1399         if (!(conffile = fopen(OPTFILE, "r"))) {
1400             priv(OFF);
1401 /*          perror("fopen");
1402             fprintf(stderr, "Ne mogu otvoriti datoteku s konfiguracijskim opcijama.\n");
1403             sleep(2);
1404 */      }
1405         else {
1406             priv(OFF);
1407             while (fgets(string, MAXSTR, conffile)) {
1408                 p = &string[strlen(string)-1];
1409                 if (*p == '\n')
1410                     *p = '\0';
1411                 if (!strncmp(string, CONF_NOCONSOLE, MAXSTR-1)) 
1412                     conscheck = 0;
1413             }
1414             fclose(conffile);
1415         }
1416         
1417         if (!authdir && conscheck)
1418            console_check(acl->pw_name);
1419     }
1420     else
1421     {
1422         authdir = NULL;
1423         group_fallback_dir = HM;
1424         acl = getpwuid(0);
1425     }
1426     if (acl && acl->pw_name)
1427         strcpy(adminlogin, acl->pw_name);
1428     else
1429         strcpy(adminlogin, "(none)");
1430     if (acl && acl->pw_gecos)
1431         strcpy(adminfull, acl->pw_gecos);
1432     else
1433         strcpy(adminfull, "NULL");
1434     logger("ADMIN START: admin %s (%s)", adminlogin, adminfull);
1435     for (;;)
1436     {
1437         priv(OFF);
1438         banner();
1439         puts("1 -- Dodavanje korisnika");
1440         puts("2 -- Brisanje korisnika");
1441         puts("3 -- Promjena lozinke korisnika");
1442         puts("4 -- Promjena quote korisnika\n");
1443         puts("5 -- Operacije nad grupama korisnika\n");
1444         puts("6 -- Zaustavljanje i gasenje racunala\n");
1445         puts("7 -- Pomoc\n");
1446         puts("8 -- Izlazak iz administracijskog programa\n");
1447         printf("Unesite odabir > ");
1448         ch = getch();
1449         clear();
1450         switch(ch)
1451         {
1452             case '1':
1453                 adduser();
1454                 break;
1455             case '2':
1456                 rmuser();
1457                 break;
1458             case '3':
1459                 chpass();
1460                 break;
1461             case '4':
1462                 chquota();
1463                 break;
1464             case '5':
1465                 opgroup();
1466                 break;
1467             case '6':
1468                 shutdown();
1469                 break;
1470             case '7':
1471             case 'h':
1472             case '?':
1473                 manual();
1474                 break;
1475             case '0':
1476             case '8':
1477             case 'Q':
1478             case 'q':
1479                 clear();
1480                 logger("ADMIN END: admin %s (%s)", adminlogin, adminfull);
1481                 fclose(logfile);
1482                 exit(0);
1483             default:
1484                 break;
1485         }
1486     }
1487 }