1 /*
2 * jabberd - Jabber Open Source Server
3 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4 * Ryan Eatmon, Robert Norris
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19 */
20
21 #include "sm.h"
22
23 /** @file sm/user.c
24 * @brief user management
25 * @author Robert Norris
26 * $Date: 2005/06/02 04:48:25 $
27 * $Revision: 1.23 $
28 */
29
30 /** make a new one */
_user_alloc(sm_t sm,jid_t jid)31 static user_t _user_alloc(sm_t sm, jid_t jid) {
32 pool_t p;
33 user_t user;
34
35 p = pool_new();
36
37 user = (user_t) pmalloco(p, sizeof(struct user_st));
38
39 user->p = p;
40 user->sm = sm;
41
42 user->jid = jid_dup(jid);
43 pool_cleanup(p, (void (*)(void *)) jid_free, user->jid);
44
45 /* a place for modules to store stuff */
46 user->module_data = (void **) pmalloco(p, sizeof(void *) * sm->mm->nindex);
47
48 return user;
49 }
50
51 /** fetch user data */
user_load(sm_t sm,jid_t jid)52 user_t user_load(sm_t sm, jid_t jid) {
53 user_t user;
54
55 /* already loaded */
56 user = xhash_get(sm->users, jid_user(jid));
57 if(user != NULL) {
58 log_debug(ZONE, "returning previously-created user data for %s", jid_user(jid));
59 return user;
60 }
61
62 /* make a new one */
63 user = _user_alloc(sm, jid);
64
65 /* get modules to setup */
66 if(mm_user_load(sm->mm, user) != 0) {
67 log_debug(ZONE, "modules failed user load for %s", jid_user(jid));
68 pool_free(user->p);
69 return NULL;
70 }
71
72 /* save them for later */
73 xhash_put(sm->users, jid_user(user->jid), (void *) user);
74
75 log_debug(ZONE, "loaded user data for %s", jid_user(jid));
76
77 return user;
78 }
79
user_free(user_t user)80 void user_free(user_t user) {
81 log_debug(ZONE, "freeing user %s", jid_user(user->jid));
82
83 xhash_zap(user->sm->users, jid_user(user->jid));
84 pool_free(user->p);
85 }
86
87 /** initialise a user */
user_create(sm_t sm,jid_t jid)88 int user_create(sm_t sm, jid_t jid) {
89 user_t user;
90
91 log_debug(ZONE, "create user request for %s", jid_user(jid));
92
93 /* check whether it is to serviced domain */
94 if(xhash_get(sm->hosts, jid->domain) == NULL) {
95 log_write(sm->log, LOG_ERR, "request to create user for non-serviced domain: jid=%s", jid_user(jid));
96 log_debug(ZONE, "no such domain, not creating");
97 return 1;
98 }
99
100 user = user_load(sm, jid);
101 if(user != NULL) {
102 log_write(sm->log, LOG_ERR, "request to create already-active user: jid=%s", jid_user(jid));
103 log_debug(ZONE, "user already active, not creating");
104 return 1;
105 }
106
107 /* modules create */
108 if(mm_user_create(sm->mm, jid) != 0) {
109 log_write(sm->log, LOG_ERR, "user creation failed: jid=%s", jid_user(jid));
110 log_debug(ZONE, "user create failed, forcing deletion for cleanup");
111 mm_user_delete(sm->mm, jid);
112 return 1;
113 }
114
115 log_write(sm->log, LOG_NOTICE, "created user: jid=%s", jid_user(jid));
116
117 return 0;
118 }
119
120 /** trash a user */
user_delete(sm_t sm,jid_t jid)121 void user_delete(sm_t sm, jid_t jid) {
122 user_t user;
123 sess_t scan, next;
124
125 log_debug(ZONE, "delete user request for %s", jid_user(jid));
126
127 user = user_load(sm, jid);
128 if(user == NULL) {
129 log_debug(ZONE, "user doesn't exist, can't delete");
130 return;
131 }
132
133 /* close their sessions first (this will free user, after the last session ends) */
134 scan = user->sessions;
135 while(scan != NULL) {
136 next = scan->next;
137 sm_c2s_action(scan, "ended", NULL);
138 sess_end(scan);
139 scan = next;
140 }
141
142 mm_user_delete(sm->mm, jid);
143
144 log_write(sm->log, LOG_NOTICE, "deleted user: jid=%s", jid_user(jid));
145 }
146