pastebin - collaborative debugging tool
rovema.kpaste.net RSS


Infrastructure to give files without account Unix_User/Unix_Group SIDs
Posted by Anonymous on Wed 11th Oct 2023 17:54
raw | new post

  1. From 07c4a9d4204b4d9b7dde8808a9c180ba9d0e109c Mon Sep 17 00:00:00 2001
  2. From: Roland Mainz <roland.mainz@nrubsig.org>
  3. Date: Wed, 11 Oct 2023 17:18:02 +0200
  4. Subject: [PATCH 2/2] Infrastructure to give files without account
  5.  Unix_User/Unix_Group SIDs
  6.  
  7. Add infrastructure to give files with uid/gid data (uid number or
  8. NFSv4 owner/owner_group) which cannot be mapped to a local account
  9. SIDs from the Unix_User+x/Unix_Group+x SID range.
  10. See https://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-mapping-samba
  11. for an explanation.
  12.  
  13. The code is currently disabled (set
  14. |NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID| to |1| in
  15. sys/nfs41_build_features.h to enable it), until we wire it into
  16. the idmap code.
  17.  
  18. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  19. ---
  20. daemon/acl.c               | 257 ++++++++++++++++++++++++++++++++++---
  21.  sys/nfs41_build_features.h |   7 +
  22.  2 files changed, 247 insertions(+), 17 deletions(-)
  23.  
  24. diff --git a/daemon/acl.c b/daemon/acl.c
  25. index 3a86735..c1a5f4f 100644
  26. --- a/daemon/acl.c
  27. +++ b/daemon/acl.c
  28. @@ -24,6 +24,7 @@
  29.  #include <sddl.h>
  30.  
  31.  #include "nfs41_ops.h"
  32. +#include "nfs41_build_features.h"
  33.  #include "delegation.h"
  34.  #include "daemon_debug.h"
  35.  #include "util.h"
  36. @@ -60,19 +61,26 @@ static int create_unknownsid(WELL_KNOWN_SID_TYPE type, PSID *sid,
  37.      dprintf(ACLLVL, "create_unknownsid: CreateWellKnownSid type %d returned %d "
  38.              "GetLastError %d sid len %d needed\n", type, status,
  39.              GetLastError(), *sid_len);
  40. -    if (status)
  41. -        return ERROR_INTERNAL_ERROR;
  42. +    if (status) {
  43. +        status = ERROR_INTERNAL_ERROR;
  44. +        goto err;
  45. +    }
  46.      status = GetLastError();
  47. -    if (status != ERROR_INSUFFICIENT_BUFFER)
  48. -        return status;
  49. +    if (status != ERROR_INSUFFICIENT_BUFFER)
  50. +        goto err;
  51. +
  52.      *sid = malloc(*sid_len);
  53. -    if (*sid == NULL)
  54. -        return ERROR_INSUFFICIENT_BUFFER;
  55. +    if (*sid == NULL) {
  56. +        status = ERROR_INSUFFICIENT_BUFFER;
  57. +        goto err;
  58. +    }
  59.      status = CreateWellKnownSid(type, NULL, *sid, sid_len);
  60. -    if (status)
  61. +    if (status)
  62.          return ERROR_SUCCESS;
  63.      free(*sid);
  64. +    *sid = NULL;
  65.      status = GetLastError();
  66. +err:
  67.      eprintf("create_unknownsid: CreateWellKnownSid failed with %d\n", status);
  68.      return status;
  69.  }
  70. @@ -90,17 +98,136 @@ static void convert_nfs4name_2_user_domain(LPSTR nfs4name,
  71.      }
  72.  }
  73.  
  74. -static int map_name_2_sid(DWORD *sid_len, PSID *sid, LPCSTR name)
  75. +#ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  76. +/*
  77. + * Allocate a SID from SECURITY_SAMBA_UNIX_AUTHORITY, which encodes an
  78. + * UNIX/POSIX uid directly into a SID.
  79. + *
  80. + * Examples:
  81. + * UID 1616 gets mapped to "Unix_User+1616", encoding the UID into the
  82. + * SID as "S-1-22-1-1616":
  83. + * $ getent passwd Unix_User+1616
  84. + * Unix_User+1616:*:4278191696:4278191696:U-Unix_User616,S-1-22-1-1616:/:/sbin/nologin
  85. + *
  86. + * GID 1984 gets mapped to "Unix_Group+1984", encoding the GID into the
  87. + * SID as "S-1-22-2-1984":
  88. + * $ getent group Unix_Group+1984
  89. + * Unix_Group+1984:S-1-22-2-1984:4278192064:
  90. + *
  91. + */
  92. +
  93. +#define SECURITY_SAMBA_UNIX_AUTHORITY { { 0,0,0,0,0,22 } }
  94. +SID_IDENTIFIER_AUTHORITY sid_id_auth = SECURITY_SAMBA_UNIX_AUTHORITY;
  95. +
  96. +static
  97. +BOOL allocate_unixuser_sid(unsigned long uid, PSID *pSid)
  98. +{
  99. +    PSID sid = NULL;
  100. +    PSID malloced_sid = NULL;
  101. +    DWORD sid_len;
  102. +
  103. +    if (AllocateAndInitializeSid(&sid_id_auth, 2, 1, (DWORD)uid,
  104. +        0, 0, 0, 0, 0, 0, &sid)) {
  105. +        sid_len = GetLengthSid(sid);
  106. +
  107. +        malloced_sid = malloc(sid_len);
  108. +
  109. +        if (malloced_sid) {
  110. +            /*
  111. +             * |AllocateAndInitializeSid()| has an own memory
  112. +             * allocator, but we need the sid in memory from
  113. +             * |malloc()|
  114. +             */
  115. +            if (CopySid(sid_len, malloced_sid, sid)) {
  116. +                FreeSid(sid);
  117. +                *pSid = malloced_sid;
  118. +                dprintf(ACLLVL, "allocate_unixuser_sid(): Allocated "
  119. +                    "Unix_User+%lu: success, len=%ld\n",
  120. +                    uid, (long)sid_len);
  121. +                return TRUE;
  122. +            }
  123. +        }
  124. +    }
  125. +
  126. +    FreeSid(sid);
  127. +    free(malloced_sid);
  128. +    dprintf(ACLLVL, "allocate_unixuser_sid(): Failed to allocate "
  129. +        "SID for Unix_User+%lu: error code %d\n",
  130. +        uid, GetLastError());
  131. +    return FALSE;
  132. +}
  133. +
  134. +static
  135. +BOOL allocate_unixgroup_sid(unsigned long gid, PSID *pSid)
  136. +{
  137. +    PSID sid = NULL;
  138. +    PSID malloced_sid = NULL;
  139. +    DWORD sid_len;
  140. +
  141. +    if (AllocateAndInitializeSid(&sid_id_auth, 2, 2, (DWORD)gid,
  142. +        0, 0, 0, 0, 0, 0, &sid)) {
  143. +        sid_len = GetLengthSid(sid);
  144. +
  145. +        malloced_sid = malloc(sid_len);
  146. +
  147. +        if (malloced_sid) {
  148. +            /*
  149. +             * |AllocateAndInitializeSid()| has an own memory
  150. +             * allocator, but we need the sid in memory from
  151. +             * |malloc()|
  152. +             */
  153. +            if (CopySid(sid_len, malloced_sid, sid)) {
  154. +                FreeSid(sid);
  155. +                *pSid = malloced_sid;
  156. +                dprintf(ACLLVL, "allocate_unixgroup_sid(): Allocated "
  157. +                    "Unix_Group+%lu: success, len=%ld\n",
  158. +                    gid, (long)sid_len);
  159. +                return TRUE;
  160. +            }
  161. +        }
  162. +    }
  163. +
  164. +    FreeSid(sid);
  165. +    free(malloced_sid);
  166. +    dprintf(ACLLVL, "allocate_unixgroup_sid(): Failed to allocate "
  167. +        "SID for Unix_Group+%lu: error code %d\n",
  168. +        gid, GetLastError());
  169. +    return FALSE;
  170. +}
  171. +#endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  172. +
  173. +static int map_name_2_sid(int query, DWORD *sid_len, PSID *sid, LPCSTR name)
  174.  {
  175.      int status = ERROR_INTERNAL_ERROR;
  176.      SID_NAME_USE sid_type;
  177.      LPSTR tmp_buf = NULL;
  178.      DWORD tmp = 0;
  179. +#ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  180. +    signed long user_uid = -1;
  181. +    signed long group_gid = -1;
  182. +#endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  183. +
  184. +#ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  185. +    if (query & OWNER_SECURITY_INFORMATION) {
  186. +        if (!strcmp(name, "rmainz")) {
  187. +            name = "roland_mainz";
  188. +            dprintf(ACLLVL, "map_name_2_sid: remap rmainz --> roland_mainz\n");
  189. +        }
  190. +        else if (!strcmp(name, "197608")) {
  191. +            name = "roland_mainz";
  192. +            dprintf(ACLLVL, "map_name_2_sid: remap 197608 --> roland_mainz\n");
  193. +        }
  194. +        else if (!strcmp(name, "1616")) {
  195. +            name = "roland_mainz";
  196. +            dprintf(ACLLVL, "map_name_2_sid: remap 1616 --> roland_mainz\n");
  197. +        }
  198. +    }
  199. +#endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  200.  
  201.      status = LookupAccountName(NULL, name, NULL, sid_len, NULL, &tmp, &sid_type);
  202. -    dprintf(ACLLVL, "map_name_2_sid: LookupAccountName for %s returned %d "
  203. -            "GetLastError %d name len %d domain len %d\n", name, status,
  204. -            GetLastError(), *sid_len, tmp);
  205. +    dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): LookupAccountName returned %d "
  206. +            "GetLastError %d name len %d domain len %d\n",
  207. +            query, name, status, GetLastError(), *sid_len, tmp);
  208.      if (status)
  209.          return ERROR_INTERNAL_ERROR;
  210.  
  211. @@ -119,8 +246,8 @@ static int map_name_2_sid(DWORD *sid_len, PSID *sid, LPCSTR name)
  212.                                      &tmp, &sid_type);
  213.          free(tmp_buf);
  214.          if (!status) {
  215. -            eprintf("map_name_2_sid: LookupAccountName for %s failed "
  216. -                    "with %d\n", name, GetLastError());
  217. +            eprintf("map_name_2_sid(query=%x,name='%s'): LookupAccountName failed "
  218. +                    "with %d\n", query, name, GetLastError());
  219.              goto out_free_sid;
  220.          } else {
  221.  #ifdef DEBUG_ACLS
  222. @@ -140,15 +267,109 @@ static int map_name_2_sid(DWORD *sid_len, PSID *sid, LPCSTR name)
  223.          status = ERROR_SUCCESS;
  224.          break;
  225.      case ERROR_NONE_MAPPED:
  226. +#ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  227. +        dprintf(1, "map_name_2_sid(query=%x,name='%s'): none mapped, "
  228. +            "trying Unix_User+/Unix_Group+ mapping\n",
  229. +            query, name);
  230. +
  231. +        if ((user_uid == -1) && (query & OWNER_SECURITY_INFORMATION)) {
  232. +            if (isdigit(name[0])) {
  233. +                user_uid = atol(name);
  234. +            }
  235. +            else if(!strcmp(name, "nobody")) {
  236. +                user_uid = 65534;
  237. +            }
  238. +            else if(!strcmp(name, "root")) {
  239. +                user_uid = 0;
  240. +            }
  241. +            else if(!strcmp(name, "rmainz")) {
  242. +                user_uid = 1616;
  243. +            }
  244. +            else if(!strcmp(name, "swulsch")) {
  245. +                user_uid = 1818;
  246. +            }
  247. +            else if(!strcmp(name, "mwenzel")) {
  248. +                user_uid = 8239;
  249. +            }
  250. +            else if(!strcmp(name, "test001")) {
  251. +                user_uid = 1000;
  252. +            }
  253. +        }
  254. +
  255. +        if ((group_gid == -1) && (query & GROUP_SECURITY_INFORMATION)) {
  256. +            if (isdigit(name[0])) {
  257. +                group_gid = atol(name);
  258. +            }
  259. +            else if(!strcmp(name, "nobody")) {
  260. +                group_gid = 65534;
  261. +            }
  262. +            else if(!strcmp(name, "root")) {
  263. +                group_gid = 0;
  264. +            }
  265. +            else if(!strcmp(name, "rmainz")) {
  266. +                group_gid = 1616;
  267. +            }
  268. +            else if(!strcmp(name, "swulsch")) {
  269. +                group_gid = 1818;
  270. +            }
  271. +            else if(!strcmp(name, "mwenzel")) {
  272. +                group_gid = 8239;
  273. +            }
  274. +            else if(!strcmp(name, "test001")) {
  275. +                group_gid = 1000;
  276. +            }
  277. +        }
  278. +
  279. +        if (user_uid != -1) {
  280. +            if (allocate_unixuser_sid(user_uid, sid)) {
  281. +                dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): "
  282. +                    "allocate_unixuser_sid(uid=%ld) success\n",
  283. +                    query, name, user_uid);
  284. +                return ERROR_SUCCESS;
  285. +            }
  286. +
  287. +            status = GetLastError();
  288. +            dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): "
  289. +                "allocate_unixuser_sid(uid=%ld) failed, error=%d\n",
  290. +                query, name, user_uid, status);
  291. +            return status;
  292. +        }
  293. +
  294. +        if (group_gid != -1) {
  295. +            if (allocate_unixgroup_sid(group_gid, sid)) {
  296. +                dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): "
  297. +                    "allocate_unixgroup_sid(gid=%ld) success\n",
  298. +                    query, name, group_gid);
  299. +                return ERROR_SUCCESS;
  300. +            }
  301. +
  302. +            status = GetLastError();
  303. +            dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): "
  304. +                "allocate_unixgroup_sid(gid=%ld) failed, error=%d\n",
  305. +                query, name, group_gid, status);
  306. +            return status;
  307. +        }
  308. +#endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  309. +
  310. +        dprintf(1, "map_name_2_sid(query=%x,name='%s'): none mapped, "
  311. +            "using WinNullSid mapping\n",
  312. +            query, name);
  313. +
  314.          status = create_unknownsid(WinNullSid, sid, sid_len);
  315.          if (status)
  316.              goto out_free_sid;
  317. +        break;
  318. +    default:
  319. +        dprintf(1, "map_name_2_sid(query=%x,name='%s'): error %d not handled\n",
  320. +            query, name, GetLastError());
  321. +        break;
  322.      }
  323.  out:
  324.      return status;
  325.  out_free_sid:
  326.      status = GetLastError();
  327.      free(*sid);
  328. +    *sid = NULL;
  329.      goto out;
  330.  }
  331.  
  332. @@ -208,7 +429,8 @@ static int convert_nfs4acl_2_dacl(nfsacl41 *acl, int file_type,
  333.              goto out;
  334.          }
  335.          if (!flag) {
  336. -            status = map_name_2_sid(&sid_len, &sids[i], acl->aces[i].who);
  337. +            status = map_name_2_sid(0xFFFF /* fixme: Unknown whether user or group */,
  338. +                &sid_len, &sids[i], acl->aces[i].who);
  339.              if (status) {
  340.                  free_sids(sids, i);
  341.                  goto out;
  342. @@ -322,7 +544,7 @@ static int handle_getacl(nfs41_upcall *upcall)
  343.          dprintf(ACLLVL, "handle_getacl: OWNER_SECURITY_INFORMATION: for user=%s "
  344.                  "domain=%s\n", info.owner, domain?domain:"<null>");
  345.          sid_len = 0;
  346. -        status = map_name_2_sid(&sid_len, &osid, info.owner);
  347. +        status = map_name_2_sid(OWNER_SECURITY_INFORMATION, &sid_len, &osid, info.owner);
  348.          if (status)
  349.              goto out;
  350.          status = SetSecurityDescriptorOwner(&sec_desc, osid, TRUE);
  351. @@ -333,12 +555,13 @@ static int handle_getacl(nfs41_upcall *upcall)
  352.              goto out;
  353.          }
  354.      }
  355. +
  356.      if (args->query & GROUP_SECURITY_INFORMATION) {
  357.          convert_nfs4name_2_user_domain(info.owner_group, &domain);
  358.          dprintf(ACLLVL, "handle_getacl: GROUP_SECURITY_INFORMATION: for %s "
  359.                  "domain=%s\n", info.owner_group, domain?domain:"<null>");
  360.          sid_len = 0;
  361. -        status = map_name_2_sid(&sid_len, &gsid, info.owner_group);
  362. +        status = map_name_2_sid(GROUP_SECURITY_INFORMATION, &sid_len, &gsid, info.owner_group);
  363.          if (status)
  364.              goto out;
  365.          status = SetSecurityDescriptorGroup(&sec_desc, gsid, TRUE);
  366. @@ -798,4 +1021,4 @@ const nfs41_upcall_op nfs41_op_setacl = {
  367.      parse_setacl,
  368.      handle_setacl,
  369.      marshall_setacl
  370. -};
  371. \ No newline at end of file
  372. +};
  373. diff --git a/sys/nfs41_build_features.h b/sys/nfs41_build_features.h
  374. index 4ce5976..f8ea548 100644
  375. --- a/sys/nfs41_build_features.h
  376. +++ b/sys/nfs41_build_features.h
  377. @@ -35,4 +35,11 @@
  378.  // #define NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES 1
  379.  // #define NFS41_DRIVER_FEATURE_LOCAL_UIDGID_TESTMAPPING 1
  380.  
  381. +/*
  382. + * NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID - give NFS
  383. + * files which do not map to a local account a SID in the
  384. + * Unix_User+x/Unix_Group+x range
  385. + */
  386. +// #define NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID 1
  387. +
  388.  #endif /* !_NFS41_DRIVER_BUILDFEATURES_ */
  389. --
  390. 2.39.0

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at