/[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.23 - (show annotations)
Tue Nov 4 13:49:51 2025 UTC (4 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.22: +9 -17 lines
Content type: text/x-csrc
Update file header information comments

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

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