nwconn: keep disk restriction scans local
All checks were successful
Source release / source-package (push) Successful in 51s

Keep NCP 0x16/0x20 Scan Volume User Disk Restrictions from linking nwconn against bindery database helpers.

The WebSDK documents the scan call as returning a sequence of Object ID / Restriction pairs, while the per-object NCP 0x16/0x29 query can be resolved through nwbind because it carries a concrete Object ID. The scan call is different: producing a quota-backed list requires iterating bindery user objects and reading each UNIX_USER property, which belongs to the nwbind/nwdbm side of the existing process split.

The previous implementation attempted that scan directly in nwconn and therefore referenced scan_for_obj() and nw_get_prop_val_by_obj_id(), which are provided by nwdbm and are not linked into the nwconn executable. This broke quota-enabled builds when the endpoint was compiled.

Return the SDK-compatible empty list after validating the volume, matching the existing non-quota behavior and the conservative behavior used by other open implementations. Leave real quota-backed scan enumeration as future nwbind-side work instead of pulling bindery database code into nwconn.

This fixes the build and preserves the documented endpoint shape; real quota scanning remains unimplemented.
This commit is contained in:
Mario Fetka
2026-05-29 23:48:39 +00:00
parent eb2983bc1a
commit ad153b88b9

View File

@@ -45,7 +45,6 @@
#include "nwqconn.h"
#include "namspace.h"
#include "nwshare.h"
#include "nwdbm.h"
#include "nwconn.h"
#include "trustee.h"
#include "nwatalk.h"
@@ -87,69 +86,24 @@ static int scan_volume_user_disk_restrictions(uint8 volnr, uint32 sequence,
{
struct XDATA {
uint8 entries;
struct {
uint8 id[4];
uint8 restriction[4];
} entry[12];
} *xdata = (struct XDATA *)response;
int result = nw_get_volume_name(volnr, NULL, 0);
(void)sequence;
if (result < 0)
return result;
/*
* Keep the scan reply empty for now. The per-object quota query can be
* routed through nwbind because it has a concrete object id to resolve,
* but this scan call would need bindery iteration plus UNIX_USER property
* lookups from nwbind-side code. nwconn does not link the bindery database
* helpers, and pulling them into this process would break the existing
* process split.
*/
xdata->entries = 0;
#if QUOTA_SUPPORT
{
NETOBJ obj;
uint32 last_obj_id = MAX_U32;
uint32 restricted_index = 0;
uint8 wild[] = "*";
int scan_result;
memset(&obj, 0, sizeof(obj));
obj.type = 1; /* user */
xstrcpy(obj.name, wild);
scan_result = scan_for_obj(&obj, last_obj_id, 1);
while (!scan_result && xdata->entries < 12) {
uint8 more_segments = 0;
uint8 property_flags = 0;
char unix_user[128];
uint32 restriction = 0x40000000;
uint32 inuse = 0;
memset(unix_user, 0, sizeof(unix_user));
if (!nw_get_prop_val_by_obj_id(obj.id, 1,
(uint8 *)"UNIX_USER", 9,
(uint8 *)unix_user, &more_segments, &property_flags)) {
struct passwd *pw;
unix_user[sizeof(unix_user)-1] = '\0';
pw = getpwnam(unix_user);
if (pw && !nw_get_vol_restrictions(volnr, pw->pw_uid,
&restriction, &inuse) &&
restriction < 0x40000000) {
if (restricted_index >= sequence) {
U32_TO_BE32(obj.id, xdata->entry[xdata->entries].id);
U32_TO_BE32(restriction, xdata->entry[xdata->entries].restriction);
xdata->entries++;
}
restricted_index++;
}
}
last_obj_id = obj.id;
memset(&obj, 0, sizeof(obj));
obj.type = 1;
xstrcpy(obj.name, wild);
scan_result = scan_for_obj(&obj, last_obj_id, 1);
}
}
#endif
return 1 + (8 * xdata->entries);
return 1;
}
static int trustee_v3_to_ncp22_rights(int rights)