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 {
113 /* Just available for Single users to view: */
119 UserListEntry* NewUserListOneEntry(StrBuf *SerializedUser)
123 if (StrLength(SerializedUser) < 8)
126 ul = (UserListEntry*) malloc(sizeof(UserListEntry));
127 ul->UserName = NewStrBuf();
128 ul->Passvoid = NewStrBuf();
130 StrBufExtract_token(ul->UserName, SerializedUser, 0, '|');
131 StrBufExtract_token(ul->Passvoid, SerializedUser, 1, '|');
132 ul->Flags = (unsigned int)StrBufExtract_long(SerializedUser, 2, '|');
133 ul->nLogons = StrBufExtract_int(SerializedUser, 3, '|');
134 ul->nPosts = StrBufExtract_int(SerializedUser, 4, '|');
135 ul->AccessLevel = StrBufExtract_int(SerializedUser, 5, '|');
136 ul->UID = StrBufExtract_int(SerializedUser, 6, '|');
137 ul->LastLogonT = StrBufExtract_long(SerializedUser, 7, '|');
138 ul->DaysTillPurge = StrBufExtract_int(SerializedUser, 8, '|');
142 void DeleteUserListEntry(void *vUserList)
144 UserListEntry *ul = (UserListEntry*) vUserList;
145 FreeStrBuf(&ul->UserName);
146 FreeStrBuf(&ul->Passvoid);
150 UserListEntry* NewUserListEntry(StrBuf *SerializedUserList)
154 if (StrLength(SerializedUserList) < 8)
157 ul = (UserListEntry*) malloc(sizeof(UserListEntry));
158 ul->UserName = NewStrBuf();
159 ul->Passvoid = NewStrBuf();
161 StrBufExtract_token(ul->UserName, SerializedUserList, 0, '|');
162 ul->AccessLevel = StrBufExtract_int(SerializedUserList, 1, '|');
163 ul->UID = StrBufExtract_int(SerializedUserList, 2, '|');
164 ul->LastLogonT = StrBufExtract_long(SerializedUserList, 3, '|');
165 ul->nLogons = StrBufExtract_int(SerializedUserList, 4, '|');
166 ul->nPosts = StrBufExtract_int(SerializedUserList, 5, '|');
167 StrBufExtract_token(ul->Passvoid, SerializedUserList, 6, '|');
169 ul->DaysTillPurge = -1;
176 int CompareUserListName(const void *vUser1, const void *vUser2)
178 UserListEntry *u1 = (UserListEntry*) vUser1;
179 UserListEntry *u2 = (UserListEntry*) vUser2;
181 return strcmp(ChrPtr(u1->UserName), ChrPtr(u2->UserName));
183 int CompareUserListNameRev(const void *vUser1, const void *vUser2)
185 UserListEntry *u1 = (UserListEntry*) vUser1;
186 UserListEntry *u2 = (UserListEntry*) vUser2;
187 return strcmp(ChrPtr(u2->UserName), ChrPtr(u1->UserName));
191 * Sort by AccessLevel
193 int CompareAccessLevel(const void *vUser1, const void *vUser2)
195 UserListEntry *u1 = (UserListEntry*) vUser1;
196 UserListEntry *u2 = (UserListEntry*) vUser2;
198 return (u1->AccessLevel > u2->AccessLevel);
200 int CompareAccessLevelRev(const void *vUser1, const void *vUser2)
202 UserListEntry *u1 = (UserListEntry*) vUser1;
203 UserListEntry *u2 = (UserListEntry*) vUser2;
205 return (u2->AccessLevel > u1->AccessLevel);
212 int CompareUID(const void *vUser1, const void *vUser2)
214 UserListEntry *u1 = (UserListEntry*) vUser1;
215 UserListEntry *u2 = (UserListEntry*) vUser2;
217 return (u1->UID > u2->UID);
219 int CompareUIDRev(const void *vUser1, const void *vUser2)
221 UserListEntry *u1 = (UserListEntry*) vUser1;
222 UserListEntry *u2 = (UserListEntry*) vUser2;
224 return (u2->UID > u1->UID);
228 * Sort By Date /// TODO!
230 int CompareLastLogon(const void *vUser1, const void *vUser2)
232 UserListEntry *u1 = (UserListEntry*) vUser1;
233 UserListEntry *u2 = (UserListEntry*) vUser2;
235 return (u1->LastLogonT > u2->LastLogonT);
237 int CompareLastLogonRev(const void *vUser1, const void *vUser2)
239 UserListEntry *u1 = (UserListEntry*) vUser1;
240 UserListEntry *u2 = (UserListEntry*) vUser2;
242 return (u2->LastLogonT > u1->LastLogonT);
246 * Sort By Number of Logons
248 int ComparenLogons(const void *vUser1, const void *vUser2)
250 UserListEntry *u1 = (UserListEntry*) vUser1;
251 UserListEntry *u2 = (UserListEntry*) vUser2;
253 return (u1->nLogons > u2->nLogons);
255 int ComparenLogonsRev(const void *vUser1, const void *vUser2)
257 UserListEntry *u1 = (UserListEntry*) vUser1;
258 UserListEntry *u2 = (UserListEntry*) vUser2;
260 return (u2->nLogons > u1->nLogons);
264 * Sort By Number of Posts
266 int ComparenPosts(const void *vUser1, const void *vUser2)
268 UserListEntry *u1 = (UserListEntry*) vUser1;
269 UserListEntry *u2 = (UserListEntry*) vUser2;
271 return (u1->nPosts > u2->nPosts);
273 int ComparenPostsRev(const void *vUser1, const void *vUser2)
275 UserListEntry *u1 = (UserListEntry*) vUser1;
276 UserListEntry *u2 = (UserListEntry*) vUser2;
278 return (u2->nPosts > u1->nPosts);
282 HashList *iterate_load_userlist(WCTemplateToken *Token)
294 serv_getln(buf, sizeof buf);
296 Hash = NewHash(1, NULL);
299 while ((len = StrBuf_ServGetln(Buf),
300 strcmp(ChrPtr(Buf), "000"))) {
301 ul = NewUserListEntry(Buf);
304 nUsed = GetCount(Hash);
305 nUsed = snprintf(nnn, sizeof(nnn), "%d", nUsed+1);
306 Put(Hash, nnn, nUsed, ul, DeleteUserListEntry);
309 Order = ibstr("SortOrder");
310 switch (ibstr("SortBy")){
312 SortByPayload(Hash, (Order)?
314 CompareUserListNameRev);
316 case 2: /*AccessLevel*/
317 SortByPayload(Hash, (Order)?
319 CompareAccessLevelRev);
322 SortByPayload(Hash, (Order)?
327 SortByPayload(Hash, (Order)?
331 case 5: /*LastLogon*/
332 SortByPayload(Hash, (Order)?
334 CompareLastLogonRev);
336 case 6: /* nLogons */
337 SortByPayload(Hash, (Order)?
342 SortByPayload(Hash, (Order)?
353 void tmplput_USERLIST_UserName(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
355 UserListEntry *ul = (UserListEntry*) Context;
357 StrBufAppendBuf(Target, ul->UserName, 0);
360 void tmplput_USERLIST_AccessLevelNo(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
362 UserListEntry *ul = (UserListEntry*) Context;
364 StrBufAppendPrintf(Target, "%d", ul->AccessLevel, 0);
367 void tmplput_USERLIST_AccessLevelStr(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
369 UserListEntry *ul = (UserListEntry*) Context;
371 StrBufAppendBufPlain(Target, _(axdefs[ul->AccessLevel]), -1, 0);
374 void tmplput_USERLIST_UID(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
376 UserListEntry *ul = (UserListEntry*) Context;
378 StrBufAppendPrintf(Target, "%d", ul->UID, 0);
381 void tmplput_USERLIST_LastLogonNo(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
383 UserListEntry *ul = (UserListEntry*) Context;
385 StrBufAppendPrintf(Target,"%ld", ul->LastLogonT, 0);
387 void tmplput_USERLIST_LastLogonStr(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
389 UserListEntry *ul = (UserListEntry*) Context;
390 StrEscAppend(Target, NULL, asctime(localtime(&ul->LastLogonT)), 0, 0);
393 void tmplput_USERLIST_nLogons(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
395 UserListEntry *ul = (UserListEntry*) Context;
397 StrBufAppendPrintf(Target, "%d", ul->nLogons, 0);
400 void tmplput_USERLIST_nPosts(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
402 UserListEntry *ul = (UserListEntry*) Context;
404 StrBufAppendPrintf(Target, "%d", ul->nPosts, 0);
407 void tmplput_USERLIST_Flags(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
409 UserListEntry *ul = (UserListEntry*) Context;
411 StrBufAppendPrintf(Target, "%d", ul->Flags, 0);
414 void tmplput_USERLIST_DaysTillPurge(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
416 UserListEntry *ul = (UserListEntry*) Context;
418 StrBufAppendPrintf(Target, "%d", ul->DaysTillPurge, 0);
421 int ConditionalUser(WCTemplateToken *Tokens, void *Context, int ContextType)
423 UserListEntry *ul = (UserListEntry*) Context;
424 if (havebstr("usernum")) {
425 return ibstr("usernum") == ul->UID;
427 else if (havebstr("username")) {
428 return strcmp(bstr("username"), ChrPtr(ul->UserName)) == 0;
434 int ConditionalFlagINetEmail(WCTemplateToken *Tokens, void *Context, int ContextType)
436 UserListEntry *ul = (UserListEntry*) Context;
437 return (ul->Flags & US_INTERNET) != 0;
440 int ConditionalUserAccess(WCTemplateToken *Tokens, void *Context, int ContextType)
442 UserListEntry *ul = (UserListEntry*) Context;
444 if (Tokens->Params[3]->Type == TYPE_LONG)
445 return (Tokens->Params[3]->lvalue == ul->AccessLevel);
451 * \brief Locate the message number of a user's vCard in the current room
452 * \param username the plaintext name of the user
453 * \param usernum the number of the user on the citadel server
454 * \return the message id of his vcard
456 long locate_user_vcard(char *username, long usernum) {
458 long vcard_msgnum = (-1L);
459 char content_type[SIZ];
461 int already_tried_creating_one = 0;
464 struct stuff_t *next;
468 struct stuff_t *stuff = NULL;
472 /** Search for the user's vCard */
473 serv_puts("MSGS ALL");
474 serv_getln(buf, sizeof buf);
475 if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
476 ptr = malloc(sizeof(struct stuff_t));
477 ptr->msgnum = atol(buf);
482 /** Iterate through the message list looking for vCards */
483 while (stuff != NULL) {
484 serv_printf("MSG0 %ld|2", stuff->msgnum);
485 serv_getln(buf, sizeof buf);
487 while(serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
488 if (!strncasecmp(buf, "part=", 5)) {
489 extract_token(partnum, &buf[5], 2, '|', sizeof partnum);
490 extract_token(content_type, &buf[5], 4, '|', sizeof content_type);
491 if ( (!strcasecmp(content_type, "text/x-vcard"))
492 || (!strcasecmp(content_type, "text/vcard")) ) {
493 vcard_msgnum = stuff->msgnum;
504 /** If there's no vcard, create one */
505 if (vcard_msgnum < 0) if (already_tried_creating_one == 0) {
506 already_tried_creating_one = 1;
507 serv_puts("ENT0 1|||4");
508 serv_getln(buf, sizeof buf);
510 serv_puts("Content-type: text/x-vcard");
512 serv_puts("begin:vcard");
513 serv_puts("end:vcard");
519 return(vcard_msgnum);
524 * \brief Display the form for editing a user's address book entry
525 * \param username the name of the user
526 * \param usernum the citadel-uid of the user
528 void display_edit_address_book_entry(char *username, long usernum) {
531 char error_message[SIZ];
532 long vcard_msgnum = (-1L);
534 /** Locate the user's config room, creating it if necessary */
535 sprintf(roomname, "%010ld.%s", usernum, USERCONFIGROOM);
536 serv_printf("GOTO %s||1", roomname);
537 serv_getln(buf, sizeof buf);
539 serv_printf("CRE8 1|%s|5|||1|", roomname);
540 serv_getln(buf, sizeof buf);
541 serv_printf("GOTO %s||1", roomname);
542 serv_getln(buf, sizeof buf);
544 sprintf(error_message,
545 "<img src=\"static/error.gif\" align=center>"
546 "%s<br /><br />\n", &buf[4]);
547 select_user_to_edit(error_message, username);
552 vcard_msgnum = locate_user_vcard(username, usernum);
554 if (vcard_msgnum < 0) {
555 sprintf(error_message,
556 "<img src=\"static/error.gif\" align=center>%s<br /><br />\n",
557 _("An error occurred while trying to create or edit this address book entry.")
559 select_user_to_edit(error_message, username);
563 do_edit_vcard(vcard_msgnum, "1", "select_user_to_edit", roomname);
567 void display_edituser(char *supplied_username, int is_new) {
570 char error_message[1024];
574 if (supplied_username != NULL) {
575 safestrncpy(username, supplied_username, sizeof username);
578 safestrncpy(username, bstr("username"), sizeof username);
582 serv_printf("AGUP %s", username);
583 StrBuf_ServGetln(Buf);
584 MajorStatus = ChrPtr(Buf)[0];
585 StrBufCutLeft(Buf, 4);
586 if (MajorStatus != '2') {
587 ///TODO ImportantMessage
588 sprintf(error_message,
589 "<img src=\"static/error.gif\" align=center>"
590 "%s<br /><br />\n", ChrPtr(Buf));
591 select_user_to_edit(error_message, username);
596 UL = NewUserListOneEntry(Buf);
597 output_headers(1, 0, 0, 0, 1, 0);
598 DoTemplate(HKEY("userlist_detailview"), NULL, (void*) UL, CTX_USERLIST);
608 * \brief Edit a user.
609 * If supplied_username is null, look in the "username"
610 * web variable for the name of the user to edit.
612 * If "is_new" is set to nonzero, this screen will set the web variables
613 * to send the user to the vCard editor next.
614 * \param supplied_username user to look up or NULL if to search in the environment
615 * \param is_new should we create the user?
617 void display_edituser(char *supplied_username, int is_new) {
619 char error_message[1024];
633 if (supplied_username != NULL) {
634 safestrncpy(username, supplied_username, sizeof username);
637 safestrncpy(username, bstr("username"), sizeof username);
640 serv_printf("AGUP %s", username);
641 serv_getln(buf, sizeof buf);
643 sprintf(error_message,
644 "<img src=\"static/error.gif\" align=center>"
645 "%s<br /><br />\n", &buf[4]);
646 select_user_to_edit(error_message, username);
650 extract_token(username, &buf[4], 0, '|', sizeof username);
651 extract_token(password, &buf[4], 1, '|', sizeof password);
652 flags = extract_int(&buf[4], 2);
653 timescalled = extract_int(&buf[4], 3);
654 msgsposted = extract_int(&buf[4], 4);
655 axlevel = extract_int(&buf[4], 5);
656 usernum = extract_long(&buf[4], 6);
657 lastcall = extract_long(&buf[4], 7);
658 purgedays = extract_long(&buf[4], 8);
660 if (havebstr("edit_abe_button")) {
661 display_edit_address_book_entry(username, usernum);
665 if (havebstr("delete_button")) {
666 delete_user(username);
670 output_headers(1, 1, 2, 0, 0, 0);
671 wprintf("<div id=\"banner\">\n");
673 wprintf(_("Edit user account: "));
678 wprintf("<div id=\"content\" class=\"service\">\n");
680 wprintf("<div class=\"fix_scrollbar_bug\">"
681 "<table class=\"useredit_background\"><tr><td>\n");
682 wprintf("<form method=\"POST\" action=\"edituser\">\n"
683 "<input type=\"hidden\" name=\"username\" value=\"");
686 wprintf("<input type=\"hidden\" name=\"is_new\" value=\"%d\">\n"
687 "<input type=\"hidden\" name=\"usernum\" value=\"%ld\">\n",
689 wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
691 wprintf("<input type=\"hidden\" name=\"flags\" value=\"%d\">\n", flags);
693 wprintf("<center><table>");
696 wprintf(_("User name:"));
698 "<input type=\"text\" name=\"newname\" value=\"");
700 wprintf("\" maxlength=\"63\"></td></tr>\n");
703 wprintf(_("Password"));
705 "<input type=\"password\" name=\"password\" value=\"");
707 wprintf("\" maxlength=\"20\"></td></tr>\n");
710 wprintf(_("Permission to send Internet mail"));
711 wprintf("</td><td>");
712 wprintf("<input type=\"checkbox\" name=\"inetmail\" value=\"yes\" ");
713 if (flags & US_INTERNET) {
716 wprintf("></td></tr>\n");
719 wprintf(_("Number of logins"));
721 "<input type=\"text\" name=\"timescalled\" value=\"");
722 wprintf("%d", timescalled);
723 wprintf("\" maxlength=\"6\"></td></tr>\n");
726 wprintf(_("Messages submitted"));
728 "<input type=\"text\" name=\"msgsposted\" value=\"");
729 wprintf("%d", msgsposted);
730 wprintf("\" maxlength=\"6\"></td></tr>\n");
733 wprintf(_("Access level"));
735 "<select name=\"axlevel\">\n");
736 for (i=0; i<7; ++i) {
739 wprintf("selected ");
741 wprintf("value=\"%d\">%d - %s</option>\n",
744 wprintf("</select></td></tr>\n");
747 wprintf(_("User ID number"));
749 "<input type=\"text\" name=\"usernum\" value=\"");
750 wprintf("%ld", usernum);
751 wprintf("\" maxlength=\"7\"></td></tr>\n");
755 wprintf(_("Date and time of last login"));
757 "<select name=\"lastcall\">\n");
759 wprintf("<option selected value=\"%ld\">", lastcall);
760 escputs(asctime(localtime(&lastcall)));
761 wprintf("</option>\n");
763 wprintf("<option value=\"%ld\">", now);
764 escputs(asctime(localtime(&now)));
765 wprintf("</option>\n");
767 wprintf("</select></td></tr>");
770 wprintf(_("Auto-purge after this many days"));
772 "<input type=\"text\" name=\"purgedays\" value=\"");
773 wprintf("%d", purgedays);
774 wprintf("\" maxlength=\"5\"></td></tr>\n");
776 wprintf("</table>\n");
778 wprintf("<input type=\"submit\" name=\"ok_button\" value=\"%s\">\n"
780 "<input type=\"submit\" name=\"cancel\" value=\"%s\">\n"
781 "<br /><br /></form>\n", _("Save changes"), _("Cancel"));
783 wprintf("</center>\n");
784 wprintf("</td></tr></table></div>\n");
791 * \brief do the backend operation of the user edit on the server
793 void edituser(void) {
797 unsigned int flags = 0;
800 is_new = ibstr("is_new");
801 safestrncpy(message, "", sizeof message);
802 username = bstr("username");
804 if (!havebstr("ok_button")) {
805 safestrncpy(message, _("Changes were not saved."), sizeof message);
809 flags = ibstr("flags");
810 if (yesbstr("inetmail")) {
811 flags |= US_INTERNET;
814 flags &= ~US_INTERNET ;
817 if ((havebstr("newname")) && (strcasecmp(bstr("username"), bstr("newname")))) {
818 serv_printf("RENU %s|%s", bstr("username"), bstr("newname"));
819 serv_getln(buf, sizeof buf);
821 sprintf(&message[strlen(message)],
822 "<img src=\"static/error.gif\" align=center>"
823 "%s<br /><br />\n", &buf[4]);
826 username = bstr("newname");
830 serv_printf("ASUP %s|%s|%d|%s|%s|%s|%s|%s|%s|",
841 serv_getln(buf, sizeof buf);
843 sprintf(&message[strlen(message)],
844 "<img src=\"static/error.gif\" align=center>"
845 "%s<br /><br />\n", &buf[4]);
850 * If we are in the middle of creating a new user, move on to
851 * the vCard edit screen.
854 display_edit_address_book_entry(username, lbstr("usernum") );
857 select_user_to_edit(message, username);
862 * \brief burge a user
863 * \param username the name of the user to remove
865 void delete_user(char *username) {
869 serv_printf("ASUP %s|0|0|0|0|0|", username);
870 serv_getln(buf, sizeof buf);
873 "<img src=\"static/error.gif\" align=center>"
874 "%s<br /><br />\n", &buf[4]);
877 safestrncpy(message, "", sizeof message);
879 select_user_to_edit(message, bstr("username"));
885 * \brief create a new user
886 * take the web environment username and create it on the citadel server
888 void create_user(void) {
890 char error_message[SIZ];
893 safestrncpy(username, bstr("username"), sizeof username);
895 serv_printf("CREU %s", username);
896 serv_getln(buf, sizeof buf);
899 sprintf(WC->ImportantMessage, _("A new user has been created."));
900 display_edituser(username, 1);
902 else if (!strncmp(buf, "570", 3)) {
903 sprintf(error_message,
904 "<img src=\"static/error.gif\" align=center>"
906 _("You are attempting to create a new user from within Citadel "
907 "while running in host based authentication mode. In this mode, "
908 "you must create new users on the host system, not within Citadel.")
910 select_user_to_edit(error_message, NULL);
913 sprintf(error_message,
914 "<img src=\"static/error.gif\" align=center>"
915 "%s<br /><br />\n", &buf[4]);
916 select_user_to_edit(error_message, NULL);
922 void _select_user_to_edit(void){select_user_to_edit(NULL, NULL);}
923 void _display_edituser(void) {display_edituser(NULL, 0);}
929 WebcitAddUrlHandler(HKEY("select_user_to_edit"), _select_user_to_edit, 0);
930 WebcitAddUrlHandler(HKEY("display_edituser"), _display_edituser, 0);
931 WebcitAddUrlHandler(HKEY("edituser"), edituser, 0);
932 WebcitAddUrlHandler(HKEY("create_user"), create_user, 0);
934 RegisterNamespace("USERLIST:USERNAME", 0, 1, tmplput_USERLIST_UserName, CTX_USERLIST);
935 RegisterNamespace("USERLIST:ACCLVLNO", 0, 0, tmplput_USERLIST_AccessLevelNo, CTX_USERLIST);
936 RegisterNamespace("USERLIST:ACCLVLSTR", 0, 0, tmplput_USERLIST_AccessLevelStr, CTX_USERLIST);
937 RegisterNamespace("USERLIST:UID", 0, 0, tmplput_USERLIST_UID, CTX_USERLIST);
938 RegisterNamespace("USERLIST:LASTLOGON:STR", 0, 0, tmplput_USERLIST_LastLogonStr, CTX_USERLIST);
939 RegisterNamespace("USERLIST:LASTLOGON:NO", 0, 0, tmplput_USERLIST_LastLogonNo, CTX_USERLIST);
940 RegisterNamespace("USERLIST:NLOGONS", 0, 0, tmplput_USERLIST_nLogons, CTX_USERLIST);
941 RegisterNamespace("USERLIST:NPOSTS", 0, 0, tmplput_USERLIST_nPosts, CTX_USERLIST);
943 RegisterNamespace("USERLIST:FLAGS", 0, 0, tmplput_USERLIST_Flags, CTX_USERLIST);
944 RegisterNamespace("USERLIST:DAYSTILLPURGE", 0, 0, tmplput_USERLIST_DaysTillPurge, CTX_USERLIST);
946 RegisterConditional(HKEY("COND:USERNAME"), 0, ConditionalUser, CTX_USERLIST);
947 RegisterConditional(HKEY("COND:USERACCESS"), 0, ConditionalUserAccess, CTX_USERLIST);
948 RegisterConditional(HKEY("COND:USERLIST:FLAG:USE_INTERNET"), 0, ConditionalFlagINetEmail, CTX_USERLIST);
950 RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST);