pastebin - collaborative debugging tool
rovema.kpaste.net RSS


msnfs41_client: idmap support with Cygwin getent passwd/group prototype
Posted by Anonymous on Tue 19th Sep 2023 13:52
raw | new post
view followups (newest first): msnfs41_client: idmap support with Cygwin getent passwd/group prototype by Anonymous
modification of post by Anonymous (view diff)

  1. diff --git a/daemon/acl.c b/daemon/acl.c
  2. index 3a86735..61a737d 100644
  3. --- a/daemon/acl.c
  4. +++ b/daemon/acl.c
  5. @@ -65,6 +65,9 @@ static int create_unknownsid(WELL_KNOWN_SID_TYPE type, PSID *sid,
  6.      status = GetLastError();
  7.      if (status != ERROR_INSUFFICIENT_BUFFER)
  8.          return status;
  9. +#if 1
  10. +*sid_len += 256;
  11. +#endif
  12.      *sid = malloc(*sid_len);
  13.      if (*sid == NULL)
  14.          return ERROR_INSUFFICIENT_BUFFER;
  15. @@ -97,6 +100,11 @@ static int map_name_2_sid(DWORD *sid_len, PSID *sid, LPCSTR name)
  16.      LPSTR tmp_buf = NULL;
  17.      DWORD tmp = 0;
  18.  
  19. +#if 1
  20. +    /* test mapping: Map UNIX user "rmainz" to Windows user "roland_mainz" */
  21. +    if (!_stricmp(name, "rmainz"))
  22. +       name = "roland_mainz";
  23. +#endif
  24.      status = LookupAccountName(NULL, name, NULL, sid_len, NULL, &tmp, &sid_type);
  25.      dprintf(ACLLVL, "map_name_2_sid: LookupAccountName for %s returned %d "
  26.              "GetLastError %d name len %d domain len %d\n", name, status,
  27. @@ -107,6 +115,9 @@ static int map_name_2_sid(DWORD *sid_len, PSID *sid, LPCSTR name)
  28.      status = GetLastError();
  29.      switch(status) {
  30.      case ERROR_INSUFFICIENT_BUFFER:
  31. +#if 1
  32. +*sid_len += 256;
  33. +#endif
  34.          *sid = malloc(*sid_len);
  35.          if (*sid == NULL) {
  36.              status = GetLastError();
  37. @@ -798,4 +809,4 @@ const nfs41_upcall_op nfs41_op_setacl = {
  38.      parse_setacl,
  39.      handle_setacl,
  40.      marshall_setacl
  41. -};
  42. \ No newline at end of file
  43. +};
  44. diff --git a/daemon/idmap.c b/daemon/idmap.c
  45. index 0dfa8ef..b50f4e2 100644
  46. --- a/daemon/idmap.c
  47. +++ b/daemon/idmap.c
  48. @@ -31,6 +31,7 @@
  49.  #include "list.h"
  50.  #include "daemon_debug.h"
  51.  
  52. +#define CYGWIN_GETENT_USERDATA 1
  53.  
  54.  #define IDLVL 2 /* dprintf level for idmap logging */
  55.  
  56. @@ -375,6 +376,156 @@ out:
  57.      return status;
  58.  }
  59.  
  60. +#ifdef CYGWIN_GETENT_USERDATA
  61. +int cygwin_getent_passwd(const char *name, char *res_loginname, uid_t *res_uid, gid_t *res_gid)
  62. +{
  63. +    char cmdbuff[1024];
  64. +    char passwd_line[1024];
  65. +    FILE* getent_pipe;
  66. +    int res = 1;
  67. +
  68. +    /* fixme: better quoting for |name| needed */
  69. +    (void)snprintf(cmdbuff, sizeof(cmdbuff), "%s passwd \"%s\"",
  70. +        "C:\\cygwin64\\bin\\getent.exe",
  71. +        name);
  72. +    if ((getent_pipe = _popen(cmdbuff, "rt")) == NULL)
  73. +    {
  74. +        (void)perror("getent failed");
  75. +        return 1;
  76. +    }
  77. +
  78. +    if (fgets(passwd_line, sizeof(passwd_line), getent_pipe))
  79. +    {
  80. +        struct _cypwent
  81. +        {
  82. +            char* loginname;
  83. +            char* passwd;
  84. +            char* uidstr;
  85. +            char* gidstr;
  86. +            char* comment;
  87. +            char* homedir;
  88. +            char* shell;
  89. +        } pwent = { 0 };
  90. +#define PWENT_ENTRY(var, prevvar) \
  91. +            (((var) = strchr((prevvar), ':'))?(*(var)++ = '\0',(var)):(NULL))
  92. +
  93. +        pwent.loginname = passwd_line;
  94. +        if (!PWENT_ENTRY(pwent.passwd, pwent.loginname)) goto fail;
  95. +        if (!PWENT_ENTRY(pwent.uidstr, pwent.passwd)) goto fail;
  96. +        if (!PWENT_ENTRY(pwent.gidstr, pwent.uidstr)) goto fail;
  97. +        if (!PWENT_ENTRY(pwent.comment, pwent.gidstr)) goto fail;
  98. +        if (!PWENT_ENTRY(pwent.homedir, pwent.comment)) goto fail;
  99. +        PWENT_ENTRY(pwent.shell, pwent.homedir);
  100. +    
  101. +        unsigned long uid;
  102. +        unsigned long gid;
  103. +
  104. +        errno = 0;
  105. +        uid = strtol(pwent.uidstr, NULL, 10);
  106. +        if (errno != 0)
  107. +            goto fail;
  108. +
  109. +        errno = 0;
  110. +        gid = strtol(pwent.gidstr, NULL, 10);
  111. +        if (errno != 0)
  112. +            goto fail;
  113. +
  114. +#if 1
  115. +       /* hack for testing, map "roland_mainz" to rmainz account */
  116. +       if (!_stricmp(pwent.loginname, "roland_mainz")) {
  117. +               uid = 1616;
  118. +               gid = 1616;
  119. +       }
  120. +#endif
  121. +#if 0
  122. +        (void)printf("loginname\t=%s\n", pwent.loginname);
  123. +        (void)printf("passwd\t=%s\n", pwent.passwd);
  124. +        (void)printf("uidstr\t=%s (%lu)\n", pwent.uidstr, (unsigned long)uid);
  125. +        (void)printf("gidstr\t=%s (%lu)\n", pwent.gidstr, (unsigned long)gid);
  126. +        (void)printf("comment\t=%s\n", pwent.comment);
  127. +        (void)printf("homedir\t=%s\n", pwent.homedir);
  128. +        (void)printf("shell\t=%s\n", pwent.shell);
  129. +#endif
  130. +        if (res_loginname)
  131. +            (void)strcpy_s(res_loginname, VAL_LEN, pwent.loginname);
  132. +        *res_uid = uid;
  133. +        *res_gid = gid;
  134. +        res = 0;
  135. +    }
  136. +
  137. +fail:
  138. +    (void)_pclose(getent_pipe);
  139. +
  140. +    return res;
  141. +}
  142. +
  143. +int cygwin_getent_group(const char* name, char* res_group_name, gid_t* res_gid)
  144. +{
  145. +    char cmdbuff[1024];
  146. +    char group_line[1024];
  147. +    FILE* getent_pipe;
  148. +    int res = 1;
  149. +
  150. +    /* fixme: better quoting for |name| needed */
  151. +    (void)snprintf(cmdbuff, sizeof(cmdbuff), "%s group \"%s\"",
  152. +        "C:\\cygwin64\\bin\\getent.exe",
  153. +        name);
  154. +    if ((getent_pipe = _popen(cmdbuff, "rt")) == NULL)
  155. +    {
  156. +        (void)perror("getent failed");
  157. +        return 1;
  158. +    }
  159. +
  160. +    if (fgets(group_line, sizeof(group_line), getent_pipe))
  161. +    {
  162. +        struct _cygrent
  163. +        {
  164. +            char* group_name;
  165. +            char* passwd;
  166. +            char* gidstr;
  167. +            char* userlist;
  168. +        } grent = { 0 };
  169. +
  170. +        grent.group_name = group_line;
  171. +        if (!PWENT_ENTRY(grent.passwd, grent.group_name)) goto fail;
  172. +        if (!PWENT_ENTRY(grent.gidstr, grent.passwd)) goto fail;
  173. +        PWENT_ENTRY(grent.userlist, grent.gidstr);
  174. +
  175. +        unsigned long gid;
  176. +
  177. +        errno = 0;
  178. +        gid = strtol(grent.gidstr, NULL, 10);
  179. +        if (errno != 0)
  180. +            goto fail;
  181. +
  182. +#if 1
  183. +       /* hack for testing, map "roland_mainz" to rmainz account */
  184. +       if (!_stricmp(grent.group_name, "roland_mainz")) {
  185. +               gid = 1616;
  186. +       }
  187. +#endif
  188. +
  189. +        (void)printf("group_name\t=%s\n", grent.group_name);
  190. +        (void)printf("passwd\t=%s\n", grent.passwd);
  191. +        (void)printf("gidstr\t=%s (%lu)\n", grent.gidstr, (unsigned long)gid);
  192. +        (void)printf("userlist\t=%s\n", grent.userlist);
  193. +
  194. +        if (res_group_name)
  195. +            (void)strcpy_s(res_group_name, VAL_LEN, grent.group_name);
  196. +        *res_gid = gid;
  197. +        res = 0;
  198. +    }
  199. +    else
  200. +    {
  201. +        (void)puts("no match for group");
  202. +    }
  203. +
  204. +fail:
  205. +    (void)_pclose(getent_pipe);
  206. +
  207. +    return res;
  208. +}
  209. +#endif /* CYGWIN_GETENT_USERDATA */
  210.  
  211.  /* generic cache */
  212.  typedef struct list_entry* (*entry_alloc_fn)();
  213. @@ -665,10 +816,10 @@ static int idmap_lookup_user(
  214.      if (status == NO_ERROR) {
  215.          /* don't return expired entries; query new attributes
  216.           * and overwrite the entry with cache_insert() */
  217. -        if (time(NULL) - user->last_updated < context->config.cache_ttl)
  218. +        if ((time(NULL) - user->last_updated) < context->config.cache_ttl)
  219.              goto out;
  220.      }
  221. -
  222. +#if 0
  223.      /* send the query to the ldap server */
  224.      status = idmap_query_attrs(context, lookup,
  225.          attributes, optional, values, NUM_ATTRIBUTES);
  226. @@ -705,7 +856,91 @@ static int idmap_lookup_user(
  227.          goto out_free_values;
  228.      }
  229.      user->last_updated = time(NULL);
  230. -
  231. +#else
  232. +    if (lookup->attr == ATTR_USER_NAME) {
  233. +       char principal_name[VAL_LEN];
  234. +       uid_t cy_uid = 0;
  235. +       gid_t cy_gid = 0;
  236. +
  237. +       status = ERROR_NOT_FOUND;
  238. +
  239. +        if (!cygwin_getent_passwd(lookup->value, NULL, &cy_uid, &cy_gid)) {
  240. +            eprintf("# ATTR_USER_NAME: cygwin_getent_passwd: returned %s, uid=%d, gid=%d\n", lookup->value, (int)cy_uid, (int)cy_gid);
  241. +           (void)snprintf(principal_name, sizeof(principal_name), "%s@%s", lookup->value, "GLOBAL.LOC");
  242. +            StringCchCopyA(user->username, VAL_LEN, lookup->value);
  243. +            StringCchCopyA(user->principal, VAL_LEN, principal_name);
  244. +            user->uid = cy_uid;
  245. +            user->gid = cy_gid;
  246. +           status = 0;
  247. +       }
  248. +    }
  249. +    else if (lookup->attr == ATTR_PRINCIPAL) {
  250. +       char search_name[VAL_LEN];
  251. +       char principal_name[VAL_LEN];
  252. +       char *s;
  253. +       uid_t cy_uid = 0;
  254. +       gid_t cy_gid = 0;
  255. +
  256. +       status = ERROR_NOT_FOUND;
  257. +
  258. +       /*
  259. +        * strip '@' from principal name and use that for getent
  260. +        * fixme: This does not work with multiple domains
  261. +        */
  262. +       (void)strcpy_s(search_name, sizeof(search_name), lookup->value);
  263. +       if (s = strchr(search_name, '@'))
  264. +           *s = '\0';
  265. +
  266. +        if (!cygwin_getent_passwd(search_name, NULL, &cy_uid, &cy_gid)) {
  267. +            eprintf("# ATTR_PRINCIPAL: cygwin_getent_passwd: returned %s, uid=%d, gid=%d\n", lookup->value, (int)cy_uid, (int)cy_gid);
  268. +           (void)snprintf(principal_name, sizeof(principal_name), "%s@%s", lookup->value, "GLOBAL.LOC");
  269. +
  270. +           if (!_stricmp(principal_name, lookup->value)) {
  271. +                StringCchCopyA(user->username, VAL_LEN, search_name);
  272. +                StringCchCopyA(user->principal, VAL_LEN, principal_name);
  273. +                user->uid = cy_uid;
  274. +                user->gid = cy_gid;
  275. +               status = 0;
  276. +           }
  277. +       }
  278. +    }
  279. +    else if (lookup->attr == ATTR_UID) {
  280. +        uid_t search_uid = (uid_t)(lookup->value);
  281. +       char search_name[VAL_LEN];
  282. +       char res_username[VAL_LEN];
  283. +       char principal_name[VAL_LEN];
  284. +       uid_t cy_uid = 0;
  285. +       gid_t cy_gid = 0;
  286. +
  287. +       status = ERROR_NOT_FOUND;
  288. +
  289. +       (void)snprintf(search_name, sizeof(search_name), "%lu", (unsigned long)search_uid);
  290. +
  291. +        if (!cygwin_getent_passwd(search_name, res_username, &cy_uid, &cy_gid)) {
  292. +            eprintf("# ATTR_UID: cygwin_getent_passwd: returned %s, uid=%d, gid=%d\n", res_username, (int)cy_uid, (int)cy_gid);
  293. +           (void)snprintf(principal_name, sizeof(principal_name), "%s@%s", res_username, "GLOBAL.LOC");
  294. +
  295. +            StringCchCopyA(user->username, VAL_LEN, res_username);
  296. +            StringCchCopyA(user->principal, VAL_LEN, principal_name);
  297. +            user->uid = cy_uid;
  298. +            user->gid = cy_gid;
  299. +            status = 0;
  300. +       }
  301. +    }
  302. +    else
  303. +    {
  304. +        status = ERROR_NOT_FOUND;
  305. +    }
  306. +    
  307. +    if (status == 0) {
  308. +        user->last_updated = time(NULL);
  309. +       eprintf("## idmap_lookup_user: found username='%s', principal='%s', uid=%lu, gid=%lu\n",
  310. +               user->username,
  311. +               user->principal,
  312. +               (unsigned long)user->uid,
  313. +               (unsigned long)user->gid);
  314. +    }
  315. +#endif
  316.      if (context->config.cache_ttl) {
  317.          /* insert the entry into the cache */
  318.          cache_insert(&context->users, lookup, &user->entry);
  319. @@ -732,10 +967,10 @@ static int idmap_lookup_group(
  320.      if (status == NO_ERROR) {
  321.          /* don't return expired entries; query new attributes
  322.           * and overwrite the entry with cache_insert() */
  323. -        if (time(NULL) - group->last_updated < context->config.cache_ttl)
  324. +        if ((time(NULL) - group->last_updated) < context->config.cache_ttl)
  325.              goto out;
  326.      }
  327. -
  328. +#if 0
  329.      /* send the query to the ldap server */
  330.      status = idmap_query_attrs(context, lookup,
  331.          attributes, 0, values, NUM_ATTRIBUTES);
  332. @@ -758,7 +993,48 @@ static int idmap_lookup_group(
  333.          goto out_free_values;
  334.      }
  335.      group->last_updated = time(NULL);
  336. +#else
  337. +    if (lookup->attr == ATTR_GROUP_NAME) {
  338. +       gid_t cy_gid = 0;
  339. +
  340. +       status = ERROR_NOT_FOUND;
  341. +
  342. +        if (!cygwin_getent_group(lookup->value, NULL, &cy_gid)) {
  343. +            eprintf("# ATTR_GROUP_NAME: cygwin_getent_group: returned %s, gid=%d\n", lookup->value, (int)cy_gid);
  344. +            StringCchCopyA(group->name, VAL_LEN, lookup->value);
  345. +            group->gid = cy_gid;
  346. +           status = 0;
  347. +       }
  348. +    }
  349. +    else if (lookup->attr == ATTR_GID) {
  350. +        gid_t search_gid = (gid_t)(lookup->value);
  351. +        char search_name[VAL_LEN];
  352. +       char res_groupname[VAL_LEN];
  353. +       gid_t cy_gid = 0;
  354. +
  355. +       status = ERROR_NOT_FOUND;
  356. +
  357. +       (void)snprintf(search_name, sizeof(search_name), "%lu", (unsigned long)search_gid);
  358. +
  359. +        if (!cygwin_getent_group(search_name, res_groupname, &cy_gid)) {
  360. +            eprintf("# ATTR_GID: cygwin_getent_group: returned %s, gid=%d\n", res_groupname, (int)cy_gid);
  361. +            StringCchCopyA(group->name, VAL_LEN, res_groupname);
  362. +            group->gid = cy_gid;
  363. +            status = 0;
  364. +       }
  365. +    }
  366. +    else
  367. +    {
  368. +        status = ERROR_NOT_FOUND;
  369. +    }
  370.  
  371. +    if (status == 0) {
  372. +        group->last_updated = time(NULL);
  373. +       eprintf("## idmap_lookup_group: found name='%s', gid=%lu\n",
  374. +               group->name,
  375. +               (unsigned long)group->gid);
  376. +    }
  377. +#endif
  378.      if (context->config.cache_ttl) {
  379.          /* insert the entry into the cache */
  380.          cache_insert(&context->groups, lookup, &group->entry);
  381. @@ -795,6 +1071,7 @@ int nfs41_idmap_create(
  382.          goto out_err_free;
  383.      }
  384.  
  385. +#if 0
  386.      /* initialize ldap and configure options */
  387.      context->ldap = ldap_init(context->config.hostname, context->config.port);
  388.      if (context->ldap == NULL) {
  389. @@ -824,6 +1101,10 @@ int nfs41_idmap_create(
  390.              goto out_err_free;
  391.          }
  392.      }
  393. +#else
  394. +    eprintf("nfs41_idmap_create: Force context->config.timeout = 6000;\n");
  395. +    context->config.timeout = 6000;
  396. +#endif
  397.  
  398.      *context_out = context;
  399.  out:
  400. diff --git a/daemon/nfs41_daemon.c b/daemon/nfs41_daemon.c
  401. index bb485cb..25ca6eb 100644
  402. --- a/daemon/nfs41_daemon.c
  403. +++ b/daemon/nfs41_daemon.c
  404. @@ -389,6 +389,11 @@ VOID ServiceStart(DWORD argc, LPTSTR *argv)
  405.          exit(1);
  406.      }
  407.  
  408. +#if 1
  409. +    /* force enable for cygwin getent passwd/group testing */
  410. +    cmd_args.ldap_enable = TRUE;
  411. +#endif
  412. +
  413.      nfs41_server_list_init();
  414.  
  415.      if (cmd_args.ldap_enable) {

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