From cf12bc723bec48c9ea7d706d2ddc13bcceae4248 Mon Sep 17 00:00:00 2001
From: Rob Swindell <rob@synchro.net>
Date: Fri, 1 Jan 2021 17:25:42 -0800
Subject: [PATCH] New user API functions to determine directory access

can_access/upload/download and is_operator
similar to what we already had defined for sub-boards
---
 src/sbbs3/userdat.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
 src/sbbs3/userdat.h |  4 +++
 2 files changed, 88 insertions(+)

diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c
index 44f6079cef..e3c7513cea 100644
--- a/src/sbbs3/userdat.c
+++ b/src/sbbs3/userdat.c
@@ -2981,6 +2981,75 @@ BOOL can_user_post(scfg_t* cfg, uint subnum, user_t* user, client_t* client, uin
 	return TRUE;
 }
 
+/****************************************************************************/
+/* Determine if the specified user can or cannot access the specified dir	*/
+/****************************************************************************/
+BOOL can_user_access_dir(scfg_t* cfg, uint dirnum, user_t* user, client_t* client)
+{
+	if(!VALID_CFG(cfg))
+		return FALSE;
+	if(dirnum>=cfg->total_dirs)
+		return FALSE;
+	if(!chk_ar(cfg,cfg->lib[cfg->dir[dirnum]->lib]->ar,user,client))
+		return FALSE;
+	if(!chk_ar(cfg,cfg->dir[dirnum]->ar,user,client))
+		return FALSE;
+
+	return TRUE;
+}
+
+/****************************************************************************/
+/* Determine if the specified user can or cannot upload files to the dirnum	*/
+/* 'reason' is an (optional) pointer to a text.dat item number, indicating	*/
+/* the reason the user cannot post, when returning FALSE.					*/
+/****************************************************************************/
+BOOL can_user_upload(scfg_t* cfg, uint dirnum, user_t* user, client_t* client, uint* reason)
+{
+	if(reason!=NULL)
+		*reason=NoAccessDir;
+	if(!can_user_access_dir(cfg, dirnum, user, client))
+		return FALSE;
+	if(reason!=NULL)
+		*reason=R_Upload;
+	if(user->rest&FLAG('U'))			/* upload restriction? */
+		return FALSE;
+	if(user->rest&FLAG('T'))			/* transfer restriction? */
+		return FALSE;
+	if(!(user->exempt&FLAG('U'))		/* upload exemption */
+		&& !is_user_dirop(cfg, dirnum, user, client)) {
+		if(reason!=NULL)
+			*reason=CantUploadHere;
+		if(!chk_ar(cfg, cfg->dir[dirnum]->ul_ar, user, client))
+			return FALSE;
+	}
+	return TRUE;
+}
+
+/****************************************************************************/
+/* Determine if the specified user can or cannot download files from dirnum	*/
+/* 'reason' is an (optional) pointer to a text.dat item number, indicating	*/
+/* the reason the user cannot post, when returning FALSE.					*/
+/****************************************************************************/
+BOOL can_user_download(scfg_t* cfg, uint dirnum, user_t* user, client_t* client, uint* reason)
+{
+	if(reason!=NULL)
+		*reason=NoAccessDir;
+	if(!can_user_access_dir(cfg, dirnum, user, client))
+		return FALSE;
+	if(reason!=NULL)
+		*reason=CantDownloadFromDir;
+	if(!chk_ar(cfg,cfg->dir[dirnum]->dl_ar,user,client))
+		return FALSE;
+	if(reason!=NULL)
+		*reason=R_Download;
+	if(user->rest&FLAG('D'))			/* download restriction? */
+		return FALSE;
+	if(user->rest&FLAG('T'))			/* transfer restriction? */
+		return FALSE;
+
+	return TRUE;
+}
+
 /****************************************************************************/
 /* Determine if the specified user can or cannot send email					*/
 /* 'reason' is an (optional) pointer to a text.dat item number				*/
@@ -3029,6 +3098,21 @@ BOOL is_user_subop(scfg_t* cfg, uint subnum, user_t* user, client_t* client)
 	return cfg->sub[subnum]->op_ar!=NULL && cfg->sub[subnum]->op_ar[0]!=0 && chk_ar(cfg,cfg->sub[subnum]->op_ar,user,client);
 }
 
+/****************************************************************************/
+/* Determine if the specified user is a directory operator					*/
+/****************************************************************************/
+BOOL is_user_dirop(scfg_t* cfg, uint dirnum, user_t* user, client_t* client)
+{
+	if(user==NULL)
+		return FALSE;
+	if(!can_user_access_dir(cfg, dirnum, user, client))
+		return FALSE;
+	if(user->level >= SYSOP_LEVEL)
+		return TRUE;
+
+	return cfg->dir[dirnum]->op_ar!=NULL && cfg->dir[dirnum]->op_ar[0]!=0 && chk_ar(cfg,cfg->dir[dirnum]->op_ar,user,client);
+}
+
 /****************************************************************************/
 /* Determine if downloads from the specified directory are free for the		*/
 /* specified user															*/
diff --git a/src/sbbs3/userdat.h b/src/sbbs3/userdat.h
index 3d78be70fe..4014af73a0 100644
--- a/src/sbbs3/userdat.h
+++ b/src/sbbs3/userdat.h
@@ -90,11 +90,15 @@ DLLEXPORT BOOL	logoutuserdat(scfg_t*, user_t*, time_t now, time_t logontime);
 DLLEXPORT void	resetdailyuserdat(scfg_t*, user_t*, BOOL write);
 DLLEXPORT void	subtract_cdt(scfg_t*, user_t*, long amt);
 DLLEXPORT int	user_rec_len(int offset);
+DLLEXPORT BOOL	can_user_access_dir(scfg_t*, uint dirnum, user_t*, client_t* client);
 DLLEXPORT BOOL	can_user_access_sub(scfg_t*, uint subnum, user_t*, client_t* client);
 DLLEXPORT BOOL	can_user_read_sub(scfg_t*, uint subnum, user_t*, client_t* client);
 DLLEXPORT BOOL	can_user_post(scfg_t*, uint subnum, user_t*, client_t* client, uint* reason);
+DLLEXPORT BOOL	can_user_upload(scfg_t*, uint dirnum, user_t*, client_t* client, uint* reason);
+DLLEXPORT BOOL	can_user_download(scfg_t*, uint dirnum, user_t*, client_t* client, uint* reason);
 DLLEXPORT BOOL	can_user_send_mail(scfg_t*, enum smb_net_type, uint usernumber, user_t*, uint* reason);
 DLLEXPORT BOOL	is_user_subop(scfg_t*, uint subnum, user_t*, client_t* client);
+DLLEXPORT BOOL	is_user_dirop(scfg_t*, uint dirnum, user_t*, client_t* client);
 DLLEXPORT BOOL	is_download_free(scfg_t*, uint dirnum, user_t*, client_t* client);
 DLLEXPORT BOOL	is_host_exempt(scfg_t*, const char* ip_addr, const char* host_name);
 DLLEXPORT BOOL	filter_ip(scfg_t*, const char* prot, const char* reason, const char* host
-- 
GitLab