5 * \defgroup AdminTasks Administrative screen to add/change/delete user accounts
6 * \ingroup CitadelConfig
12 #include "webserver.h"
16 * \brief show a list of available users to edit them
17 * \param message the header message???
18 * \param preselect which user should be selected in the browser
20 void select_user_to_edit(char *message, char *preselect)
25 output_headers(1, 0, 0, 0, 1, 0);
26 do_template("edituser_select", NULL);
31 output_headers(1, 1, 2, 0, 0, 0);
32 wprintf("<div id=\"banner\">\n");
33 wprintf("<img src=\"static/usermanag_48x.gif\">");
35 wprintf(_("Edit or delete users"));
39 wprintf("<div id=\"content\" class=\"service\">\n");
41 if (message != NULL) wprintf(message);
43 wprintf("<table border=0 cellspacing=10><tr valign=top><td>\n");
45 svput("BOXTITLE", WCS_STRING, _("Add users"));
46 do_template("beginbox", NULL);
48 wprintf(_("To create a new user account, enter the desired "
49 "user name in the box below and click 'Create'."));
50 wprintf("<br /><br />");
52 wprintf("<center><form method=\"POST\" action=\"create_user\">\n");
53 wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
54 wprintf(_("New user: "));
55 wprintf("<input type=\"text\" name=\"username\"><br />\n"
56 "<input type=\"submit\" name=\"create_button\" value=\"%s\">"
57 "</form></center>\n", _("Create"));
59 do_template("endbox", NULL);
63 svput("BOXTITLE", WCS_STRING, _("Edit or Delete users"));
64 do_template("beginbox", NULL);
66 wprintf(_("To edit an existing user account, select the user "
67 "name from the list and click 'Edit'."));
68 wprintf("<br /><br />");
71 "<form method=\"POST\" action=\"display_edituser\">\n");
72 wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
73 wprintf("<select name=\"username\" size=10 style=\"width:100%%\">\n");
75 serv_getln(buf, sizeof buf);
77 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
78 extract_token(username, buf, 0, '|', sizeof username);
80 if (preselect != NULL)
81 if (!strcasecmp(username, preselect))
88 wprintf("</select><br />\n");
90 wprintf("<input type=\"submit\" name=\"edit_config_button\" value=\"%s\">", _("Edit configuration"));
91 wprintf("<input type=\"submit\" name=\"edit_abe_button\" value=\"%s\">", _("Edit address book entry"));
92 wprintf("<input type=\"submit\" name=\"delete_button\" value=\"%s\" "
93 "onClick=\"return confirm('%s');\">", _("Delete user"), _("Delete this user?"));
94 wprintf("</form></center>\n");
95 do_template("endbox", NULL);
97 wprintf("</td></tr></table>\n");
104 typedef struct _UserListEntry {
114 /* Just available for Single users to view: */
120 UserListEntry* NewUserListOneEntry(StrBuf *SerializedUser)
124 if (StrLength(SerializedUser) < 8)
127 ul = (UserListEntry*) malloc(sizeof(UserListEntry));
128 ul->UserName = NewStrBuf();
129 ul->LastLogon = NewStrBuf();
130 ul->Passvoid = NewStrBuf();
132 StrBufExtract_token(ul->UserName, SerializedUser, 0, '|');
133 StrBufExtract_token(ul->Passvoid, SerializedUser, 1, '|');
134 ul->Flags = (unsigned int)StrBufExtract_long(SerializedUser, 2, '|');
135 ul->nLogons = StrBufExtract_int(SerializedUser, 3, '|');
136 ul->nPosts = StrBufExtract_int(SerializedUser, 4, '|');
137 ul->AccessLevel = StrBufExtract_int(SerializedUser, 5, '|');
138 ul->UID = StrBufExtract_int(SerializedUser, 6, '|');
139 StrBufExtract_token(ul->LastLogon, SerializedUser, 7, '|');
140 ul->LastLogonT = StrTol(ul->LastLogon);
141 ul->DaysTillPurge = StrBufExtract_int(SerializedUser, 8, '|');
145 void DeleteUserListEntry(void *vUserList)
147 UserListEntry *ul = (UserListEntry*) vUserList;
148 FreeStrBuf(&ul->UserName);
149 FreeStrBuf(&ul->LastLogon);
150 FreeStrBuf(&ul->Passvoid);
154 UserListEntry* NewUserListEntry(StrBuf *SerializedUserList)
158 if (StrLength(SerializedUserList) < 8)
161 ul = (UserListEntry*) malloc(sizeof(UserListEntry));
162 ul->UserName = NewStrBuf();
163 ul->LastLogon = NewStrBuf();
164 ul->Passvoid = NewStrBuf();
166 StrBufExtract_token(ul->UserName, SerializedUserList, 0, '|');
167 ul->AccessLevel = StrBufExtract_int(SerializedUserList, 1, '|');
168 ul->UID = StrBufExtract_int(SerializedUserList, 2, '|');
169 StrBufExtract_token(ul->LastLogon, SerializedUserList, 3, '|');
170 /// TODO: ul->LastLogon -> ulLastLogonT
171 ul->nLogons = StrBufExtract_int(SerializedUserList, 4, '|');
172 ul->nPosts = StrBufExtract_int(SerializedUserList, 5, '|');
173 StrBufExtract_token(ul->Passvoid, SerializedUserList, 6, '|');
175 ul->DaysTillPurge = -1;
182 int CompareUserListName(const void *vUser1, const void *vUser2)
184 UserListEntry *u1 = (UserListEntry*) vUser1;
185 UserListEntry *u2 = (UserListEntry*) vUser2;
187 return strcmp(ChrPtr(u1->UserName), ChrPtr(u2->UserName));
189 int CompareUserListNameRev(const void *vUser1, const void *vUser2)
191 UserListEntry *u1 = (UserListEntry*) vUser1;
192 UserListEntry *u2 = (UserListEntry*) vUser2;
193 return strcmp(ChrPtr(u2->UserName), ChrPtr(u1->UserName));
197 * Sort by AccessLevel
199 int CompareAccessLevel(const void *vUser1, const void *vUser2)
201 UserListEntry *u1 = (UserListEntry*) vUser1;
202 UserListEntry *u2 = (UserListEntry*) vUser2;
204 return (u1->AccessLevel > u2->AccessLevel);
206 int CompareAccessLevelRev(const void *vUser1, const void *vUser2)
208 UserListEntry *u1 = (UserListEntry*) vUser1;
209 UserListEntry *u2 = (UserListEntry*) vUser2;
211 return (u2->AccessLevel > u1->AccessLevel);
218 int CompareUID(const void *vUser1, const void *vUser2)
220 UserListEntry *u1 = (UserListEntry*) vUser1;
221 UserListEntry *u2 = (UserListEntry*) vUser2;
223 return (u1->UID > u2->UID);
225 int CompareUIDRev(const void *vUser1, const void *vUser2)
227 UserListEntry *u1 = (UserListEntry*) vUser1;
228 UserListEntry *u2 = (UserListEntry*) vUser2;
230 return (u2->UID > u1->UID);
234 * Sort By Date /// TODO!
236 int CompareLastLogon(const void *vUser1, const void *vUser2)
238 UserListEntry *u1 = (UserListEntry*) vUser1;
239 UserListEntry *u2 = (UserListEntry*) vUser2;
241 return (u1->LastLogonT > u2->LastLogonT);
243 int CompareLastLogonRev(const void *vUser1, const void *vUser2)
245 UserListEntry *u1 = (UserListEntry*) vUser1;
246 UserListEntry *u2 = (UserListEntry*) vUser2;
248 return (u2->LastLogonT > u1->LastLogonT);
252 * Sort By Number of Logons
254 int ComparenLogons(const void *vUser1, const void *vUser2)
256 UserListEntry *u1 = (UserListEntry*) vUser1;
257 UserListEntry *u2 = (UserListEntry*) vUser2;
259 return (u1->nLogons > u2->nLogons);
261 int ComparenLogonsRev(const void *vUser1, const void *vUser2)
263 UserListEntry *u1 = (UserListEntry*) vUser1;
264 UserListEntry *u2 = (UserListEntry*) vUser2;
266 return (u2->nLogons > u1->nLogons);
270 * Sort By Number of Posts
272 int ComparenPosts(const void *vUser1, const void *vUser2)
274 UserListEntry *u1 = (UserListEntry*) vUser1;
275 UserListEntry *u2 = (UserListEntry*) vUser2;
277 return (u1->nPosts > u2->nPosts);
279 int ComparenPostsRev(const void *vUser1, const void *vUser2)
281 UserListEntry *u1 = (UserListEntry*) vUser1;
282 UserListEntry *u2 = (UserListEntry*) vUser2;
284 return (u2->nPosts > u1->nPosts);
288 HashList *iterate_load_userlist(WCTemplateToken *Token)
300 serv_getln(buf, sizeof buf);
302 Hash = NewHash(1, NULL);
305 while ((len = StrBuf_ServGetln(Buf),
306 strcmp(ChrPtr(Buf), "000"))) {
307 ul = NewUserListEntry(Buf);
310 nUsed = GetCount(Hash);
311 nUsed = snprintf(nnn, sizeof(nnn), "%d", nUsed+1);
312 Put(Hash, nnn, nUsed, ul, DeleteUserListEntry);
315 Order = ibstr("SortOrder");
316 switch (ibstr("SortBy")){
318 SortByPayload(Hash, (Order)?
320 CompareUserListNameRev);
322 case 2: /*AccessLevel*/
323 SortByPayload(Hash, (Order)?
325 CompareAccessLevelRev);
328 SortByPayload(Hash, (Order)?
333 SortByPayload(Hash, (Order)?
337 case 5: /*LastLogon*/
338 SortByPayload(Hash, (Order)?
340 CompareLastLogonRev);
342 case 6: /* nLogons */
343 SortByPayload(Hash, (Order)?
348 SortByPayload(Hash, (Order)?
359 void tmplput_USERLIST_UserName(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
361 UserListEntry *ul = (UserListEntry*) Context;
363 StrBufAppendBuf(Target, ul->UserName, 0);
366 void tmplput_USERLIST_AccessLevelNo(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
368 UserListEntry *ul = (UserListEntry*) Context;
370 StrBufAppendPrintf(Target, "%d", ul->AccessLevel, 0);
373 void tmplput_USERLIST_AccessLevelStr(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
375 UserListEntry *ul = (UserListEntry*) Context;
377 StrBufAppendBufPlain(Target, _(axdefs[ul->AccessLevel]), -1, 0);
380 void tmplput_USERLIST_UID(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
382 UserListEntry *ul = (UserListEntry*) Context;
384 StrBufAppendPrintf(Target, "%d", ul->UID, 0);
387 void tmplput_USERLIST_LastLogonNo(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
389 UserListEntry *ul = (UserListEntry*) Context;
391 StrBufAppendBuf(Target, ul->LastLogon, 0);
393 void tmplput_USERLIST_LastLogonStr(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
395 UserListEntry *ul = (UserListEntry*) Context;
396 StrEscAppend(Target, NULL, asctime(localtime(&ul->LastLogonT)), 0, 0);
399 void tmplput_USERLIST_nLogons(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
401 UserListEntry *ul = (UserListEntry*) Context;
403 StrBufAppendPrintf(Target, "%d", ul->nLogons, 0);
406 void tmplput_USERLIST_nPosts(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
408 UserListEntry *ul = (UserListEntry*) Context;
410 StrBufAppendPrintf(Target, "%d", ul->nPosts, 0);
413 void tmplput_USERLIST_Flags(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
415 UserListEntry *ul = (UserListEntry*) Context;
417 StrBufAppendPrintf(Target, "%d", ul->Flags, 0);
420 void tmplput_USERLIST_DaysTillPurge(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
422 UserListEntry *ul = (UserListEntry*) Context;
424 StrBufAppendPrintf(Target, "%d", ul->DaysTillPurge, 0);
427 int ConditionalUser(WCTemplateToken *Tokens, void *Context, int ContextType)
429 UserListEntry *ul = (UserListEntry*) Context;
430 if (havebstr("usernum")) {
431 return ibstr("usernum") == ul->UID;
433 else if (havebstr("username")) {
434 return strcmp(bstr("username"), ChrPtr(ul->UserName)) == 0;
440 int ConditionalFlagINetEmail(WCTemplateToken *Tokens, void *Context, int ContextType)
442 UserListEntry *ul = (UserListEntry*) Context;
443 return (ul->Flags & US_INTERNET) != 0;
446 int ConditionalUserAccess(WCTemplateToken *Tokens, void *Context, int ContextType)
448 UserListEntry *ul = (UserListEntry*) Context;
450 if (Tokens->Params[3]->Type == TYPE_LONG)
451 return (Tokens->Params[3]->lvalue == ul->AccessLevel);
457 * \brief Locate the message number of a user's vCard in the current room
458 * \param username the plaintext name of the user
459 * \param usernum the number of the user on the citadel server
460 * \return the message id of his vcard
462 long locate_user_vcard(char *username, long usernum) {
464 long vcard_msgnum = (-1L);
465 char content_type[SIZ];
467 int already_tried_creating_one = 0;
470 struct stuff_t *next;
474 struct stuff_t *stuff = NULL;
478 /** Search for the user's vCard */
479 serv_puts("MSGS ALL");
480 serv_getln(buf, sizeof buf);
481 if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
482 ptr = malloc(sizeof(struct stuff_t));
483 ptr->msgnum = atol(buf);
488 /** Iterate through the message list looking for vCards */
489 while (stuff != NULL) {
490 serv_printf("MSG0 %ld|2", stuff->msgnum);
491 serv_getln(buf, sizeof buf);
493 while(serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
494 if (!strncasecmp(buf, "part=", 5)) {
495 extract_token(partnum, &buf[5], 2, '|', sizeof partnum);
496 extract_token(content_type, &buf[5], 4, '|', sizeof content_type);
497 if ( (!strcasecmp(content_type, "text/x-vcard"))
498 || (!strcasecmp(content_type, "text/vcard")) ) {
499 vcard_msgnum = stuff->msgnum;
510 /** If there's no vcard, create one */
511 if (vcard_msgnum < 0) if (already_tried_creating_one == 0) {
512 already_tried_creating_one = 1;
513 serv_puts("ENT0 1|||4");
514 serv_getln(buf, sizeof buf);
516 serv_puts("Content-type: text/x-vcard");
518 serv_puts("begin:vcard");
519 serv_puts("end:vcard");
525 return(vcard_msgnum);
530 * \brief Display the form for editing a user's address book entry
531 * \param username the name of the user
532 * \param usernum the citadel-uid of the user
534 void display_edit_address_book_entry(char *username, long usernum) {
537 char error_message[SIZ];
538 long vcard_msgnum = (-1L);
540 /** Locate the user's config room, creating it if necessary */
541 sprintf(roomname, "%010ld.%s", usernum, USERCONFIGROOM);
542 serv_printf("GOTO %s||1", roomname);
543 serv_getln(buf, sizeof buf);
545 serv_printf("CRE8 1|%s|5|||1|", roomname);
546 serv_getln(buf, sizeof buf);
547 serv_printf("GOTO %s||1", roomname);
548 serv_getln(buf, sizeof buf);
550 sprintf(error_message,
551 "<img src=\"static/error.gif\" align=center>"
552 "%s<br /><br />\n", &buf[4]);
553 select_user_to_edit(error_message, username);
558 vcard_msgnum = locate_user_vcard(username, usernum);
560 if (vcard_msgnum < 0) {
561 sprintf(error_message,
562 "<img src=\"static/error.gif\" align=center>%s<br /><br />\n",
563 _("An error occurred while trying to create or edit this address book entry.")
565 select_user_to_edit(error_message, username);
569 do_edit_vcard(vcard_msgnum, "1", "select_user_to_edit", roomname);
573 void display_edituser(char *supplied_username, int is_new) {
576 char error_message[1024];
580 if (supplied_username != NULL) {
581 safestrncpy(username, supplied_username, sizeof username);
584 safestrncpy(username, bstr("username"), sizeof username);
588 serv_printf("AGUP %s", username);
589 StrBuf_ServGetln(Buf);
590 MajorStatus = ChrPtr(Buf)[0];
591 StrBufCutLeft(Buf, 4);
592 if (MajorStatus != '2') {
593 ///TODO ImportantMessage
594 sprintf(error_message,
595 "<img src=\"static/error.gif\" align=center>"
596 "%s<br /><br />\n", ChrPtr(Buf));
597 select_user_to_edit(error_message, username);
602 UL = NewUserListOneEntry(Buf);
603 output_headers(1, 0, 0, 0, 1, 0);
604 DoTemplate(HKEY("userlist_detailview"), NULL, (void*) UL, CTX_USERLIST);
614 * \brief Edit a user.
615 * If supplied_username is null, look in the "username"
616 * web variable for the name of the user to edit.
618 * If "is_new" is set to nonzero, this screen will set the web variables
619 * to send the user to the vCard editor next.
620 * \param supplied_username user to look up or NULL if to search in the environment
621 * \param is_new should we create the user?
623 void display_edituser(char *supplied_username, int is_new) {
625 char error_message[1024];
639 if (supplied_username != NULL) {
640 safestrncpy(username, supplied_username, sizeof username);
643 safestrncpy(username, bstr("username"), sizeof username);
646 serv_printf("AGUP %s", username);
647 serv_getln(buf, sizeof buf);
649 sprintf(error_message,
650 "<img src=\"static/error.gif\" align=center>"
651 "%s<br /><br />\n", &buf[4]);
652 select_user_to_edit(error_message, username);
656 extract_token(username, &buf[4], 0, '|', sizeof username);
657 extract_token(password, &buf[4], 1, '|', sizeof password);
658 flags = extract_int(&buf[4], 2);
659 timescalled = extract_int(&buf[4], 3);
660 msgsposted = extract_int(&buf[4], 4);
661 axlevel = extract_int(&buf[4], 5);
662 usernum = extract_long(&buf[4], 6);
663 lastcall = extract_long(&buf[4], 7);
664 purgedays = extract_long(&buf[4], 8);
666 if (havebstr("edit_abe_button")) {
667 display_edit_address_book_entry(username, usernum);
671 if (havebstr("delete_button")) {
672 delete_user(username);
676 output_headers(1, 1, 2, 0, 0, 0);
677 wprintf("<div id=\"banner\">\n");
679 wprintf(_("Edit user account: "));
684 wprintf("<div id=\"content\" class=\"service\">\n");
686 wprintf("<div class=\"fix_scrollbar_bug\">"
687 "<table class=\"useredit_background\"><tr><td>\n");
688 wprintf("<form method=\"POST\" action=\"edituser\">\n"
689 "<input type=\"hidden\" name=\"username\" value=\"");
692 wprintf("<input type=\"hidden\" name=\"is_new\" value=\"%d\">\n"
693 "<input type=\"hidden\" name=\"usernum\" value=\"%ld\">\n",
695 wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
697 wprintf("<input type=\"hidden\" name=\"flags\" value=\"%d\">\n", flags);
699 wprintf("<center><table>");
702 wprintf(_("User name:"));
704 "<input type=\"text\" name=\"newname\" value=\"");
706 wprintf("\" maxlength=\"63\"></td></tr>\n");
709 wprintf(_("Password"));
711 "<input type=\"password\" name=\"password\" value=\"");
713 wprintf("\" maxlength=\"20\"></td></tr>\n");
716 wprintf(_("Permission to send Internet mail"));
717 wprintf("</td><td>");
718 wprintf("<input type=\"checkbox\" name=\"inetmail\" value=\"yes\" ");
719 if (flags & US_INTERNET) {
722 wprintf("></td></tr>\n");
725 wprintf(_("Number of logins"));
727 "<input type=\"text\" name=\"timescalled\" value=\"");
728 wprintf("%d", timescalled);
729 wprintf("\" maxlength=\"6\"></td></tr>\n");
732 wprintf(_("Messages submitted"));
734 "<input type=\"text\" name=\"msgsposted\" value=\"");
735 wprintf("%d", msgsposted);
736 wprintf("\" maxlength=\"6\"></td></tr>\n");
739 wprintf(_("Access level"));
741 "<select name=\"axlevel\">\n");
742 for (i=0; i<7; ++i) {
745 wprintf("selected ");
747 wprintf("value=\"%d\">%d - %s</option>\n",
750 wprintf("</select></td></tr>\n");
753 wprintf(_("User ID number"));
755 "<input type=\"text\" name=\"usernum\" value=\"");
756 wprintf("%ld", usernum);
757 wprintf("\" maxlength=\"7\"></td></tr>\n");
761 wprintf(_("Date and time of last login"));
763 "<select name=\"lastcall\">\n");
765 wprintf("<option selected value=\"%ld\">", lastcall);
766 escputs(asctime(localtime(&lastcall)));
767 wprintf("</option>\n");
769 wprintf("<option value=\"%ld\">", now);
770 escputs(asctime(localtime(&now)));
771 wprintf("</option>\n");
773 wprintf("</select></td></tr>");
776 wprintf(_("Auto-purge after this many days"));
778 "<input type=\"text\" name=\"purgedays\" value=\"");
779 wprintf("%d", purgedays);
780 wprintf("\" maxlength=\"5\"></td></tr>\n");
782 wprintf("</table>\n");
784 wprintf("<input type=\"submit\" name=\"ok_button\" value=\"%s\">\n"
786 "<input type=\"submit\" name=\"cancel\" value=\"%s\">\n"
787 "<br /><br /></form>\n", _("Save changes"), _("Cancel"));
789 wprintf("</center>\n");
790 wprintf("</td></tr></table></div>\n");
797 * \brief do the backend operation of the user edit on the server
799 void edituser(void) {
803 unsigned int flags = 0;
806 is_new = ibstr("is_new");
807 safestrncpy(message, "", sizeof message);
808 username = bstr("username");
810 if (!havebstr("ok_button")) {
811 safestrncpy(message, _("Changes were not saved."), sizeof message);
815 flags = ibstr("flags");
816 if (yesbstr("inetmail")) {
817 flags |= US_INTERNET;
820 flags &= ~US_INTERNET ;
823 if ((havebstr("newname")) && (strcasecmp(bstr("username"), bstr("newname")))) {
824 serv_printf("RENU %s|%s", bstr("username"), bstr("newname"));
825 serv_getln(buf, sizeof buf);
827 sprintf(&message[strlen(message)],
828 "<img src=\"static/error.gif\" align=center>"
829 "%s<br /><br />\n", &buf[4]);
832 username = bstr("newname");
836 serv_printf("ASUP %s|%s|%d|%s|%s|%s|%s|%s|%s|",
847 serv_getln(buf, sizeof buf);
849 sprintf(&message[strlen(message)],
850 "<img src=\"static/error.gif\" align=center>"
851 "%s<br /><br />\n", &buf[4]);
856 * If we are in the middle of creating a new user, move on to
857 * the vCard edit screen.
860 display_edit_address_book_entry(username, lbstr("usernum") );
863 select_user_to_edit(message, username);
868 * \brief burge a user
869 * \param username the name of the user to remove
871 void delete_user(char *username) {
875 serv_printf("ASUP %s|0|0|0|0|0|", username);
876 serv_getln(buf, sizeof buf);
879 "<img src=\"static/error.gif\" align=center>"
880 "%s<br /><br />\n", &buf[4]);
883 safestrncpy(message, "", sizeof message);
885 select_user_to_edit(message, bstr("username"));
891 * \brief create a new user
892 * take the web environment username and create it on the citadel server
894 void create_user(void) {
896 char error_message[SIZ];
899 safestrncpy(username, bstr("username"), sizeof username);
901 serv_printf("CREU %s", username);
902 serv_getln(buf, sizeof buf);
905 sprintf(WC->ImportantMessage, _("A new user has been created."));
906 display_edituser(username, 1);
908 else if (!strncmp(buf, "570", 3)) {
909 sprintf(error_message,
910 "<img src=\"static/error.gif\" align=center>"
912 _("You are attempting to create a new user from within Citadel "
913 "while running in host based authentication mode. In this mode, "
914 "you must create new users on the host system, not within Citadel.")
916 select_user_to_edit(error_message, NULL);
919 sprintf(error_message,
920 "<img src=\"static/error.gif\" align=center>"
921 "%s<br /><br />\n", &buf[4]);
922 select_user_to_edit(error_message, NULL);
928 void _select_user_to_edit(void){select_user_to_edit(NULL, NULL);}
929 void _display_edituser(void) {display_edituser(NULL, 0);}
935 WebcitAddUrlHandler(HKEY("select_user_to_edit"), _select_user_to_edit, 0);
936 WebcitAddUrlHandler(HKEY("display_edituser"), _display_edituser, 0);
937 WebcitAddUrlHandler(HKEY("edituser"), edituser, 0);
938 WebcitAddUrlHandler(HKEY("create_user"), create_user, 0);
940 RegisterNamespace("USERLIST:USERNAME", 0, 1, tmplput_USERLIST_UserName, CTX_USERLIST);
941 RegisterNamespace("USERLIST:ACCLVLNO", 0, 0, tmplput_USERLIST_AccessLevelNo, CTX_USERLIST);
942 RegisterNamespace("USERLIST:ACCLVLSTR", 0, 0, tmplput_USERLIST_AccessLevelStr, CTX_USERLIST);
943 RegisterNamespace("USERLIST:UID", 0, 0, tmplput_USERLIST_UID, CTX_USERLIST);
944 RegisterNamespace("USERLIST:LASTLOGON:STR", 0, 0, tmplput_USERLIST_LastLogonStr, CTX_USERLIST);
945 RegisterNamespace("USERLIST:LASTLOGON:NO", 0, 0, tmplput_USERLIST_LastLogonNo, CTX_USERLIST);
946 RegisterNamespace("USERLIST:NLOGONS", 0, 0, tmplput_USERLIST_nLogons, CTX_USERLIST);
947 RegisterNamespace("USERLIST:NPOSTS", 0, 0, tmplput_USERLIST_nPosts, CTX_USERLIST);
949 RegisterNamespace("USERLIST:FLAGS", 0, 0, tmplput_USERLIST_Flags, CTX_USERLIST);
950 RegisterNamespace("USERLIST:DAYSTILLPURGE", 0, 0, tmplput_USERLIST_DaysTillPurge, CTX_USERLIST);
952 RegisterConditional(HKEY("COND:USERNAME"), 0, ConditionalUser, CTX_USERLIST);
953 RegisterConditional(HKEY("COND:USERACCESS"), 0, ConditionalUserAccess, CTX_USERLIST);
954 RegisterConditional(HKEY("COND:USERLIST:FLAG:USE_INTERNET"), 0, ConditionalFlagINetEmail, CTX_USERLIST);
956 RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST);