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

Annotation of /lbbs/src/user_priv.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.24 - (hide annotations)
Tue Nov 4 14:58:56 2025 UTC (4 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.23: +1 -1 lines
Content type: text/x-csrc
Refine file header information comments

1 sysadm 1.23 /* SPDX-License-Identifier: GPL-3.0-or-later */
2     /*
3     * user_priv
4     * - basic operations of user privilege
5     *
6 sysadm 1.24 * Copyright (C) 2004-2025 Leaflet <leaflet@leafok.com>
7 sysadm 1.23 */
8 sysadm 1.1
9     #include "bbs.h"
10 sysadm 1.2 #include "common.h"
11 sysadm 1.10 #include "database.h"
12 sysadm 1.8 #include "log.h"
13 sysadm 1.21 #include "user_priv.h"
14 sysadm 1.8 #include <stdio.h>
15 sysadm 1.15 #include <stdlib.h>
16 sysadm 1.19 #include <mysql/mysql.h>
17 sysadm 1.1
18 sysadm 1.8 BBS_user_priv BBS_priv;
19    
20 sysadm 1.18 inline static int search_priv(BBS_user_priv *p_priv, int sid, int *p_offset)
21 sysadm 1.2 {
22 sysadm 1.16 int left = 0;
23     int right = p_priv->s_count - 1;
24 sysadm 1.17 int mid = 0;
25 sysadm 1.16
26     while (left < right)
27     {
28     mid = (left + right) / 2;
29    
30 sysadm 1.22 if (sid < p_priv->s_priv_list[mid].sid)
31 sysadm 1.5 {
32 sysadm 1.22 right = mid - 1;
33 sysadm 1.5 }
34 sysadm 1.22 else if (sid > p_priv->s_priv_list[mid].sid)
35 sysadm 1.5 {
36 sysadm 1.16 left = mid + 1;
37 sysadm 1.5 }
38 sysadm 1.22 else // if (sid == p_priv->s_priv_list[mid].sid)
39     {
40     left = mid;
41     break;
42     }
43 sysadm 1.2 }
44 sysadm 1.16
45 sysadm 1.18 *p_offset = left;
46    
47 sysadm 1.22 return (sid == p_priv->s_priv_list[left].sid);
48 sysadm 1.18 }
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 sysadm 1.23 if (search_priv(p_priv, sid, &offset)) // found
62 sysadm 1.2 {
63 sysadm 1.18 p_priv->s_priv_list[offset].s_priv = priv;
64     p_priv->s_priv_list[offset].is_favor = is_favor;
65 sysadm 1.16 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 sysadm 1.18 for (i = p_priv->s_count - 1; i >= offset; i--)
76 sysadm 1.16 {
77 sysadm 1.18 p_priv->s_priv_list[i + 1] = p_priv->s_priv_list[i];
78 sysadm 1.2 }
79 sysadm 1.17 p_priv->s_count++;
80    
81 sysadm 1.16 // insert new item at offset left
82 sysadm 1.18 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 sysadm 1.5
86     return 0;
87     }
88    
89 sysadm 1.17 int getpriv(BBS_user_priv *p_priv, int sid, int *p_is_favor)
90 sysadm 1.5 {
91 sysadm 1.18 int offset;
92 sysadm 1.2
93 sysadm 1.23 if (search_priv(p_priv, sid, &offset)) // found
94 sysadm 1.17 {
95 sysadm 1.18 *p_is_favor = p_priv->s_priv_list[offset].is_favor;
96     return p_priv->s_priv_list[offset].s_priv;
97 sysadm 1.17 }
98    
99 sysadm 1.18 *p_is_favor = 0;
100 sysadm 1.5 return (sid >= 0 ? p_priv->g_priv : S_NONE);
101 sysadm 1.2 }
102    
103 sysadm 1.20 int load_priv(MYSQL *db, BBS_user_priv *p_priv, int uid)
104 sysadm 1.2 {
105 sysadm 1.5 MYSQL_RES *rs;
106     MYSQL_ROW row;
107 sysadm 1.10 char sql[SQL_BUFFER_LEN];
108 sysadm 1.17 int priv;
109     int is_favor;
110 sysadm 1.5
111     p_priv->uid = uid;
112     p_priv->level = (uid == 0 ? P_GUEST : P_USER);
113     p_priv->g_priv = S_DEFAULT;
114 sysadm 1.14 p_priv->s_count = 0;
115 sysadm 1.5
116     if (db == NULL)
117     return 1;
118    
119 sysadm 1.7 // Permission
120 sysadm 1.17 snprintf(sql, sizeof(sql),
121 sysadm 1.20 "SELECT p_post, p_msg FROM user_list WHERE UID = %d AND verified",
122 sysadm 1.16 uid);
123 sysadm 1.5 if (mysql_query(db, sql) != 0)
124     {
125 sysadm 1.15 log_error("Query user_list error: %s\n", mysql_error(db));
126 sysadm 1.5 return -1;
127     }
128     if ((rs = mysql_store_result(db)) == NULL)
129     {
130 sysadm 1.7 log_error("Get user_list data failed\n");
131 sysadm 1.5 return -1;
132     }
133 sysadm 1.10 if ((row = mysql_fetch_row(rs)))
134 sysadm 1.5 {
135 sysadm 1.7 p_priv->g_priv |= (atoi(row[0]) ? S_POST : 0);
136     p_priv->g_priv |= (atoi(row[1]) ? S_MSG : 0);
137 sysadm 1.5 }
138     mysql_free_result(rs);
139    
140 sysadm 1.7 // Admin
141 sysadm 1.17 snprintf(sql, sizeof(sql),
142 sysadm 1.20 "SELECT major FROM admin_config WHERE UID = %d "
143 sysadm 1.17 "AND enable AND (NOW() BETWEEN begin_dt AND end_dt)",
144 sysadm 1.16 uid);
145 sysadm 1.5 if (mysql_query(db, sql) != 0)
146     {
147 sysadm 1.15 log_error("Query admin_config error: %s\n", mysql_error(db));
148 sysadm 1.5 return -1;
149     }
150     if ((rs = mysql_store_result(db)) == NULL)
151     {
152 sysadm 1.7 log_error("Get admin_config data failed\n");
153 sysadm 1.5 return -1;
154     }
155 sysadm 1.10 if ((row = mysql_fetch_row(rs)))
156 sysadm 1.5 {
157 sysadm 1.9 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 sysadm 1.5 }
160     mysql_free_result(rs);
161    
162     // Section Master
163 sysadm 1.17 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 sysadm 1.20 "WHERE UID = %d AND section_master.enable AND section_config.enable "
167 sysadm 1.17 "AND (NOW() BETWEEN begin_dt AND end_dt)",
168 sysadm 1.16 uid);
169 sysadm 1.5 if (mysql_query(db, sql) != 0)
170     {
171 sysadm 1.15 log_error("Query section_master error: %s\n", mysql_error(db));
172 sysadm 1.5 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 sysadm 1.10 while ((row = mysql_fetch_row(rs)))
180 sysadm 1.5 {
181     p_priv->level |= (atoi(row[1]) ? P_MAN_M : P_MAN_S);
182 sysadm 1.17 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 sysadm 1.5 }
185     mysql_free_result(rs);
186    
187     // Section status
188 sysadm 1.17 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 sysadm 1.5 if (mysql_query(db, sql) != 0)
194     {
195 sysadm 1.15 log_error("Query section_config error: %s\n", mysql_error(db));
196 sysadm 1.5 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 sysadm 1.10 while ((row = mysql_fetch_row(rs)))
204 sysadm 1.5 {
205 sysadm 1.17 int priv = getpriv(p_priv, atoi(row[0]), &is_favor);
206 sysadm 1.5 if (p_priv->level < atoi(row[2]))
207 sysadm 1.7 {
208     priv &= (~S_LIST);
209     }
210 sysadm 1.5 if (p_priv->level < atoi(row[3]))
211 sysadm 1.7 {
212     priv &= (~S_POST);
213     }
214 sysadm 1.5 if (!atoi(row[1]))
215 sysadm 1.7 {
216     priv &= (~S_GETEXP);
217     }
218 sysadm 1.17 setpriv(p_priv, atoi(row[0]), priv, is_favor);
219 sysadm 1.5 }
220     mysql_free_result(rs);
221 sysadm 1.2
222 sysadm 1.5 // Section ban
223 sysadm 1.17 snprintf(sql, sizeof(sql),
224 sysadm 1.20 "SELECT SID FROM ban_user_list WHERE UID = %d AND enable "
225 sysadm 1.17 "AND (NOW() BETWEEN ban_dt AND unban_dt)",
226 sysadm 1.16 uid);
227 sysadm 1.5 if (mysql_query(db, sql) != 0)
228     {
229 sysadm 1.15 log_error("Query ban_user_list error: %s\n", mysql_error(db));
230 sysadm 1.5 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 sysadm 1.10 while ((row = mysql_fetch_row(rs)))
238 sysadm 1.5 {
239 sysadm 1.17 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 sysadm 1.20 "SELECT SID FROM section_favorite WHERE UID = %d",
247 sysadm 1.17 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 sysadm 1.5 }
267     mysql_free_result(rs);
268    
269     return 0;
270 sysadm 1.1 }

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