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