pastebin - collaborative debugging tool
rovema.kpaste.net RSS


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