/[LeafOK_CVS]/lbbs/src/user_priv.c
ViewVC logotype

Contents of /lbbs/src/user_priv.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.28 - (show annotations)
Sat Jan 3 10:27:14 2026 UTC (2 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.27: +1 -1 lines
Content type: text/x-csrc
Update copyright info

1 /* SPDX-License-Identifier: GPL-3.0-or-later */
2 /*
3 * user_priv
4 * - basic operations of user privilege
5 *
6 * Copyright (C) 2004-2026 Leaflet <leaflet@leafok.com>
7 */
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #include "bbs.h"
14 #include "common.h"
15 #include "database.h"
16 #include "log.h"
17 #include "user_priv.h"
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <mysql.h>
21
22 BBS_user_priv BBS_priv;
23
24 inline static int search_priv(BBS_user_priv *p_priv, int sid, int *p_offset)
25 {
26 int left = 0;
27 int right = p_priv->s_count - 1;
28 int mid = 0;
29
30 while (left < right)
31 {
32 mid = (left + right) / 2;
33
34 if (sid < p_priv->s_priv_list[mid].sid)
35 {
36 right = mid - 1;
37 }
38 else if (sid > p_priv->s_priv_list[mid].sid)
39 {
40 left = mid + 1;
41 }
42 else // if (sid == p_priv->s_priv_list[mid].sid)
43 {
44 left = mid;
45 break;
46 }
47 }
48
49 *p_offset = left;
50
51 return (sid == p_priv->s_priv_list[left].sid);
52 }
53
54 int setpriv(BBS_user_priv *p_priv, int sid, int priv, int is_favor)
55 {
56 int offset;
57 int i;
58
59 if (sid == 0)
60 {
61 p_priv->g_priv = priv;
62 return 0;
63 }
64
65 if (search_priv(p_priv, sid, &offset)) // found
66 {
67 p_priv->s_priv_list[offset].s_priv = priv;
68 p_priv->s_priv_list[offset].is_favor = is_favor;
69 return 0;
70 }
71
72 // not found
73 if (p_priv->s_count >= BBS_max_section)
74 {
75 return -1;
76 }
77
78 // move items at [left, p_priv->s_count - 1] to [left + 1, p_priv->s_count]
79 for (i = p_priv->s_count - 1; i >= offset; i--)
80 {
81 p_priv->s_priv_list[i + 1] = p_priv->s_priv_list[i];
82 }
83 p_priv->s_count++;
84
85 // insert new item at offset left
86 p_priv->s_priv_list[offset].sid = sid;
87 p_priv->s_priv_list[offset].s_priv = priv;
88 p_priv->s_priv_list[offset].is_favor = is_favor;
89
90 return 0;
91 }
92
93 int getpriv(BBS_user_priv *p_priv, int sid, int *p_is_favor)
94 {
95 int offset;
96
97 if (search_priv(p_priv, sid, &offset)) // found
98 {
99 *p_is_favor = p_priv->s_priv_list[offset].is_favor;
100 return p_priv->s_priv_list[offset].s_priv;
101 }
102
103 *p_is_favor = 0;
104 return (sid >= 0 ? p_priv->g_priv : S_NONE);
105 }
106
107 int load_priv(MYSQL *db, BBS_user_priv *p_priv, int uid)
108 {
109 MYSQL_RES *rs;
110 MYSQL_ROW row;
111 char sql[SQL_BUFFER_LEN];
112 int priv;
113 int is_favor;
114
115 p_priv->uid = uid;
116 p_priv->level = (uid == 0 ? P_GUEST : P_USER);
117 p_priv->g_priv = S_DEFAULT;
118 p_priv->s_count = 0;
119
120 if (db == NULL)
121 return 1;
122
123 // Permission
124 snprintf(sql, sizeof(sql),
125 "SELECT p_post, p_msg FROM user_list WHERE UID = %d AND verified",
126 uid);
127 if (mysql_query(db, sql) != 0)
128 {
129 log_error("Query user_list error: %s", mysql_error(db));
130 return -1;
131 }
132 if ((rs = mysql_store_result(db)) == NULL)
133 {
134 log_error("Get user_list data failed");
135 return -1;
136 }
137 if ((row = mysql_fetch_row(rs)))
138 {
139 p_priv->g_priv |= (atoi(row[0]) ? S_POST : 0);
140 p_priv->g_priv |= (atoi(row[1]) ? S_MSG : 0);
141 }
142 mysql_free_result(rs);
143
144 // Admin
145 snprintf(sql, sizeof(sql),
146 "SELECT major FROM admin_config WHERE UID = %d "
147 "AND enable AND (NOW() BETWEEN begin_dt AND end_dt)",
148 uid);
149 if (mysql_query(db, sql) != 0)
150 {
151 log_error("Query admin_config error: %s", mysql_error(db));
152 return -1;
153 }
154 if ((rs = mysql_store_result(db)) == NULL)
155 {
156 log_error("Get admin_config data failed");
157 return -1;
158 }
159 if ((row = mysql_fetch_row(rs)))
160 {
161 p_priv->level |= (atoi(row[0]) ? P_ADMIN_M : P_ADMIN_S);
162 p_priv->g_priv |= (atoi(row[0]) ? S_ALL : S_ADMIN);
163 }
164 mysql_free_result(rs);
165
166 // Section Master
167 snprintf(sql, sizeof(sql),
168 "SELECT section_master.SID, major FROM section_master "
169 "INNER JOIN section_config ON section_master.SID = section_config.SID "
170 "WHERE UID = %d AND section_master.enable AND section_config.enable "
171 "AND (NOW() BETWEEN begin_dt AND end_dt)",
172 uid);
173 if (mysql_query(db, sql) != 0)
174 {
175 log_error("Query section_master error: %s", mysql_error(db));
176 return -1;
177 }
178 if ((rs = mysql_store_result(db)) == NULL)
179 {
180 log_error("Get section_master data failed");
181 return -1;
182 }
183 while ((row = mysql_fetch_row(rs)))
184 {
185 p_priv->level |= (atoi(row[1]) ? P_MAN_M : P_MAN_S);
186 priv = (getpriv(p_priv, atoi(row[0]), &is_favor) | (atoi(row[1]) ? S_MAN_M : S_MAN_S));
187 setpriv(p_priv, atoi(row[0]), priv, is_favor);
188 }
189 mysql_free_result(rs);
190
191 // Section status
192 snprintf(sql, sizeof(sql),
193 "SELECT SID, exp_get, read_user_level, write_user_level FROM section_config "
194 "INNER JOIN section_class ON section_config.CID = section_class.CID "
195 "WHERE section_config.enable AND section_class.enable "
196 "ORDER BY SID");
197 if (mysql_query(db, sql) != 0)
198 {
199 log_error("Query section_config error: %s", mysql_error(db));
200 return -1;
201 }
202 if ((rs = mysql_store_result(db)) == NULL)
203 {
204 log_error("Get section_config data failed");
205 return -1;
206 }
207 while ((row = mysql_fetch_row(rs)))
208 {
209 int priv = getpriv(p_priv, atoi(row[0]), &is_favor);
210 if (p_priv->level < atoi(row[2]))
211 {
212 priv &= (~S_LIST);
213 }
214 if (p_priv->level < atoi(row[3]))
215 {
216 priv &= (~S_POST);
217 }
218 if (!atoi(row[1]))
219 {
220 priv &= (~S_GETEXP);
221 }
222 setpriv(p_priv, atoi(row[0]), priv, is_favor);
223 }
224 mysql_free_result(rs);
225
226 // Section ban
227 snprintf(sql, sizeof(sql),
228 "SELECT SID FROM ban_user_list WHERE UID = %d AND enable "
229 "AND (NOW() BETWEEN ban_dt AND unban_dt)",
230 uid);
231 if (mysql_query(db, sql) != 0)
232 {
233 log_error("Query ban_user_list error: %s", mysql_error(db));
234 return -1;
235 }
236 if ((rs = mysql_store_result(db)) == NULL)
237 {
238 log_error("Get ban_user_list data failed");
239 return -1;
240 }
241 while ((row = mysql_fetch_row(rs)))
242 {
243 priv = getpriv(p_priv, atoi(row[0]), &is_favor) & (~S_POST);
244 setpriv(p_priv, atoi(row[0]), priv, is_favor);
245 }
246 mysql_free_result(rs);
247
248 // User favor section
249 snprintf(sql, sizeof(sql),
250 "SELECT SID FROM section_favorite WHERE UID = %d",
251 uid);
252 if (mysql_query(db, sql) != 0)
253 {
254 log_error("Query section_favorite error: %s", mysql_error(db));
255 return -1;
256 }
257 if ((rs = mysql_store_result(db)) == NULL)
258 {
259 log_error("Get section_favorite data failed");
260 return -1;
261 }
262 while ((row = mysql_fetch_row(rs)))
263 {
264 priv = getpriv(p_priv, atoi(row[0]), &is_favor);
265 if (!is_favor)
266 {
267 setpriv(p_priv, atoi(row[0]), priv, 1);
268 priv = getpriv(p_priv, atoi(row[0]), &is_favor);
269 }
270 }
271 mysql_free_result(rs);
272
273 return 0;
274 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1