8 #include <moira_site.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
23 /* Called with moira data that is to be modified. */
25 int ModifyCallback(argc, argv, form)
36 switch (form->menu->operation) {
39 f = GetAndClearForm("mod_user");
41 display_error("Unknown form in ModifyCallback!\n");
44 f->extrastuff = form->extrastuff;
46 for (i = 0; i < U_SIGNATURE; i++)
47 if (f->inputlines[i]->type == FT_BOOLEAN)
48 f->inputlines[i]->returnvalue.booleanvalue =
49 strcmp(argv[i + offset], "0") ? 1 : 0;
51 StoreField(f, i, argv[i + offset]);
52 f->inputlines[U_SIGNATURE]->keyword_name = strsave(argv[U_SIGNATURE]);
53 f->inputlines[U_SIGNATURE]->returnvalue.booleanvalue =
54 strcmp(argv[U_SECURE], "0") ? 1 : 0;
55 f->inputlines[U_COMMENT]->keyword_name = strsave(argv[U_SECURE]);
59 count = F_MODTIME - 1;
64 form->extrastuff = NULL;
66 form->extrastuff = strsave(argv[U_UID]);
78 f = GetAndClearForm("mod_nfs");
80 display_error("Unknown form in ModifyCallback of mod_nfs\n");
83 f->extrastuff = form->extrastuff;
85 StoreField(f, 0, argv[0]);
86 StoreField(f, 1, argv[1]);
87 StoreField(f, 2, argv[2]);
88 f->inputlines[3]->keywords = nfs_states;
89 for (i = 0; nfs_states[i]; i++)
90 if (atoi(nfs_states[i]) & atoi(argv[3]))
91 StoreField(f, 3, nfs_states[i]);
92 if (atoi(argv[3]) & MR_FS_GROUPQUOTA)
93 f->inputlines[4]->returnvalue.booleanvalue = 1;
95 f->inputlines[4]->returnvalue.booleanvalue = 0;
96 StoreField(f, 5, argv[4]);
97 StoreField(f, 6, argv[5]);
109 count = PCAP_MODTIME;
112 f = GetAndClearForm("mod_service");
114 display_error("Unknown form in ModifyCallback of mod_service\n");
117 f->extrastuff = form->extrastuff;
118 f->menu = form->menu;
119 for (i = 0; i < 4; i++) StoreField(f, i, argv[i]);
120 StoreField(f, 4, argv[6]);
121 f->inputlines[5]->returnvalue.booleanvalue = atoi(argv[7]);
122 StoreField(f, 6, argv[11]);
123 StoreField(f, 7, argv[12]);
127 f = GetAndClearForm("mod_host");
129 display_error("Unknown form in ModifyCallback of mod_host\n");
132 f->extrastuff = form->extrastuff;
133 f->menu = form->menu;
134 StoreField(f, 0, argv[0]);
135 StoreField(f, 1, argv[1]);
136 f->inputlines[2]->returnvalue.booleanvalue = atoi(argv[2]);
137 StoreField(f, 3, argv[10]);
138 StoreField(f, 4, argv[11]);
139 StoreField(f, 5, argv[12]);
145 f = GetAndClearForm(fn);
147 display_error("Unknown form in ModifyCallback!\n");
150 f->extrastuff = form->extrastuff;
151 f->menu = form->menu;
152 for (i = 0; i < count; i++)
153 if (f->inputlines[i]->type == FT_BOOLEAN)
154 f->inputlines[i]->returnvalue.booleanvalue =
155 strcmp(argv[i + offset], "0") ? 1 : 0;
157 StoreField(f, i, argv[i + offset]);
159 display_error("Unknown function in ModifyCallback!\n");
165 /* Generate a new cryptographic signature for the user record */
166 SignUser(argv, offset)
175 if (strcmp(argv[U_NAME + offset], UNIQUE_LOGIN)) {
176 sprintf(buf, "%s:%s", argv[U_NAME + offset], argv[U_MITID + offset]);
178 i = GDSS_Verify(buf, strlen(buf), argv[U_SIGNATURE + offset], &si);
179 /* If it's already signed OK, don't resign it. */
180 if (i != GDSS_SUCCESS) {
181 free(argv[U_SIGNATURE + offset]);
182 argv[U_SIGNATURE + offset] = (char *) malloc(GDSS_Sig_Size() * 2);
184 i = GDSS_Sign(buf, strlen(buf), argv[U_SIGNATURE + offset]);
185 if (i != GDSS_SUCCESS)
186 com_err(program_name, gdss2et(i),
187 "Failed to create signature");
189 unsigned char newbuf[256];
191 i = GDSS_Verify(buf, strlen(buf),
192 argv[U_SIGNATURE + offset], &si);
193 if (strlen(newbuf) > 68) {
195 AppendLog("Signature too long, trying again\n");
201 AppendLog("Made signature:");hex_dump(argv[U_SIGNATURE + offset]);
203 AppendLog("Don't need to remake signature\n");
208 argv[U_SIGNATURE + offset] = strsave("");
213 /* when OK pressed */
215 MoiraFormComplete(dummy1, form)
219 process_form(form, TRUE);
223 /* when APPLY pressed */
225 MoiraFormApply(dummy1, form)
232 /* undocumented Motif internal routine to advance in tab group.
233 * In this case we're going backwards because for some reason
234 * the form advances whenever this button is pressed.
235 * However, it doesn't seem to go backwards even though source
236 * implies that it should. So we go forward until we wrap.
239 for (p = form->inputlines; *p; p++)
240 if (!((*p)->insensitive))
243 _XmMgrTraversal(form->formpointer, XmTRAVERSE_PREV_TAB_GROUP);
244 MoiraFocusOut(form->inputlines[0]->mywidget,
245 (XEvent *)NULL, (String *)NULL, 0);
246 process_form(form, FALSE);
250 int CollectData(argc, argv, form)
255 struct save_queue *sq;
257 sq = (struct save_queue *) form->extrastuff;
258 sq_save_data(sq, strsave(argv[0]));
263 /* callback when form is complete to process the data */
265 process_form(form, remove)
269 char *qy, *argv[32], buf[256], *s, **aargv;
270 int (*retfunc)(), argc, i;
273 retfunc = DisplayCallback;
276 for (i = 0; form->inputlines[i]; i++)
277 argv[i] = StringValue(form, i);
278 form->extrastuff = NULL;
279 qy = form->menu->query;
280 argc = form->menu->argc;
282 switch (form->menu->operation) {
284 if (*stringval(form, 0)) {
285 qy = "get_user_account_by_login";
286 argv[0] = stringval(form, 0);
288 } else if (*stringval(form, 3)) {
289 qy = "get_user_account_by_uid";
290 argv[0] = stringval(form, 3);
292 } else if (*stringval(form, 4)) {
293 qy = "get_user_account_by_class";
294 argv[0] = stringval(form, 4);
296 } else if (*stringval(form, 1) == 0 &&
297 *stringval(form, 2) == 0) {
298 display_error("Must fill in at least one blank.");
301 if (*stringval(form, 1) == 0)
302 StoreField(form, 1, "*");
303 if (*stringval(form, 2) == 0)
304 StoreField(form, 2, "*");
305 qy = "get_user_account_by_name";
306 argv[0] = stringval(form, 1);
307 argv[1] = stringval(form, 2);
312 argv[U_STATE][1] = 0;
313 argv[U_SECURE] = argv[U_SIGNATURE];
318 if (!strcmp(form->formname, "mod_user")) {
319 qy = "update_user_account";
320 for (i = 0; i < U_SIGNATURE; i++)
321 argv[i + 1] = StringValue(form, i);
322 argv[0] = form->extrastuff;
323 argv[U_STATE + 1][1] = 0;
324 argv[U_SIGNATURE + 1] = form->inputlines[U_SIGNATURE]->keyword_name;
325 argv[U_SECURE + 1] = StringValue(form, U_SIGNATURE);
326 if (*argv[U_SECURE + 1] == '1')
327 if (atoi(form->inputlines[U_COMMENT]->keyword_name))
328 argv[U_SECURE + 1] = form->inputlines[U_COMMENT]->keyword_name;
332 gettimeofday(&tv, NULL);
333 printf("Got %ld, %ld\n", tv.tv_sec, tv.tv_usec);
334 sprintf(buf, "%ld", tv.tv_sec);
335 argv[U_SECURE + 1] = strsave(buf);
338 argc = U_MODTIME + 1;
341 form->extrastuff = (caddr_t) "mod_user";
342 retfunc = ModifyCallback;
345 if (*stringval(form, 2)) {
346 argv[0] = stringval(form, 2);
348 argv[0] = stringval(form, 0);
349 argv[1] = stringval(form, 1);
350 form->extrastuff = NULL;
351 i = MoiraQuery("get_user_account_by_name", 2, argv,
352 ModifyCallback, (char *)form);
354 com_err(program_name, i, " looking up user by name");
357 if (form->extrastuff == NULL) {
358 display_error("Ambiguous user specification");
361 argv[0] = (char *)form->extrastuff;
363 qy = "register_user";
364 argv[1] = stringval(form, 3);
372 display_error("Expunge is not yet implemented");
376 if (!strcmp(form->formname, "mod_finger")) {
377 qy = "update_finger_by_login";
378 for (i = 0; i < F_MODTIME - 1; i++)
379 argv[i + 1] = StringValue(form, i);
380 argv[0] = form->extrastuff;
384 form->extrastuff = (caddr_t) "mod_finger";
385 retfunc = ModifyCallback;
388 if (!*stringval(form, 0))
390 if (!*stringval(form, 1))
392 AppendToLog("Kerberos mappings:\n");
395 if (!strcmp(argv[1], "POP"))
396 argv[2] = stringval(form, 3);
398 case MM_SHOW_ACE_USE:
399 if (boolval(form, 2)) {
400 sprintf(buf, "R%s", stringval(form, 0));
401 argv[0] = strsave(buf);
403 sprintf(buf, "Objects %s %s can administer\n",
404 stringval(form, 0), stringval(form, 1));
408 if (!strcmp(form->formname, "mod_list")) {
410 for (i = 0; i < L_MODTIME; i++)
411 argv[i + 1] = StringValue(form, i);
412 argv[0] = form->extrastuff;
413 argc = L_MODTIME + 1;
416 form->extrastuff = (caddr_t) "mod_list";
417 retfunc = ModifyCallback;
419 case MM_SHOW_MEMBERS:
420 if (!*stringval(form, 0)) {
421 qy = "get_lists_of_member";
422 argv[0] = stringval(form, 1);
423 sprintf(buf, "Lists of %s %s:\n", stringval(form, 1), argv[2]);
425 if (boolval(form, 3)) {
426 sprintf(buf, "R%s", stringval(form, 1));
429 argv[1] = stringval(form, 2);
432 if (boolval(form, 3)) {
433 qy = "get_end_members_of_list";
434 sprintf(buf, "Recursive members of list: %s\n", argv[0]);
436 sprintf(buf, "Members of list: %s\n", argv[0]);
440 case MM_DEL_ALL_MEMBER:
441 form->extrastuff = (caddr_t) sq_create();
442 retfunc = CollectData;
445 if (*stringval(form, 0)) {
446 qy = "get_filesys_by_label";
447 argv[0] = stringval(form, 0);
449 } else if (*stringval(form, 1)) {
450 StoreHost(form, 1, &argv[0]);
451 if (*stringval(form, 2)) {
452 qy = "get_filesys_by_nfsphys";
453 argv[1] = stringval(form, 2);
456 qy = "get_filesys_by_machine";
459 } else if (*stringval(form, 3)) {
460 qy = "get_filesys_by_group";
461 argv[0] = stringval(form, 3);
463 } else if (*stringval(form, 4)) {
464 qy = "get_filesys_by_path";
465 argv[0] = stringval(form, 4);
468 /* fall through to */
469 case MM_SHOW_FSGROUP:
470 form->extrastuff = (caddr_t) sq_create();
473 StoreHost(form, FS_MACHINE, &argv[FS_MACHINE]);
474 if (!strcmp(stringval(form, FS_TYPE), "FSGROUP") ||
475 !strcmp(stringval(form, FS_TYPE), "MUL"))
476 argv[FS_MACHINE] = "\\[NONE\\]";
479 if (!strcmp(form->formname, "mod_filsys")) {
480 qy = "update_filesys";
481 for (i = 0; i < FS_MODTIME; i++)
482 argv[i + 1] = StringValue(form, i);
483 StoreHost(form, FS_MACHINE, &argv[FS_MACHINE + 1]);
484 argv[0] = form->extrastuff;
485 argc = FS_MODTIME + 1;
488 form->extrastuff = (caddr_t) "mod_filsys";
489 retfunc = ModifyCallback;
492 argv[1] = strsave(stringval(form, 1));
493 s = index(argv[1], ' ');
495 i = MoiraQuery("remove_filesys_from_fsgroup", 2, argv, ModifyCallback,
498 com_err(program_name, i, " removing filesystem from FS group");
502 /* fall through to: */
504 /* find the two keys to sort between */
505 argv[2] = strsave(argv[2]);
506 s = index(argv[2], ' ');
509 s = index(argv[2], ')');
513 if (*argv[2] == 0) argv[2] = "A";
514 /* Finding the after key is gross. We look through the widgets
515 * in the radiobox to find the one selected and the one after
516 * it. The name of the widget is also the member name.
522 w = form->inputlines[2]->mywidget;
523 for (i = 0; i < NumChildren(w); i++) {
524 kid = NthChild(w, i);
525 if (!strcmp(XtName(kid), stringval(form, 2))) {
527 if (i < NumChildren(w)) {
528 argv[3] = strsave(XtName(NthChild(w, i)));
529 s = index(argv[3], ' ');
532 s = index(argv[3], ')');
541 printf("Don't know how to do this\007\007!\n");
543 if (*argv[3] == 0) argv[3] = "Z";
545 printf("Got before key of \"%s\" and after key of \"%s\"\n",
548 /* copy the matching chars */
549 for (s = buf; *argv[2] && *argv[2] == *argv[3]; argv[3]++)
551 /* and set the last char */
557 if (*argv[3] == 0) *argv[3] = 'Z';
558 if (*argv[3] - *argv[2] > 1) {
559 *s++ = (*argv[3] + *argv[2])/2;
565 argv[2] = strsave(buf);
568 argv[1] = strsave(stringval(form, 1));
569 s = index(argv[1], ' ');
572 case MM_SHOW_FS_ALIAS:
573 if (!*stringval(form, 0))
576 argv[2] = stringval(form, 0);
577 if (!*stringval(form, 1))
580 argv[0] = stringval(form, 1);
583 case MM_ADD_FS_ALIAS:
584 case MM_DEL_FS_ALIAS:
585 argv[0] = stringval(form, 1);
587 argv[2] = stringval(form, 0);
590 StoreHost(form, NFS_NAME, &argv[NFS_NAME]);
591 if (!*stringval(form, 1))
595 StoreHost(form, NFS_NAME, &argv[NFS_NAME]);
596 sprintf(buf, "%d", atoi(stringval(form, NFS_STATUS)) +
597 (boolval(form, 4) ? MR_FS_GROUPQUOTA : 0));
598 argv[NFS_STATUS] = buf;
599 argv[NFS_ALLOC] = stringval(form, 5);
600 argv[NFS_SIZE] = stringval(form, 6);
603 StoreHost(form, NFS_NAME, &argv[NFS_NAME]);
604 if (!strcmp(form->formname, "mod_nfs")) {
605 qy = "update_nfsphys";
607 StoreHost(form, NFS_NAME, &argv[NFS_NAME]);
608 sprintf(buf, "%d", atoi(stringval(form, NFS_STATUS)) +
609 (boolval(form, 4) ? MR_FS_GROUPQUOTA : 0));
610 argv[NFS_STATUS] = buf;
611 argv[NFS_ALLOC] = stringval(form, 5);
612 argv[NFS_SIZE] = stringval(form, 6);
615 form->extrastuff = (caddr_t) "mod_nfs";
616 retfunc = ModifyCallback;
619 StoreHost(form, NFS_NAME, &argv[NFS_NAME]);
622 if (!*stringval(form, 0))
624 if (*stringval(form, 1)) {
626 argv[2] = stringval(form, 1);
627 } else if (*stringval(form, 2)) {
629 argv[2] = stringval(form, 2);
630 } else if (!*stringval(form, 0)) {
631 display_error("Must specify something.");
634 qy = "get_quota_by_filesys";
641 StoreHost(form, 0, &argv[0]);
644 if (!strcmp(form->formname, "mod_machine")) {
645 qy = "update_machine";
646 for (i = 0; i < M_MODTIME; i++)
647 argv[i + 1] = StringValue(form, i);
648 argv[0] = form->extrastuff;
649 argc = M_MODTIME + 1;
652 StoreHost(form, 0, &argv[0]);
653 form->extrastuff = (caddr_t) "mod_machine";
654 retfunc = ModifyCallback;
657 if (!strcmp(form->formname, "mod_cluster")) {
658 qy = "update_cluster";
659 for (i = 0; i < C_MODTIME; i++)
660 argv[i + 1] = StringValue(form, i);
661 argv[0] = form->extrastuff;
662 argc = C_MODTIME + 1;
665 form->extrastuff = (caddr_t) "mod_cluster";
666 retfunc = ModifyCallback;
669 if (!*stringval(form, 0))
672 StoreHost(form, 0, &argv[0]);
673 if (!*stringval(form, 1))
675 AppendToLog("Cluster mappings:\n");
679 StoreHost(form, 0, &argv[0]);
682 if (!*stringval(form, 1))
684 AppendToLog("Cluster data:\n");
687 StoreHost(form, PCAP_SPOOL_HOST, &argv[PCAP_SPOOL_HOST]);
688 StoreHost(form, PCAP_QSERVER, &argv[PCAP_QSERVER]);
691 if (!strcmp(form->formname, "mod_printer")) {
692 qy = "update_printcap_entry";
696 form->extrastuff = (caddr_t) "mod_printer";
697 retfunc = ModifyCallback;
700 if (!strcmp(form->formname, "mod_service")) {
701 qy = "update_server_info";
705 form->extrastuff = (caddr_t) "mod_service";
706 retfunc = ModifyCallback;
708 case MM_RESET_SERVICE:
709 argv[1] = argv[2] = argv[3] = argv[4] = "0";
713 StoreHost(form, 1, &argv[1]);
714 argv[2] = argv[3] = argv[4] = argv[5] = argv[7] = argv[8] = "0";
718 StoreHost(form, 1, &argv[1]);
721 if (!*stringval(form, 0))
723 if (!*stringval(form, 1))
726 StoreHost(form, 1, &argv[1]);
729 if (!strcmp(form->formname, "mod_host")) {
730 qy = "update_server_host_info";
734 StoreHost(form, 1, &argv[1]);
735 form->extrastuff = (caddr_t) "mod_host";
736 retfunc = ModifyCallback;
739 if (!write_log_to_file(stringval(form, 0)) && remove)
740 XtUnmanageChild(form->formpointer);
743 argv[0] = form->extrastuff;
745 argv[2] = StringValue(form, 0);
746 for (s = argv[2]; *s; s++)
747 if (islower(*s)) *s = toupper(*s);
750 if (boolvalue(form, 0)) {
751 status = mr_do_update();
753 com_err(program_name, status, " starting DCM");
755 AppendToLog("DCM started.\n");
758 XtUnmanageChild(form->formpointer);
763 display_error("Unknown function in form callback.\n");
766 i = MoiraQuery(qy, argc, argv, retfunc, (char *)form);
768 com_err(program_name, i, " executing database query");
773 if (form->extrastuff && (f = GetForm((char *)(form->extrastuff)))) {
774 if (form->formpointer)
775 XtUnmanageChild(form->formpointer);
776 f->extrastuff = (caddr_t) strsave(stringval(form, 0));
777 f->menu = form->menu;
780 switch (form->menu->operation) {
783 f->inputlines[U_STATE]->keywords = user_states;
784 StoreField(f, U_STATE, user_states[atoi(stringval(f, U_STATE))]);
785 GetKeywords(f, U_CLASS, "class");
787 AppendToLog("Done.\n");
792 AppendToLog("Done.\n");
796 GetKeywords(f, L_ACE_TYPE, "ace_type");
797 f->inputlines[L_GROUP]->valuechanged = MoiraValueChanged;
798 f->inputlines[L_ACE_TYPE]->valuechanged = MoiraValueChanged;
800 AppendToLog("Done.\n");
804 GetKeywords(f, SC_TYPE, "service");
805 GetKeywords(f, SC_ACE_TYPE, "ace_type");
810 GetKeywords(f, FS_TYPE, "filesys");
811 sprintf(buf, "fs_access_%s", stringval(f, FS_TYPE));
812 GetKeywords(f, FS_ACCESS, buf);
813 GetKeywords(f, FS_L_TYPE, "lockertype");
814 if (!strcmp(stringval(f, FS_MACHINE), "[NONE]"))
815 StoreField(f, FS_MACHINE, "\\[NONE\\]");
816 f->inputlines[FS_TYPE]->valuechanged = MoiraValueChanged;
818 AppendToLog("Done.\n");
822 GetKeywords(f, 1, "mac_type");
824 AppendToLog("Done.\n");
828 f->inputlines[3]->keywords = nfs_states;
830 AppendToLog("Done.\n");
832 case MM_DEL_ALL_MEMBER:
833 argv[1] = StringValue(form, 0);
834 argv[2] = StringValue(form, 1);
835 while (sq_get_data(form->extrastuff, &(argv[0]))) {
836 sprintf(buf, "Delete %s %s from list %s?", StringValue(form, 0),
837 StringValue(form, 1), argv[0]);
838 if (!boolval(form, 2) ||
839 AskQuestion(buf, "confirm_del_all")) {
840 i = MoiraQuery("delete_member_from_list", 3, argv,
841 DisplayCallback, NULL);
843 com_err(program_name, i, " while removing member from list");
845 sprintf(buf, "Member %s %s removed from list %s.\n",
846 argv[1], argv[2], argv[0]);
852 AppendToLog("Done.\n");
855 case MM_SHOW_FSGROUP:
856 while (sq_get_data(form->extrastuff, &aargv)) {
859 sq_destroy(form->extrastuff);
867 case MM_CLEAR_SERVICE:
868 case MM_RESET_SERVICE:
891 case MM_ADD_FS_ALIAS:
892 case MM_DEL_FS_ALIAS:
907 AppendToLog("Done.\n");
912 case MM_SHOW_MEMBERS:
915 case MM_SHOW_ACE_USE:
919 CacheNewValue(GetForm(form->menu->form), (int) form->menu->accel,
920 form->extrastuff, StringValue(form, 0));
923 if (remove && form->formpointer)
924 XtUnmanageChild(form->formpointer);
939 int (*retfunc)(), argc, i;
942 retfunc = DisplayCallback;
948 switch (m->operation) {
949 case MM_SHOW_MAILLIST:
950 argv[0] = argv[1] = argv[3] = "TRUE";
952 argv[4] = "DONTCARE";
953 AppendToLog("Public Mailinglists:\n");
956 argv[0] = "def_quota";
959 AppendToLog("Services and Hosts with failed updates:\n");
960 argv[0] = argv[2] = "DONTCARE";
962 i = MoiraQuery("qualified_get_server", 3, argv, retfunc,
964 if (i && i != MR_NO_MATCH)
965 com_err(program_name, i, " executing database query");
967 argv[1] = argv[2] = argv[3] = argv[5] = "DONTCARE";
969 i = MoiraQuery("qualified_get_server_host", 6, argv, retfunc,
971 if (i && i != MR_NO_MATCH)
972 com_err(program_name, i, " executing database query");
976 case MM_HELP_WILDCARDS:
977 case MM_HELP_AUTHORS:
980 case MM_HELP_KEYBOARD:
988 display_error("Unknown function in menu callback.\n");
991 i = MoiraQuery(qy, argc, argv, retfunc, (char *)&dummy);
993 com_err(program_name, i, " executing database query");