pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


Switch to new idmapper prototype
Posted by Anonymous on Thu 2nd Apr 2026 18:22
raw | new post

  1. diff --git a/cygwin_idmapper.ksh b/cygwin_idmapper.ksh
  2. index 2f16b55..f98f336 100644
  3. --- a/cygwin_idmapper.ksh
  4. +++ b/cygwin_idmapper.ksh
  5. @@ -19,9 +19,6 @@ if (( $# > 1 )) ; then
  6.         # strip '"' characters (for Cygwin 3.3 compatibility)
  7.         # note that "${2-//..." does NOT work!
  8.         c.name="${2//\"/}"
  9. -
  10. -       # strip domain part, e.g. "name@domain" --> "name"
  11. -       c.name="${c.name%@*}"
  12.  fi
  13.  
  14.  #
  15. @@ -96,7 +93,10 @@ if [[ ! -v COMPUTERNAME ]] ; then
  16.         export COMPUTERNAME="$(uname -n | tr '[:lower:]' '[:upper:]')"
  17.  fi
  18.  
  19. -typeset -r localdomain='global.loc'
  20. +compound idmap_config=(
  21. +       typeset -r localdomain='GLOBAL.LOC'     # Default domain for Windows
  22. +       typeset -r nfsdomain='global.loc'       # Default domain for NFS server
  23. +)
  24.  
  25.  compound -A localusers=(
  26.         #
  27. @@ -109,37 +109,37 @@ compound -A localusers=(
  28.         ["roland_mainz"]=(
  29.                 localaccountname="roland_mainz@${COMPUTERNAME}"
  30.                 localuid=197608
  31. -               nfsowner="roland_mainz@${localdomain}"
  32. +               nfsowner="roland_mainz@${idmap_config.nfsdomain}"
  33.                 nfsuid=197608
  34.         )
  35.         ["siegfried_wulsch"]=(
  36.                 localaccountname="siegfried_wulsch@${COMPUTERNAME}"
  37.                 localuid=197609
  38. -               nfsowner="siegfried_wulsch@${localdomain}"
  39. +               nfsowner="siegfried_wulsch@${idmap_config.nfsdomain}"
  40.                 nfsuid=197609
  41.         )
  42.         ["rmainz"]=(
  43.                 localaccountname="rmainz@${COMPUTERNAME}"
  44.                 localuid=1616
  45. -               nfsowner="rmainz@${localdomain}"
  46. +               nfsowner="rmainz@${idmap_config.nfsdomain}"
  47.                 nfsuid=1616
  48.         )
  49.         ["swulsch"]=(
  50.                 localaccountname="swulsch@${COMPUTERNAME}"
  51.                 localuid=1818
  52. -               nfsowner="swulsch@${localdomain}"
  53. +               nfsowner="swulsch@${idmap_config.nfsdomain}"
  54.                 nfsuid=1818
  55.         )
  56.         ["root"]=(
  57.                 localaccountname="root@${COMPUTERNAME}"
  58.                 localuid=0
  59. -               nfsowner="root@${localdomain}"
  60. +               nfsowner="root@${idmap_config.nfsdomain}"
  61.                 nfsuid=0
  62.         )
  63.         ["nobody"]=(
  64.                 localaccountname="nobody@${COMPUTERNAME}"
  65.                 localuid=65534
  66. -               nfsowner="nobody@${localdomain}"
  67. +               nfsowner="nobody@${idmap_config.nfsdomain}"
  68.                 nfsuid=65534
  69.         )
  70.  )
  71. @@ -150,19 +150,19 @@ if [[ -v c.localised_usernames['Administrator'] ]] ; then
  72.                         localaccountname="${c.localised_usernames['Administrator']}@${COMPUTERNAME}"
  73.                         localuid=197108
  74.                         nfsuid=197108
  75. -                       nfsowner="Administrator@${localdomain}"
  76. +                       nfsowner="Administrator@${idmap_config.nfsdomain}"
  77.                 )
  78.                 ['Administrator']=(
  79.                         localaccountname="${c.localised_usernames['Administrator']}@${COMPUTERNAME}"
  80.                         localuid=197108
  81. -                       nfsowner="Administrator@${localdomain}"
  82. +                       nfsowner="Administrator@${idmap_config.nfsdomain}"
  83.                         nfsuid=197108
  84.                 )
  85.                 # French user "Administrator"
  86.                 ['Administrateur']=(
  87.                         localaccountname="${c.localised_usernames['Administrator']}@${COMPUTERNAME}"
  88.                         localuid=197108
  89. -                       nfsowner="Administrator@${localdomain}"
  90. +                       nfsowner="Administrator@${idmap_config.nfsdomain}"
  91.                         nfsuid=197108
  92.                 )
  93.         )
  94. @@ -172,13 +172,13 @@ if [[ -v c.localised_usernames['SYSTEM'] ]] ; then
  95.                 ["${c.localised_usernames['SYSTEM']}"]=(
  96.                         localaccountname="${c.localised_usernames['SYSTEM']}@${COMPUTERNAME}"
  97.                         localuid=18
  98. -                       nfsowner="SYSTEM@${localdomain}"
  99. +                       nfsowner="SYSTEM@${idmap_config.nfsdomain}"
  100.                         nfsuid=18
  101.                 )
  102.                 ["SYSTEM"]=(
  103.                         localaccountname="${c.localised_usernames['SYSTEM']}@${COMPUTERNAME}"
  104.                         localuid=18
  105. -                       nfsowner="SYSTEM@${localdomain}"
  106. +                       nfsowner="SYSTEM@${idmap_config.nfsdomain}"
  107.                         nfsuid=18
  108.                 )
  109.                 # French user "SYSTEM"
  110. @@ -187,7 +187,7 @@ if [[ -v c.localised_usernames['SYSTEM'] ]] ; then
  111.                 [$'Syst\xc3\xa8me']=(
  112.                         localaccountname="${c.localised_usernames['SYSTEM']}@${COMPUTERNAME}"
  113.                         localuid=18
  114. -                       nfsowner="SYSTEM@${localdomain}"
  115. +                       nfsowner="SYSTEM@${idmap_config.nfsdomain}"
  116.                         nfsuid=18
  117.                 )
  118.         )
  119. @@ -205,25 +205,25 @@ compound -A localgroups=(
  120.         ["rmainz"]=(
  121.                 localgroupname="rmainz@${COMPUTERNAME}"
  122.                 localgid=1616
  123. -               nfsownergroup="rmainz@${localdomain}"
  124. +               nfsownergroup="rmainz@${idmap_config.nfsdomain}"
  125.                 nfsgid=1616
  126.         )
  127.         ["swulsch"]=(
  128.                 localgroupname="swulsch@${COMPUTERNAME}"
  129.                 localgid=1818
  130. -               nfsownergroup="swulsch@${localdomain}"
  131. +               nfsownergroup="swulsch@${idmap_config.nfsdomain}"
  132.                 nfsgid=1818
  133.         )
  134.         ["root"]=(
  135.                 localgroupname="root@${COMPUTERNAME}"
  136.                 localgid=0
  137. -               nfsownergroup="root@${localdomain}"
  138. +               nfsownergroup="root@${idmap_config.nfsdomain}"
  139.                 nfsgid=0
  140.         )
  141.         ["nogroup"]=(
  142.                 localgroupname="nogroup@${COMPUTERNAME}"
  143.                 localgid=65534
  144. -               nfsownergroup="nogroup@${localdomain}"
  145. +               nfsownergroup="nogroup@${idmap_config.nfsdomain}"
  146.                 nfsgid=65534
  147.         )
  148.         #
  149. @@ -232,7 +232,7 @@ compound -A localgroups=(
  150.         ["sys"]=(
  151.                 localgroupname="sys@${COMPUTERNAME}"
  152.                 localgid=3
  153. -               nfsownergroup="sys@${localdomain}"
  154. +               nfsownergroup="sys@${idmap_config.nfsdomain}"
  155.                 nfsgid=3
  156.         )
  157.         #
  158. @@ -242,7 +242,7 @@ compound -A localgroups=(
  159.         ["nobody"]=(
  160.                 localgroupname="nobody@${COMPUTERNAME}"
  161.                 localgid=65534
  162. -               nfsownergroup="nobody@${localdomain}"
  163. +               nfsownergroup="nobody@${idmap_config.nfsdomain}"
  164.                 nfsgid=65534
  165.         )
  166.  )
  167. @@ -250,11 +250,13 @@ compound -A localgroups=(
  168.  function getent_local_domain_passwd
  169.  {
  170.         integer res
  171. -       typeset passwdname="$1"
  172. +       typeset arg="$1"
  173. +
  174. +       typeset username="${arg%%@*}"
  175. +       typeset domainname="${arg#*@}"
  176.  
  177.         #
  178. -       # first try local accounts and if getent does
  179. -       # not find anything do a (normal) domain lookup
  180. +       # lookup local accounts
  181.         #
  182.         # Notes:
  183.         # - Cygwin getent uses "+" prefix to search for local
  184. @@ -262,25 +264,22 @@ function getent_local_domain_passwd
  185.         # - Cygwin getent uses "U-" prefix to pass the input string to
  186.         # |LookupAccountNameA()| directly
  187.         #
  188. -       getent passwd "U-${passwdname}"
  189. +       getent passwd "U-${domainname}\\${username}"
  190.         (( res=$? ))
  191.  
  192. -       if (( res == 2 )) ; then
  193. -               getent passwd "${passwdname}"
  194. -               (( res=$? ))
  195. -       fi
  196. -
  197.         return $res
  198.  }
  199.  
  200.  function getent_local_domain_group
  201.  {
  202.         integer res
  203. -       typeset groupname="$1"
  204. +       typeset arg="$1"
  205. +
  206. +       typeset groupname="${arg%%@*}"
  207. +       typeset domainname="${arg#*@}"
  208.  
  209.         #
  210. -       # first try local accounts and if getent does
  211. -       # not find anything do a (normal) domain lookup
  212. +       # lookup local accounts
  213.         #
  214.         # Notes:
  215.         # - Cygwin getent uses "+" prefix to search for local
  216. @@ -288,12 +287,45 @@ function getent_local_domain_group
  217.         # - Cygwin getent uses "U-" prefix to pass the input string to
  218.         # |LookupAccountNameA()| directly
  219.         #
  220. -       getent group "U-${groupname}"
  221. +       getent group "U-${domainname}\\${groupname}"
  222.         (( res=$? ))
  223.  
  224. -       if (( res == 2 )) ; then
  225. +       return $res
  226. +}
  227. +
  228. +function getent_nfs_domain_passwd
  229. +{
  230. +       integer res
  231. +       typeset arg="$1"
  232. +
  233. +       typeset username="${arg%%@*}"
  234. +       typeset domainname="${arg#*@}"
  235. +
  236. +       if [[ "${domainname}" == "${idmap_config.nfsdomain}" ]] ; then
  237. +               getent passwd "${username}"
  238. +               (( res=$? ))
  239. +       else
  240. +               getent passwd "${domainname}+${username}"
  241. +               (( res=$? ))
  242. +       fi
  243. +
  244. +       return $res
  245. +}
  246. +
  247. +function getent_nfs_domain_group
  248. +{
  249. +       integer res
  250. +       typeset arg="$1"
  251. +
  252. +       typeset groupname="${arg%%@*}"
  253. +       typeset domainname="${arg#*@}"
  254. +
  255. +       if [[ "${domainname}" == "${idmap_config.nfsdomain}" ]] ; then
  256.                 getent group "${groupname}"
  257.                 (( res=$? ))
  258. +       else
  259. +               getent group "${domainname}+${groupname}"
  260. +               (( res=$? ))
  261.         fi
  262.  
  263.         return $res
  264. @@ -304,27 +336,27 @@ if [[ -v c.localised_groupnames['None'] ]] ; then
  265.                 ["${c.localised_groupnames['None']}"]=(
  266.                         localgroupname="${c.localised_groupnames['None']}@${COMPUTERNAME}"
  267.                         localgid=197121
  268. -                       nfsownergroup="None@${localdomain}"
  269. +                       nfsownergroup="None@${idmap_config.nfsdomain}"
  270.                         nfsgid=197121
  271.                 )
  272.                 ["None"]=(
  273.                         localgroupname="${c.localised_groupnames['None']}@${COMPUTERNAME}"
  274.                         localgid=197121
  275. -                       nfsownergroup="None@${localdomain}"
  276. +                       nfsownergroup="None@${idmap_config.nfsdomain}"
  277.                         nfsgid=197121
  278.                 )
  279.                 # French Windows localised group name for "None"
  280.                 ['Aucun']=(
  281.                         localgroupname="${c.localised_groupnames['None']}@${COMPUTERNAME}"
  282.                         localgid=197121
  283. -                       nfsownergroup="None@${localdomain}"
  284. +                       nfsownergroup="None@${idmap_config.nfsdomain}"
  285.                         nfsgid=197121
  286.                 )
  287.                 # German Windows localised group name for "None"
  288.                 ["Kein"]=(
  289.                         localgroupname="${c.localised_groupnames['None']}@${COMPUTERNAME}"
  290.                         localgid=197121
  291. -                       nfsownergroup="None@${localdomain}"
  292. +                       nfsownergroup="None@${idmap_config.nfsdomain}"
  293.                         nfsgid=197121
  294.                 )
  295.         )
  296. @@ -335,13 +367,13 @@ if [[ -v c.localised_groupnames['Administrators'] ]] ; then
  297.                 ["${c.localised_groupnames['Administrators']}"]=(
  298.                         localgroupname="${c.localised_groupnames['Administrators']}@${COMPUTERNAME}"
  299.                         localgid=544
  300. -                       nfsownergroup="Administrators@${localdomain}"
  301. +                       nfsownergroup="Administrators@${idmap_config.nfsdomain}"
  302.                         nfsgid=544
  303.                 )
  304.                 ['Administrators']=(
  305.                         localgroupname="${c.localised_groupnames['Administrators']}@${COMPUTERNAME}"
  306.                         localgid=544
  307. -                       nfsownergroup="Administrators@${localdomain}"
  308. +                       nfsownergroup="Administrators@${idmap_config.nfsdomain}"
  309.                         nfsgid=544
  310.                 )
  311.                 # French Windows localised group name for "Administrators"
  312. @@ -349,14 +381,14 @@ if [[ -v c.localised_groupnames['Administrators'] ]] ; then
  313.                 ['Administrateurs']=(
  314.                         localgroupname="${c.localised_groupnames['Administrators']}@${COMPUTERNAME}"
  315.                         localgid=544
  316. -                       nfsownergroup="Administrators@${localdomain}"
  317. +                       nfsownergroup="Administrators@${idmap_config.nfsdomain}"
  318.                         nfsgid=544
  319.                 )
  320.                 # German Windows localised group name for "Administrators"
  321.                 ['Administratoren']=(
  322.                         localgroupname="${c.localised_groupnames['Administrators']}@${COMPUTERNAME}"
  323.                         localgid=544
  324. -                       nfsownergroup="Administrators@${localdomain}"
  325. +                       nfsownergroup="Administrators@${idmap_config.nfsdomain}"
  326.                         nfsgid=544
  327.                 )
  328.         )
  329. @@ -367,13 +399,13 @@ if [[ -v c.localised_groupnames['Users'] ]] ; then
  330.                 ["${c.localised_groupnames['Users']}"]=(
  331.                         localgroupname="${c.localised_groupnames['Users']}@${COMPUTERNAME}"
  332.                         localgid=545
  333. -                       nfsownergroup="Users@${localdomain}"
  334. +                       nfsownergroup="Users@${idmap_config.nfsdomain}"
  335.                         nfsgid=545
  336.                 )
  337.                 ['Users']=(
  338.                         localgroupname="${c.localised_groupnames['Users']}@${COMPUTERNAME}"
  339.                         localgid=545
  340. -                       nfsownergroup="Users@${localdomain}"
  341. +                       nfsownergroup="Users@${idmap_config.nfsdomain}"
  342.                         nfsgid=545
  343.                 )
  344.                 # French Windows localised group name for "Users"
  345. @@ -381,36 +413,36 @@ if [[ -v c.localised_groupnames['Users'] ]] ; then
  346.                 ['Utilisateurs']=(
  347.                         localgroupname="${c.localised_groupnames['Users']}@${COMPUTERNAME}"
  348.                         localgid=545
  349. -                       nfsownergroup="Users@${localdomain}"
  350. +                       nfsownergroup="Users@${idmap_config.nfsdomain}"
  351.                         nfsgid=545
  352.                 )
  353.                 # German Windows localised group name for "Users"
  354.                 ['Benutzer']=(
  355.                         localgroupname="${c.localised_groupnames['Users']}@${COMPUTERNAME}"
  356.                         localgid=545
  357. -                       nfsownergroup="Users@${localdomain}"
  358. +                       nfsownergroup="Users@${idmap_config.nfsdomain}"
  359.                         nfsgid=545
  360.                 )
  361.         )
  362.  fi
  363.  
  364. -function ntaccount2principal
  365. +function parse_ntaccount
  366.  {
  367. -       typeset raw_string="$1"
  368. +       nameref c=$1
  369. +       typeset raw_string="$2"
  370.  
  371.         typeset stripped="${raw_string#*U-}"
  372.  
  373.         stripped="${stripped%%,*}"
  374.  
  375. -       typeset domain="${stripped%\\*}"
  376. -       typeset user="${stripped#*\\}"
  377. +       c.domain="${stripped%\\*}"
  378. +       c.user="${stripped#*\\}"
  379.  
  380. -       printf '%s\n' "${user}@${domain}"
  381.         return 0
  382.  }
  383.  
  384.  case "${c.mode}" in
  385. -       'nfsserver_owner2localaccount')
  386. +       'localname2localaccount')
  387.                 #
  388.                 # Try static info
  389.                 #
  390. @@ -422,11 +454,11 @@ case "${c.mode}" in
  391.                                 fi
  392.                         done
  393.                         # getent passwd accepts numeric uids too, so continue below
  394. -               fi
  395. -
  396. -               if [[ -v localusers["${c.name}"] ]] ; then
  397. -                       print -v localusers["${c.name}"]
  398. -                       exit 0
  399. +               else
  400. +                       if [[ -v localusers["${c.name}"] ]] ; then
  401. +                               print -v localusers["${c.name}"]
  402. +                               exit 0
  403. +                       fi
  404.                 fi
  405.  
  406.                 #
  407. @@ -439,8 +471,10 @@ case "${c.mode}" in
  408.  
  409.                 if [[ "${s-}" != '' ]] ; then
  410.                         if [[ "${gec.localuid-}" == ~(Elr)[[:digit:]]+ && "${gec.localgid-}" == ~(Elr)[[:digit:]]+ ]] ; then
  411. -                               gec.localaccountname="${ ntaccount2principal "$s" ; }"
  412. -                               gec.nfsowner="${ ntaccount2principal "$s" ; }"
  413. +                               compound nt_parsed
  414. +                               parse_ntaccount nt_parsed "$s"
  415. +                               gec.localaccountname="${nt_parsed.user}@${nt_parsed.domain}"
  416. +                               gec.nfsowner="${nt_parsed.user}@${idmap_config.nfsdomain}"
  417.                                 (( gec.nfsuid=gec.localuid ))
  418.                                 print -v gec
  419.                                 exit 0
  420. @@ -452,7 +486,7 @@ case "${c.mode}" in
  421.                 print -u2 -f "cygwin_idmapper.ksh: Account %q not found.\n" "${c.name}"
  422.                 exit 1
  423.                 ;;
  424. -       'nfsserver_owner_group2localgroup')
  425. +       'localgroup2localgroup')
  426.                 #
  427.                 # Try static info
  428.                 #
  429. @@ -464,11 +498,116 @@ case "${c.mode}" in
  430.                                 fi
  431.                         done
  432.                         # getent group accepts numeric gids too, so continue below
  433. +               else
  434. +                       if [[ -v localgroups["${c.name}"] ]] ; then
  435. +                               print -v localgroups["${c.name}"]
  436. +                               exit 0
  437. +                       fi
  438. +               fi
  439. +
  440. +               #
  441. +               # try getent group
  442. +               #
  443. +               compound gec # getent compound var
  444. +               typeset dummy1 dummy2 s
  445. +               getent_local_domain_group "${c.name}" | \
  446. +                       IFS=':' read s dummy1 gec.localgid dummy2
  447. +
  448. +               if [[ "${s-}" != '' ]] ; then
  449. +                       if [[ "${gec.localgid-}" == ~(Elr)[[:digit:]]+ ]] ; then
  450. +                               if [[ "$s" == *"+"* ]]; then
  451. +                                       domain="${s%%+*}"
  452. +                                       user="${input#*+}"
  453. +                               else
  454. +                                       # No '+' found, fallback to the local machine name
  455. +                                       domain="${COMPUTERNAME}"
  456. +                                       user="$s"
  457. +                               fi
  458. +
  459. +                               gec.localgroupname="${user}@${domain}"
  460. +                               gec.nfsownergroup="${user}@${idmap_config.nfsdomain}"
  461. +                               (( gec.nfsgid=gec.localgid ))
  462. +                               print -v gec
  463. +                               exit 0
  464. +                       else
  465. +                               print -u2 -f "cygwin_idmapper.ksh: getent group %q returned garbage.\n" "${c.name}"
  466. +                       fi
  467.                 fi
  468.  
  469. -               if [[ -v localgroups["${c.name}"] ]] ; then
  470. -                       print -v localgroups["${c.name}"]
  471. -                       exit 0
  472. +               print -u2 -f "cygwin_idmapper.ksh: Group %q not found.\n" "${c.name}"
  473. +               exit 1
  474. +               ;;
  475. +       'nfsserver_owner2localaccount')
  476. +               #
  477. +               # Try static info
  478. +               #
  479. +
  480. +               # Numeric ? Try looking up static UID
  481. +               if [[ "${c.name}" == ~(Elr)[[:digit:]]+ ]] ; then
  482. +                       # Numeric ? Try looking up static UID
  483. +                       for s in "${!localusers[@]}" ; do
  484. +                               if (( localusers[$s].nfsuid == c.name )) ; then
  485. +                                       print -v localusers[$s]
  486. +                                       exit 0
  487. +                               fi
  488. +                       done
  489. +                       # getent passwd accepts numeric uids too, so continue below
  490. +               else
  491. +                       # Search for user name
  492. +                       for s in "${!localusers[@]}" ; do
  493. +                               if [[ "${localusers[$s].nfsowner}" == "${c.name}" ]] ; then
  494. +                                       print -v localusers[$s]
  495. +                                       exit 0
  496. +                               fi
  497. +                       done
  498. +               fi
  499. +
  500. +               #
  501. +               # try getent passwd
  502. +               #
  503. +               compound gec # getent compound var
  504. +               typeset dummy1 dummy2 s
  505. +               getent_nfs_domain_passwd "${c.name}" | \
  506. +                       IFS=':' read -r dummy1 dummy2 gec.localuid gec.localgid s dummy3
  507. +
  508. +               if [[ "${s-}" != '' ]] ; then
  509. +                       if [[ "${gec.localuid-}" == ~(Elr)[[:digit:]]+ && "${gec.localgid-}" == ~(Elr)[[:digit:]]+ ]] ; then
  510. +                               compound nt_parsed
  511. +                               parse_ntaccount nt_parsed "$s"
  512. +                               gec.localaccountname="${nt_parsed.user}@${nt_parsed.domain}"
  513. +                               gec.nfsowner="${nt_parsed.user}@${idmap_config.nfsdomain}"
  514. +                               (( gec.nfsuid=gec.localuid ))
  515. +                               print -v gec
  516. +                               exit 0
  517. +                       else
  518. +                               print -u2 -f "cygwin_idmapper.ksh: getent passwd %q returned garbage.\n" "${c.name}"
  519. +                       fi
  520. +               fi
  521. +
  522. +               print -u2 -f "cygwin_idmapper.ksh: Account %q not found.\n" "${c.name}"
  523. +               exit 1
  524. +               ;;
  525. +       'nfsserver_owner_group2localgroup')
  526. +               #
  527. +               # Try static info
  528. +               #
  529. +               if [[ "${c.name}" == ~(Elr)[[:digit:]]+ ]] ; then
  530. +                       # Numeric ? Try looking up static UID
  531. +                       for s in "${!localgroups[@]}" ; do
  532. +                               if (( localgroups[$s].localgid == c.name )) ; then
  533. +                                       print -v localgroups[$s]
  534. +                                       exit 0
  535. +                               fi
  536. +                       done
  537. +                       # getent group accepts numeric gids too, so continue below
  538. +               else
  539. +                       # Search for user name
  540. +                       for s in "${!localgroups[@]}" ; do
  541. +                               if [[ "${localgroups[$s].nfsownergroup}" == "${c.name}" ]] ; then
  542. +                                       print -v localgroups[$s]
  543. +                                       exit 0
  544. +                               fi
  545. +                       done
  546.                 fi
  547.  
  548.                 #
  549. @@ -476,7 +615,7 @@ case "${c.mode}" in
  550.                 #
  551.                 compound gec # getent compound var
  552.                 typeset dummy1 dummy2 s
  553. -               getent_local_domain_group "${c.name}" | \
  554. +               getent_nfs_domain_group "${c.name}" | \
  555.                         IFS=':' read s dummy1 gec.localgid dummy2
  556.  
  557.                 if [[ "${s-}" != '' ]] ; then
  558. @@ -491,7 +630,7 @@ case "${c.mode}" in
  559.                                 fi
  560.  
  561.                                 gec.localgroupname="${user}@${domain}"
  562. -                               gec.nfsownergroup="${user}@${domain}"
  563. +                               gec.nfsownergroup="${user}@${idmap_config.nfsdomain}"
  564.                                 (( gec.nfsgid=gec.localgid ))
  565.                                 print -v gec
  566.                                 exit 0
  567. diff --git a/daemon/accesstoken.c b/daemon/accesstoken.c
  568. index 21d2ca4..041a73d 100644
  569. --- a/daemon/accesstoken.c
  570. +++ b/daemon/accesstoken.c
  571. @@ -157,15 +157,14 @@ bool fill_auth_unix_aup_gids(HANDLE tok,
  572.          return false;
  573.      }
  574.  
  575. -    gid_t map_gid;
  576. +    idmapcache_entry *ie;
  577.      *num_aup_gids = 0;
  578. -
  579.      for (i=0 ; i < num_groups ; i++) {
  580. -        if (nfs41_idmap_group_to_gid(
  581. -            nfs41_dg.idmapper,
  582. -            group_names[i],
  583. -            &map_gid) == 0) {
  584. -            aup_gids[(*num_aup_gids)++] = map_gid;
  585. +        ie = nfs41_idmap_group_lookup_by_win32name(nfs41_dg.idmapper,
  586. +            group_names[i]);
  587. +        if (ie != NULL) {
  588. +            aup_gids[(*num_aup_gids)++] = ie->nfsid;
  589. +            idmapcache_entry_refcount_dec(ie);
  590.          }
  591.          else {
  592.              eprintf("fill_auth_unix_aup_gids: "
  593. diff --git a/daemon/aclutil.c b/daemon/aclutil.c
  594. index 98402ea..bb8ce61 100644
  595. --- a/daemon/aclutil.c
  596. +++ b/daemon/aclutil.c
  597. @@ -727,10 +727,12 @@ int map_sid2nfs4ace_who(PSID sid, PSID owner_sid, PSID group_sid,
  598.      SID_NAME_USE sid_type = 0;
  599.      /* |who_buf| needs space for user+domain */
  600.      char who_buf[UTF8_PRINCIPALLEN+1];
  601. -    char domain_buf[UTF8_UNLEN+1];
  602. -    DWORD who_size = sizeof(who_buf), domain_size = sizeof(domain_buf);
  603. +    DWORD who_size = sizeof(who_buf);
  604.      LPSTR sidstr = NULL;
  605.  
  606. +    /* fixme: This should be a function argument */
  607. +    extern nfs41_daemon_globals nfs41_dg;
  608. +
  609.      DPRINTF(ACLLVL2, ("--> map_sid2nfs4ace_who("
  610.          "sid=0x%p,owner_sid=0x%p, group_sid=0x%p)\n",
  611.          sid, owner_sid, group_sid));
  612. @@ -789,17 +791,76 @@ int map_sid2nfs4ace_who(PSID sid, PSID owner_sid, PSID group_sid,
  613.      if (status) {
  614.          DPRINTF(ACLLVL2, ("map_sid2nfs4ace_who: "
  615.              "LookupAccountSid(sidtostr(sid)='%s', who_buf='%s', "
  616. -            "who_size=%d, domain='%s', domain_size=%d) "
  617. +            "who_size=%d) "
  618.              "returned success, status=%d, GetLastError=%d\n",
  619.              sidstr, who_buf, who_size,
  620. -            domain_buf, domain_size, status, lasterr));
  621. +            status, lasterr));
  622. +        idmapcache_entry *ie;
  623. +
  624. +        switch (sid_type) {
  625. +            case SidTypeUser:
  626. +                ie = nfs41_idmap_user_lookup_by_win32name(nfs41_dg.idmapper, who_buf);
  627. +                if (ie != NULL) {
  628. +                    (void)strcpy(who_out, ie->nfsname.buf);
  629. +                    who_size = (DWORD)strlen(who_out); /* FIXME: |ie->nfsname.len| ? */
  630. +                    status = ERROR_SUCCESS;
  631. +
  632. +                    DPRINTF(ACLLVL1, ("map_sid2nfs4ace_who: "
  633. +                        "win32name='%s' mapped to user '%s'\n",
  634. +                        who_buf, who_out));
  635. +                    idmapcache_entry_refcount_dec(ie);
  636. +                    goto out;
  637. +                }
  638. +                else {
  639. +                    DPRINTF(0,
  640. +                        ("map_sid2nfs4ace_who: "
  641. +                        "nfs41_idmap_user_lookup_by_win32name(who_buf='%s') failed\n",
  642. +                        who_buf));
  643. +                    status = ERROR_NOT_FOUND; /* FIXME: We need a better error code */
  644. +                    goto out;
  645. +                }
  646. +                break;
  647. +            case SidTypeGroup:
  648. +            case SidTypeAlias: /* Treat |SidTypeAlias| as (local) group */
  649. +                ie = nfs41_idmap_group_lookup_by_win32name(nfs41_dg.idmapper, who_buf);
  650. +                if (ie != NULL) {
  651. +                    (void)strcpy(who_out, ie->nfsname.buf);
  652. +                    who_size = (DWORD)strlen(who_out); /* FIXME: |ie->nfsname.len| ? */
  653. +                    status = ERROR_SUCCESS;
  654. +
  655. +                    DPRINTF(ACLLVL1, ("map_sid2nfs4ace_who: "
  656. +                        "win32name='%s' mapped to group '%s'\n",
  657. +                        who_buf, who_out));
  658. +                    idmapcache_entry_refcount_dec(ie);
  659. +                    goto out;
  660. +                }
  661. +                else {
  662. +                    DPRINTF(0,
  663. +                        ("map_sid2nfs4ace_who: "
  664. +                        "nfs41_idmap_group_lookup_by_win32name(who_buf='%s') failed\n",
  665. +                        who_buf));
  666. +                    status = ERROR_NOT_FOUND; /* FIXME: We need a better error code */
  667. +                    goto out;
  668. +                }
  669. +                break;
  670. +            default:
  671. +                DPRINTF(0,
  672. +                    ("map_sid2nfs4ace_who: "
  673. +                    "ERROR: Unsupported sid_type=%d for who_buf='%s'\n",
  674. +                    (int)sid_type, who_buf));
  675. +                status = ERROR_NOT_FOUND; /* FIXME: We need a better error code */
  676. +                goto out;
  677. +                break;
  678. +        }
  679. +
  680. +        /* NOTREACHED */
  681.      }
  682.      else {
  683.          DPRINTF(ACLLVL2, ("map_sid2nfs4ace_who: "
  684. -            "LookupAccountSid(sidtostr(sid)='%s', who_size=%d, "
  685. -            "domain_size=%d) returned failure, status=%d, "
  686. +            "LookupAccountSid(sidtostr(sid)='%s', who_size=%d "
  687. +            "returned failure, status=%d, "
  688.              "GetLastError=%d\n",
  689. -            sidstr, who_size, domain_size, status, lasterr));
  690. +            sidstr, who_size, status, lasterr));
  691.  
  692.          /*
  693.           * No SID to local account mapping. Can happen for some system
  694. @@ -821,16 +882,18 @@ int map_sid2nfs4ace_who(PSID sid, PSID owner_sid, PSID group_sid,
  695.                   * a user-/group-name mapped.
  696.                   */
  697.  #ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  698. -                /* fixme: This should be a function argument */
  699. -                extern nfs41_daemon_globals nfs41_dg;
  700.  
  701.                  uid_t unixuser_uid = ~0U;
  702.                  gid_t unixgroup_gid = ~0U;
  703.  
  704.                  if (unixuser_sid2uid(sid, &unixuser_uid)) {
  705. -                    if (!nfs41_idmap_uid_to_name(nfs41_dg.idmapper,
  706. -                        unixuser_uid, who_out, UTF8_PRINCIPALLEN)) {
  707. -                        who_size = (DWORD)strlen(who_out);
  708. +                    idmapcache_entry *ie;
  709. +
  710. +                    ie = nfs41_idmap_user_lookup_by_localid(nfs41_dg.idmapper,
  711. +                        unixuser_uid);
  712. +                    if (ie != NULL) {
  713. +                        (void)strcpy(who_out, ie->nfsname.buf);
  714. +                        who_size = (DWORD)strlen(who_out); /* FIXME: |ie->nfsname.len| ? */
  715.                          sid_type = SidTypeUser;
  716.                          status = ERROR_SUCCESS;
  717.  
  718. @@ -838,7 +901,8 @@ int map_sid2nfs4ace_who(PSID sid, PSID owner_sid, PSID group_sid,
  719.                              "Unix_User+%d SID "
  720.                              "mapped to user '%s'\n",
  721.                              unixuser_uid, who_out));
  722. -                        goto add_domain;
  723. +                        idmapcache_entry_refcount_dec(ie);
  724. +                        goto out;
  725.                      }
  726.  
  727.                      eprintf("map_sid2nfs4ace_who: "
  728. @@ -849,9 +913,13 @@ int map_sid2nfs4ace_who(PSID sid, PSID owner_sid, PSID group_sid,
  729.                  }
  730.  
  731.                  if (unixgroup_sid2gid(sid, &unixgroup_gid)) {
  732. -                    if (!nfs41_idmap_gid_to_group(nfs41_dg.idmapper,
  733. -                        unixgroup_gid, who_out, UTF8_PRINCIPALLEN)) {
  734. -                        who_size = (DWORD)strlen(who_out);
  735. +                    idmapcache_entry *ie;
  736. +
  737. +                    ie = nfs41_idmap_group_lookup_by_localid(nfs41_dg.idmapper,
  738. +                        unixgroup_gid);
  739. +                    if (ie != NULL) {
  740. +                        (void)strcpy(who_out, ie->nfsname.buf);
  741. +                        who_size = (DWORD)strlen(who_out); /* FIXME: |ie->nfsname.len| ? */
  742.                          sid_type = SidTypeGroup;
  743.                          status = ERROR_SUCCESS;
  744.  
  745. @@ -859,7 +927,8 @@ int map_sid2nfs4ace_who(PSID sid, PSID owner_sid, PSID group_sid,
  746.                              "Unix_Group+%d SID "
  747.                              "mapped to group '%s'\n",
  748.                              unixgroup_gid, who_out));
  749. -                        goto add_domain;
  750. +                        idmapcache_entry_refcount_dec(ie);
  751. +                        goto out;
  752.                      }
  753.  
  754.                      eprintf("map_sid2nfs4ace_who: "
  755. @@ -903,7 +972,8 @@ err_none_mapped:
  756.          }
  757.      }
  758.  
  759. -    (void)memcpy(who_out, who_buf, who_size);
  760. +    /* NOTREACHED */
  761. +
  762.  add_domain:
  763.      /*
  764.       * Complain if we attempt to add a domain suffix to an UID/GID
  765. @@ -942,8 +1012,6 @@ add_domain:
  766.  #endif /* NFS41_DRIVER_WS2022_HACKS */
  767.      (void)memcpy(wp, domain, strlen(domain)+1);
  768.  
  769. -/* no_add_domain: */
  770. -    status = ERROR_SUCCESS;
  771.  out:
  772.      if (status) {
  773.          DPRINTF(ACLLVL2,
  774. @@ -965,6 +1033,7 @@ out:
  775.      return status;
  776.  }
  777.  
  778. +/* FIXME: New idmapper API might make the |domain| parameter obsolete */
  779.  int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl,
  780.      int file_type, bool nfs_namedattr_support, char *domain)
  781.  {
  782. diff --git a/daemon/fileinfoutil.c b/daemon/fileinfoutil.c
  783. index d093a75..20a51ea 100644
  784. --- a/daemon/fileinfoutil.c
  785. +++ b/daemon/fileinfoutil.c
  786. @@ -439,8 +439,7 @@ void nfs_to_stat_lx_info(
  787.  
  788.      char owner[NFS4_FATTR4_OWNER_LIMIT+1];
  789.      char owner_group[NFS4_FATTR4_OWNER_LIMIT+1];
  790. -    uid_t map_uid = ~0UL;
  791. -    gid_t map_gid = ~0UL;
  792. +    idmapcache_entry *ie;
  793.  
  794.      EASSERT((info->attrmask.arr[1] & FATTR4_WORD1_OWNER) != 0);
  795.      EASSERT((info->attrmask.arr[1] & FATTR4_WORD1_OWNER_GROUP) != 0);
  796. @@ -459,12 +458,12 @@ void nfs_to_stat_lx_info(
  797.      EASSERT_MSG(IS_PRINCIPAL_NAME(owner),
  798.          ("owner='%s' is not a principal\n", owner));
  799.  
  800. -    if (!nfs41_idmap_name_to_uid(
  801. -        nfs41_dg->idmapper,
  802. -        owner,
  803. -        &map_uid)) {
  804. +    ie = nfs41_idmap_user_lookup_by_nfsname(nfs41_dg->idmapper,
  805. +        owner);
  806. +    if (ie != NULL) {
  807.          stat_lx_out->LxFlags |= LX_FILE_METADATA_HAS_UID;
  808. -        stat_lx_out->LxUid = map_uid;
  809. +        stat_lx_out->LxUid = ie->localid;
  810. +        idmapcache_entry_refcount_dec(ie);
  811.      }
  812.      else {
  813.          /*
  814. @@ -486,12 +485,12 @@ void nfs_to_stat_lx_info(
  815.      EASSERT_MSG(IS_PRINCIPAL_NAME(owner_group),
  816.          ("owner_group='%s' is not a principal\n", owner_group));
  817.  
  818. -    if (!nfs41_idmap_group_to_gid(
  819. -        nfs41_dg->idmapper,
  820. -        owner_group,
  821. -        &map_gid)) {
  822. +    ie = nfs41_idmap_group_lookup_by_nfsname(nfs41_dg->idmapper,
  823. +        owner_group);
  824. +    if (ie != NULL) {
  825.          stat_lx_out->LxFlags |= LX_FILE_METADATA_HAS_GID;
  826. -        stat_lx_out->LxGid = map_gid;
  827. +        stat_lx_out->LxGid = ie->localid;
  828. +        idmapcache_entry_refcount_dec(ie);
  829.      }
  830.      else {
  831.          /*
  832. diff --git a/daemon/idmap.c b/daemon/idmap.c
  833. index 4a4656c..88318bd 100644
  834. --- a/daemon/idmap.c
  835. +++ b/daemon/idmap.c
  836. @@ -23,7 +23,6 @@
  837.  
  838.  #include <Windows.h>
  839.  #include <strsafe.h>
  840. -#include <Winldap.h>
  841.  #include <stdlib.h> /* for strtoul() */
  842.  #include <errno.h>
  843.  
  844. @@ -34,71 +33,9 @@
  845.  #include "daemon_debug.h"
  846.  #include "util.h"
  847.  
  848. -#define PTR2UID_T(p) ((uid_t)PTR2PTRDIFF_T(p))
  849. -#define PTR2GID_T(p) ((gid_t)PTR2PTRDIFF_T(p))
  850. -#define PTR2UINT(p)  ((UINT)PTR2PTRDIFF_T(p))
  851. -#define UID_T2PTR(u) (PTRDIFF_T2PTR((ptrdiff_t)u))
  852. -#define GID_T2PTR(g) (PTRDIFF_T2PTR((ptrdiff_t)g))
  853. -
  854. -#define IDLVL 2         /* dprintf level for idmap logging */
  855. -#define CYGWINIDLVL 2   /* dprintf level for idmap logging */
  856. -
  857. -#define FILTER_LEN 1024
  858. -#define NAME_LEN 32
  859. -#define VAL_LEN 257
  860. -
  861. -
  862. -enum ldap_class {
  863. -    CLASS_USER,
  864. -    CLASS_GROUP,
  865. -
  866. -    NUM_CLASSES
  867. -};
  868. -
  869. -enum ldap_attr {
  870. -    ATTR_USER_NAME,
  871. -    ATTR_GROUP_NAME,
  872. -    ATTR_PRINCIPAL,
  873. -    ATTR_UID,
  874. -    ATTR_GID,
  875. -
  876. -    NUM_ATTRIBUTES
  877. -};
  878. -
  879. -#define ATTR_FLAG(attr) (1 << (attr))
  880. -#define ATTR_ISSET(mask, attr) (((mask) & ATTR_FLAG(attr)) != 0)
  881. -
  882. -
  883. -/* ldap/cache lookups */
  884. -struct idmap_lookup {
  885. -    enum ldap_attr attr;
  886. -    enum ldap_class klass;
  887. -    enum config_type type;
  888. -    list_compare_fn compare;
  889. -    const void *value;
  890. -};
  891. -
  892. -
  893.  /* configuration */
  894.  static const char CONFIG_FILENAME[] = "C:\\etc\\ms-nfs41-idmap.conf";
  895.  
  896. -struct idmap_config {
  897. -    /* ldap server information */
  898. -    char hostname[NFS41_HOSTNAME_LEN+1];
  899. -    char localdomain_name[NFS41_HOSTNAME_LEN+1];
  900. -    UINT port;
  901. -    UINT version;
  902. -    UINT timeout;
  903. -
  904. -    /* ldap schema information */
  905. -    char classes[NUM_CLASSES][NAME_LEN];
  906. -    char attributes[NUM_ATTRIBUTES][NAME_LEN];
  907. -    char base[VAL_LEN];
  908. -
  909. -    /* caching configuration */
  910. -    INT cache_ttl;
  911. -};
  912. -
  913.  
  914.  enum config_type {
  915.      TYPE_STR,
  916. @@ -125,22 +62,6 @@ struct config_option {
  917.  
  918.  /* table of recognized config options, including type and default value */
  919.  static const struct config_option g_options[] = {
  920. -    /* server information */
  921. -    OPT_STR("ldap_hostname", "localhost", hostname, NFS41_HOSTNAME_LEN+1),
  922. -    OPT_INT("ldap_port", "389", port),
  923. -    OPT_INT("ldap_version", "3", version),
  924. -    OPT_INT("ldap_timeout", "0", timeout),
  925. -
  926. -    /* schema information */
  927. -    OPT_STR("ldap_base", "cn=localhost", base, VAL_LEN),
  928. -    OPT_CLASS("ldap_class_users", "user", CLASS_USER),
  929. -    OPT_CLASS("ldap_class_groups", "group", CLASS_GROUP),
  930. -    OPT_ATTR("ldap_attr_username", "cn", ATTR_USER_NAME),
  931. -    OPT_ATTR("ldap_attr_groupname", "cn", ATTR_GROUP_NAME),
  932. -    OPT_ATTR("ldap_attr_gssAuthName", "gssAuthName", ATTR_PRINCIPAL),
  933. -    OPT_ATTR("ldap_attr_uidNumber", "uidNumber", ATTR_UID),
  934. -    OPT_ATTR("ldap_attr_gidNumber", "gidNumber", ATTR_GID),
  935. -
  936.      /* caching configuration */
  937.      OPT_INT("cache_ttl", "6000", cache_ttl),
  938.  };
  939. @@ -386,20 +307,6 @@ out:
  940.  }
  941.  
  942.  
  943. -/* generic cache */
  944. -
  945. -
  946. -/* ldap context */
  947. -struct idmap_context {
  948. -    struct idmap_config config;
  949. -
  950. -    idmapcache_context *usercache;
  951. -    idmapcache_context *groupcache;
  952. -
  953. -    LDAP *ldap;
  954. -};
  955. -
  956. -
  957.  /* public idmap interface */
  958.  int nfs41_idmap_create(
  959.      struct idmap_context **context_out, const char *localdomain_name)
  960. @@ -413,24 +320,16 @@ int nfs41_idmap_create(
  961.          goto out;
  962.      }
  963.  
  964. -    (void)strcpy_s(context->config.localdomain_name,
  965. -        sizeof(context->config.localdomain_name),
  966. -        localdomain_name);
  967. -    if (context == NULL) {
  968. -        status = GetLastError();
  969. -        goto out;
  970. -    }
  971. -
  972.      /* initialize the caches */
  973.      context->usercache = idmapcache_context_create();
  974.      context->groupcache = idmapcache_context_create();
  975.  
  976.      if ((context->usercache == NULL) || (context->groupcache == NULL)) {
  977.          eprintf("nfs41_idmap_create: Cannot create idmapcache\n");
  978. -        goto out;
  979. +        goto out_err_free;
  980.      }
  981.  
  982. -    /* load ldap configuration from file */
  983. +    /* load configuration from file */
  984.      status = config_init(&context->config);
  985.      if (status) {
  986.          eprintf("config_init() failed with %d\n", status);
  987. @@ -438,7 +337,8 @@ int nfs41_idmap_create(
  988.      }
  989.  
  990.  #ifdef NFS41_DRIVER_FEATURE_IDMAPPER_CYGWIN
  991. -    DPRINTF(CYGWINIDLVL, ("nfs41_idmap_create: Force context->config.timeout = 6000;\n"));
  992. +    DPRINTF(1,
  993. +        ("nfs41_idmap_create: Force context->config.timeout = 6000;\n"));
  994.      context->config.timeout = 6000;
  995.  #endif /* NFS41_DRIVER_FEATURE_IDMAPPER_CYGWIN */
  996.  
  997. @@ -455,306 +355,10 @@ out_err_free:
  998.  void nfs41_idmap_free(
  999.      struct idmap_context *context)
  1000.  {
  1001. -    /* clean up the connection */
  1002. -    if (context->ldap)
  1003. -        ldap_unbind(context->ldap);
  1004. -
  1005. -    idmapcache_context_destroy(context->usercache);
  1006. -    idmapcache_context_destroy(context->groupcache);
  1007. +    if (context->usercache != NULL)
  1008. +        idmapcache_context_destroy(context->usercache);
  1009. +    if (context->groupcache != NULL)
  1010. +        idmapcache_context_destroy(context->groupcache);
  1011.  
  1012.      free(context);
  1013.  }
  1014. -
  1015. -int nfs41_idmap_name_to_uid(
  1016. -    struct idmap_context *context,
  1017. -    const char *name,
  1018. -    uid_t *uid_out)
  1019. -{
  1020. -    int status = ERROR_NOT_FOUND;
  1021. -
  1022. -    DPRINTF(IDLVL, ("--> nfs41_idmap_name_to_uid(name='%s')\n", name));
  1023. -
  1024. -    idmapcache_entry *ie = NULL;
  1025. -
  1026. -    ie = idmapcache_lookup_by_nfsname(context->usercache, name);
  1027. -    if (ie != NULL) {
  1028. -        *uid_out = ie->nfsid;
  1029. -        status = ERROR_SUCCESS;
  1030. -        goto out;
  1031. -    }
  1032. -
  1033. -    char localname[256];
  1034. -    uid_t localuid;
  1035. -    char nfsowner[256];
  1036. -    uid_t nfsuid;
  1037. -
  1038. -    if (!cygwin_getent_passwd(name,
  1039. -        localname,
  1040. -        &localuid,
  1041. -        nfsowner,
  1042. -        &nfsuid)) {
  1043. -        DPRINTF(0, ("nfs41_idmap_name_to_uid(name='%s'): "
  1044. -            "Adding new user entry localname='%s', localuid=%ld, nfsowner='%s', nfsuid=%ld\n",
  1045. -            name,
  1046. -            localname,
  1047. -            (long)localuid,
  1048. -            nfsowner,
  1049. -            (long)nfsuid));
  1050. -
  1051. -        ie = idmapcache_add(context->usercache,
  1052. -            name/*localname*/,
  1053. -            localuid,
  1054. -            name/*nfsowner*/,
  1055. -            localuid/*nfsuid*/);
  1056. -        if (ie == NULL) {
  1057. -            DPRINTF(0, ("nfs41_idmap_name_to_uid(name='%s'): idmapcache_add() failed\n", name));
  1058. -        }
  1059. -        else {
  1060. -            *uid_out = ie->nfsid;
  1061. -            status = ERROR_SUCCESS;
  1062. -        }
  1063. -    }
  1064. -
  1065. -out:
  1066. -    DPRINTF(IDLVL, ("<-- nfs41_idmap_name_to_uid(name='%s') "
  1067. -        "returning status=%d, uid=%u\n",
  1068. -        name,
  1069. -        status,
  1070. -        (unsigned int)*uid_out));
  1071. -
  1072. -    if (ie != NULL) {
  1073. -        DPRINTF(3, ("nfs41_idmap_name_to_uid(name='%s'): "
  1074. -            "returning *uid_out=%u / user ie(=0x%p)={ win32name='%s', localuid=%ld, nfsname='%s', nfsid=%ld\n",
  1075. -            name,
  1076. -            (unsigned int)*uid_out,
  1077. -            (void *)ie,
  1078. -            ie->win32name.buf,
  1079. -            (long)ie->localid,
  1080. -            ie->nfsname.buf,
  1081. -            (long)ie->nfsid));
  1082. -        idmapcache_entry_refcount_dec(ie);
  1083. -    }
  1084. -
  1085. -    return status;
  1086. -}
  1087. -
  1088. -int nfs41_idmap_uid_to_name(
  1089. -    struct idmap_context *context,
  1090. -    uid_t uid,
  1091. -    char *name,
  1092. -    size_t len)
  1093. -{
  1094. -    int status = ERROR_NOT_FOUND;
  1095. -
  1096. -    DPRINTF(IDLVL, ("--> nfs41_idmap_uid_to_name(uid=%u)\n", (unsigned int)uid));
  1097. -
  1098. -    idmapcache_entry *ie = NULL;
  1099. -
  1100. -    ie = idmapcache_lookup_by_nfsid(context->usercache, uid);
  1101. -    if (ie != NULL) {
  1102. -        (void)strcpy(name, ie->nfsname.buf);
  1103. -        status = ERROR_SUCCESS;
  1104. -        goto out;
  1105. -    }
  1106. -
  1107. -    char localname[256];
  1108. -    uid_t localuid;
  1109. -    char nfsowner[256];
  1110. -    uid_t nfsuid;
  1111. -
  1112. -    if (!cygwin_getent_passwd(name,
  1113. -        localname,
  1114. -        &localuid,
  1115. -        nfsowner,
  1116. -        &nfsuid)) {
  1117. -        DPRINTF(0, ("nfs41_idmap_uid_to_name(name='%s'): "
  1118. -            "Adding new user entry localname='%s', localuid=%ld, nfsowner='%s', nfsuid=%ld\n",
  1119. -            name,
  1120. -            localname,
  1121. -            (long)localuid,
  1122. -            nfsowner,
  1123. -            (long)nfsuid));
  1124. -
  1125. -        ie = idmapcache_add(context->usercache,
  1126. -            name/*localname*/,
  1127. -            localuid,
  1128. -            name/*nfsowner*/,
  1129. -            localuid/*nfsuid*/);
  1130. -        if (ie == NULL) {
  1131. -            DPRINTF(0, ("nfs41_idmap_uid_to_name(name='%s'): idmapcache_add() failed\n", name));
  1132. -        }
  1133. -        else {
  1134. -            (void)strcpy(name, ie->nfsname.buf);
  1135. -            status = ERROR_SUCCESS;
  1136. -        }
  1137. -    }
  1138. -
  1139. -out:
  1140. -    DPRINTF(IDLVL, ("<-- nfs41_idmap_uid_to_name(uid=%u) "
  1141. -        "returning status=%d, name='%s'\n",
  1142. -        (unsigned int)uid,
  1143. -        status,
  1144. -        ((status == 0)?name:"<nothing>")));
  1145. -
  1146. -    if (ie != NULL) {
  1147. -        DPRINTF(0, ("nfs41_idmap_uid_to_name(uid=%u): "
  1148. -            "returning *name='%s' / user ie(=0x%p)={ win32name='%s', localuid=%ld, nfsname='%s', nfsid=%ld\n",
  1149. -            (unsigned int)uid,
  1150. -            ((status == 0)?name:"<nothing>"),
  1151. -            (void *)ie,
  1152. -            ie->win32name.buf,
  1153. -            (long)ie->localid,
  1154. -            ie->nfsname.buf,
  1155. -            (long)ie->nfsid));
  1156. -        idmapcache_entry_refcount_dec(ie);
  1157. -    }
  1158. -
  1159. -    return status;
  1160. -}
  1161. -
  1162. -int nfs41_idmap_group_to_gid(
  1163. -    struct idmap_context *context,
  1164. -    const char *name,
  1165. -    gid_t *gid_out)
  1166. -{
  1167. -    int status = ERROR_NOT_FOUND;
  1168. -
  1169. -    DPRINTF(IDLVL, ("--> nfs41_idmap_group_to_gid(name='%s')\n", name));
  1170. -
  1171. -    idmapcache_entry *ie = NULL;
  1172. -
  1173. -    ie = idmapcache_lookup_by_nfsname(context->groupcache, name);
  1174. -    if (ie != NULL) {
  1175. -        *gid_out = ie->nfsid;
  1176. -        status = ERROR_SUCCESS;
  1177. -        goto out;
  1178. -    }
  1179. -
  1180. -    char localgroupname[256];
  1181. -    gid_t localgid;
  1182. -    char nfsownergroup[256];
  1183. -    gid_t nfsgid;
  1184. -
  1185. -    if (!cygwin_getent_group(name,
  1186. -        localgroupname,
  1187. -        &localgid,
  1188. -        nfsownergroup,
  1189. -        &nfsgid)) {
  1190. -        DPRINTF(0, ("nfs41_idmap_group_to_gid(name='%s'): "
  1191. -            "Adding new group entry localgroupname='%s', localgid=%ld, nfsownergroup='%s', nfsgid=%ld\n",
  1192. -            name,
  1193. -            localgroupname,
  1194. -            (long)localgid,
  1195. -            nfsownergroup,
  1196. -            (long)nfsgid));
  1197. -
  1198. -        ie = idmapcache_add(context->groupcache,
  1199. -            name/*localgroupname*/,
  1200. -            localgid,
  1201. -            name/*nfsownergroup*/,
  1202. -            localgid/*nfsgid*/);
  1203. -        if (ie == NULL) {
  1204. -            DPRINTF(0, ("nfs41_idmap_group_to_gid(name='%s'): idmapcache_add() failed\n", name));
  1205. -        }
  1206. -        else {
  1207. -            *gid_out = ie->nfsid;
  1208. -            status = ERROR_SUCCESS;
  1209. -        }
  1210. -    }
  1211. -
  1212. -out:
  1213. -    DPRINTF(IDLVL, ("<-- nfs41_idmap_group_to_gid(name='%s') "
  1214. -        "returning status=%d, gid=%u\n",
  1215. -        name,
  1216. -        status,
  1217. -        (unsigned int)*gid_out));
  1218. -
  1219. -    if (ie != NULL) {
  1220. -        DPRINTF(3, ("nfs41_idmap_group_to_gid(name='%s'): "
  1221. -            "returning *gid_out=%u / group ie(=0x%p)={ win32name='%s', localgid=%ld, nfsname='%s', nfsid=%ld\n",
  1222. -            name,
  1223. -            (unsigned int)*gid_out,
  1224. -            (void *)ie,
  1225. -            ie->win32name.buf,
  1226. -            (long)ie->localid,
  1227. -            ie->nfsname.buf,
  1228. -            (long)ie->nfsid));
  1229. -        idmapcache_entry_refcount_dec(ie);
  1230. -    }
  1231. -
  1232. -    return status;
  1233. -}
  1234. -
  1235. -int nfs41_idmap_gid_to_group(
  1236. -    struct idmap_context *context,
  1237. -    gid_t gid,
  1238. -    char *name,
  1239. -    size_t len)
  1240. -{
  1241. -    int status = ERROR_NOT_FOUND;
  1242. -
  1243. -    DPRINTF(IDLVL, ("--> nfs41_idmap_gid_to_group(gid=%u)\n", (unsigned int)gid));
  1244. -
  1245. -    idmapcache_entry *ie = NULL;
  1246. -
  1247. -    ie = idmapcache_lookup_by_nfsid(context->groupcache, gid);
  1248. -    if (ie != NULL) {
  1249. -        (void)strcpy(name, ie->nfsname.buf);
  1250. -        status = ERROR_SUCCESS;
  1251. -        goto out;
  1252. -    }
  1253. -
  1254. -    char localgroupname[256];
  1255. -    gid_t localgid;
  1256. -    char nfsownergroup[256];
  1257. -    gid_t nfsgid;
  1258. -
  1259. -    if (!cygwin_getent_group(name,
  1260. -        localgroupname,
  1261. -        &localgid,
  1262. -        nfsownergroup,
  1263. -        &nfsgid)) {
  1264. -        DPRINTF(0, ("nfs41_idmap_group_to_gid(name='%s'): "
  1265. -            "Adding new group entry localgroupname='%s', localgid=%ld, nfsownergroup='%s', nfsgid=%ld\n",
  1266. -            name,
  1267. -            localgroupname,
  1268. -            (long)localgid,
  1269. -            nfsownergroup,
  1270. -            (long)nfsgid));
  1271. -
  1272. -        ie = idmapcache_add(context->groupcache,
  1273. -            name/*localgroupname*/,
  1274. -            localgid,
  1275. -            name/*nfsownergroup*/,
  1276. -            localgid/*nfsgid*/);
  1277. -        if (ie == NULL) {
  1278. -            DPRINTF(0, ("nfs41_idmap_group_to_gid(name='%s'): idmapcache_add() failed\n", name));
  1279. -        }
  1280. -        else {
  1281. -            (void)strcpy(name, ie->nfsname.buf);
  1282. -            status = ERROR_SUCCESS;
  1283. -        }
  1284. -    }
  1285. -
  1286. -out:
  1287. -    DPRINTF(IDLVL, ("<-- nfs41_idmap_gid_to_group(gid=%u) "
  1288. -        "returning status=%d, name='%s'\n",
  1289. -        (unsigned int)gid,
  1290. -        status,
  1291. -        ((status == 0)?name:"<nothing>")));
  1292. -
  1293. -    if (ie != NULL) {
  1294. -        DPRINTF(0, ("nfs41_idmap_gid_to_group(gid=%u): "
  1295. -            "returning *name='%s' / group ie(=0x%p)={ win32name='%s', localgid=%ld, nfsname='%s', nfsid=%ld\n",
  1296. -            (unsigned int)gid,
  1297. -            ((status == 0)?name:"<nothing>"),
  1298. -            (void *)ie,
  1299. -            ie->win32name.buf,
  1300. -            (long)ie->localid,
  1301. -            ie->nfsname.buf,
  1302. -            (long)ie->nfsid));
  1303. -        idmapcache_entry_refcount_dec(ie);
  1304. -    }
  1305. -
  1306. -    return status;
  1307. -}
  1308. diff --git a/daemon/idmap.h b/daemon/idmap.h
  1309. index 1c277d1..68e6f9e 100644
  1310. --- a/daemon/idmap.h
  1311. +++ b/daemon/idmap.h
  1312. @@ -32,42 +32,30 @@ typedef struct idmap_context nfs41_idmapper;
  1313.  
  1314.  int nfs41_idmap_create(
  1315.      nfs41_idmapper **context_out, const char *localdomain_name);
  1316. -
  1317.  void nfs41_idmap_free(
  1318.      nfs41_idmapper *context);
  1319.  
  1320. -
  1321. -int nfs41_idmap_name_to_uid(
  1322. -    struct idmap_context *context,
  1323. -    const char *username,
  1324. -    uid_t *uid_out);
  1325. -
  1326. -int nfs41_idmap_uid_to_name(
  1327. -    nfs41_idmapper *context,
  1328. -    uid_t uid,
  1329. -    char *name_out,
  1330. -    size_t len);
  1331. -
  1332. -int nfs41_idmap_group_to_gid(
  1333. -    nfs41_idmapper *context,
  1334. -    const char *name,
  1335. -    gid_t *gid_out);
  1336. -
  1337. -int nfs41_idmap_gid_to_group(
  1338. -    nfs41_idmapper *context,
  1339. -    gid_t gid,
  1340. -    char *name_out,
  1341. -    size_t len);
  1342. -
  1343.  /* idmap_cygwin.c */
  1344.  #ifdef NFS41_DRIVER_FEATURE_IDMAPPER_CYGWIN
  1345. -int cygwin_getent_passwd(
  1346. +int cygwin_local_getent_passwd(
  1347. +    const char *restrict name,
  1348. +    char *restrict res_localaccountname,
  1349. +    uid_t *restrict res_localuid,
  1350. +    char *restrict res_nfsowner,
  1351. +    uid_t *restrict res_nfsuid);
  1352. +int cygwin_nfsserver_getent_passwd(
  1353.      const char *restrict name,
  1354.      char *restrict res_localaccountname,
  1355.      uid_t *restrict res_localuid,
  1356.      char *restrict res_nfsowner,
  1357.      uid_t *restrict res_nfsuid);
  1358. -int cygwin_getent_group(
  1359. +int cygwin_local_getent_group(
  1360. +    const char *restrict name,
  1361. +    char *restrict res_localgroupname,
  1362. +    gid_t *restrict res_localgid,
  1363. +    char *restrict res_nfsownergroup,
  1364. +    gid_t *restrict res_nfsgid);
  1365. +int cygwin_nfsserver_getent_group(
  1366.      const char *restrict name,
  1367.      char *restrict res_localgroupname,
  1368.      gid_t *restrict res_localgid,
  1369. @@ -75,7 +63,7 @@ int cygwin_getent_group(
  1370.      gid_t *restrict res_nfsgid);
  1371.  #endif /* NFS41_DRIVER_FEATURE_IDMAPPER_CYGWIN */
  1372.  
  1373. -#define IDMAPCACHE_TTL_SECONDS 60
  1374. +#define IDMAPCACHE_TTL_SECONDS (60*5)
  1375.  #define IDMAPCACHE_MAXNAME_LEN 256
  1376.  
  1377.  /*
  1378. @@ -107,15 +95,68 @@ idmapcache_entry *idmapcache_add(idmapcache_context *restrict ctx,
  1379.      idmapcache_idnumber localid,
  1380.      const char *restrict nfsname,
  1381.      idmapcache_idnumber nfsid);
  1382. -idmapcache_entry *idmapcache_lookup_by_win32name(idmapcache_context *restrict ctx,
  1383. +idmapcache_entry *idmapcache_lookup_by_win32name(
  1384. +    idmapcache_context *restrict ctx,
  1385.      const char *restrict win32name);
  1386. -idmapcache_entry *idmapcache_lookup_by_localid(idmapcache_context *restrict ctx,
  1387. +idmapcache_entry *idmapcache_lookup_by_localid(
  1388. +    idmapcache_context *restrict ctx,
  1389.      idmapcache_idnumber search_localid);
  1390. -idmapcache_entry *idmapcache_lookup_by_nfsname(idmapcache_context *restrict ctx,
  1391. +idmapcache_entry *idmapcache_lookup_by_nfsname(
  1392. +    idmapcache_context *restrict ctx,
  1393.      const char *restrict nfsname);
  1394.  idmapcache_entry *idmapcache_lookup_by_nfsid(idmapcache_context *restrict ctx,
  1395.      idmapcache_idnumber search_nfslid);
  1396.  void idmapcache_entry_refcount_inc(idmapcache_entry *restrict e);
  1397.  void idmapcache_entry_refcount_dec(idmapcache_entry *restrict e);
  1398.  
  1399. +struct idmap_config {
  1400. +    UINT timeout;
  1401. +
  1402. +    /* caching configuration */
  1403. +    INT cache_ttl;
  1404. +};
  1405. +
  1406. +struct idmap_context {
  1407. +    struct idmap_config config;
  1408. +
  1409. +    idmapcache_context *usercache;
  1410. +    idmapcache_context *groupcache;
  1411. +
  1412. +    void *ldap;
  1413. +};
  1414. +
  1415. +/*
  1416. + * User lookup functions
  1417. + * If an entry does not exists the idmapper script will be called to create it
  1418. + */
  1419. +idmapcache_entry *nfs41_idmap_user_lookup_by_win32name(
  1420. +    struct idmap_context *context,
  1421. +    const char *restrict win32name);
  1422. +idmapcache_entry *nfs41_idmap_user_lookup_by_localid(
  1423. +    struct idmap_context *context,
  1424. +    idmapcache_idnumber search_localid);
  1425. +idmapcache_entry *nfs41_idmap_user_lookup_by_nfsname(
  1426. +    struct idmap_context *context,
  1427. +    const char *restrict nfsname);
  1428. +idmapcache_entry *nfs41_idmap_user_lookup_by_nfsid(
  1429. +    struct idmap_context *context,
  1430. +    idmapcache_idnumber search_nfslid);
  1431. +
  1432. +/*
  1433. + * User lookup functions
  1434. + * If an entry does not exists the idmapper script will be called to create it
  1435. + */
  1436. +idmapcache_entry *nfs41_idmap_group_lookup_by_win32name(
  1437. +    struct idmap_context *context,
  1438. +    const char *restrict win32name);
  1439. +idmapcache_entry *nfs41_idmap_group_lookup_by_localid(
  1440. +    struct idmap_context *context,
  1441. +    idmapcache_idnumber search_localid);
  1442. +idmapcache_entry *nfs41_idmap_group_lookup_by_nfsname(
  1443. +    struct idmap_context *context,
  1444. +    const char *restrict nfsname);
  1445. +idmapcache_entry *nfs41_idmap_group_lookup_by_nfsid(
  1446. +    struct idmap_context *context,
  1447. +    idmapcache_idnumber search_nfslid);
  1448. +
  1449.  #endif /* !IDMAP_H */
  1450. diff --git a/daemon/idmap_cygwin.c b/daemon/idmap_cygwin.c
  1451. index a30b7d6..771974f 100644
  1452. --- a/daemon/idmap_cygwin.c
  1453. +++ b/daemon/idmap_cygwin.c
  1454. @@ -52,7 +52,9 @@
  1455.  #endif /* _WIN64 */
  1456.  
  1457.  #ifdef NFS41_DRIVER_FEATURE_IDMAPPER_CYGWIN
  1458. +static
  1459.  int cygwin_getent_passwd(
  1460. +    const char *restrict mode,
  1461.      const char *restrict name,
  1462.      char *restrict res_localaccountname,
  1463.      uid_t *restrict res_localuid,
  1464. @@ -75,14 +77,14 @@ int cygwin_getent_passwd(
  1465.      const char *nfsowner = NULL;
  1466.  
  1467.      DPRINTF(CYGWINIDLVL,
  1468. -        ("--> cygwin_getent_passwd(name='%s')\n",
  1469. -        name));
  1470. +        ("--> cygwin_getent_passwd(mode='%s',name='%s')\n",
  1471. +        mode, name));
  1472.  
  1473.      if (name[0] == '\0') {
  1474.          DPRINTF(0,
  1475. -            ("cygwin_getent_passwd(name='%s'): "
  1476. +            ("cygwin_getent_passwd(mode='%s',name='%s'): "
  1477.              "ERROR: Empty user name.\n",
  1478. -            name));
  1479. +            mode, name));
  1480.          goto fail;
  1481.      }
  1482.  
  1483. @@ -91,14 +93,16 @@ int cygwin_getent_passwd(
  1484.  
  1485.      /* fixme: better quoting for |name| needed */
  1486.      (void)snprintf(cmdbuff, sizeof(cmdbuff),
  1487. -        "%s nfsserver_owner2localaccount \"%s\"",
  1488. +        "%s %s \"%s\"",
  1489.          CYGWIN_IDMAPPER_SCRIPT,
  1490. +        mode,
  1491.          name);
  1492.      if ((script_pipe = subcmd_popen(cmdbuff)) == NULL) {
  1493.          int last_error = GetLastError();
  1494.          DPRINTF(0,
  1495. -            ("cygwin_getent_passwd(name='%s'): "
  1496. +            ("cygwin_getent_passwd(mode='%s',name='%s'): "
  1497.              "'%s' failed, GetLastError()='%d'\n",
  1498. +            mode,
  1499.              name,
  1500.              cmdbuff,
  1501.              last_error));
  1502. @@ -108,9 +112,9 @@ int cygwin_getent_passwd(
  1503.      if (!subcmd_readcmdoutput(script_pipe,
  1504.          buff, sizeof(buff), &num_buff_read)) {
  1505.          DPRINTF(0,
  1506. -            ("cygwin_getent_passwd(name='%s'): "
  1507. +            ("cygwin_getent_passwd(mode='%s',name='%s'): "
  1508.              "subcmd_readcmdoutput() failed\n",
  1509. -            name));
  1510. +            mode, name));
  1511.          goto fail;
  1512.      }
  1513.  
  1514. @@ -118,26 +122,26 @@ int cygwin_getent_passwd(
  1515.  
  1516.      if (num_buff_read < 10) {
  1517.          DPRINTF(0,
  1518. -            ("cygwin_getent_passwd(name='%s'): "
  1519. +            ("cygwin_getent_passwd(mode='%s',name='%s'): "
  1520.              "Could not read enough data, returned %d\n",
  1521. -            name, (int)num_buff_read));
  1522. +            mode, name, (int)num_buff_read));
  1523.          goto fail;
  1524.      }
  1525.  
  1526.      cpvp = cpv_create_parser(buff, 0/*CPVFLAG_DEBUG_OUTPUT*/);
  1527.      if (!cpvp) {
  1528.          DPRINTF(0,
  1529. -            ("cygwin_getent_passwd(name='%s'): "
  1530. +            ("cygwin_getent_passwd(mode='%s',name='%s'): "
  1531.              "Could not create parser\n",
  1532. -            name));
  1533. +            mode, name));
  1534.          goto fail;
  1535.      }
  1536.  
  1537.      if (cpv_read_cpv_header(cpvp)) {
  1538.          DPRINTF(0,
  1539. -            ("cygwin_getent_passwd(name='%s'): "
  1540. +            ("cygwin_getent_passwd(mode='%s',name='%s'): "
  1541.              "cpv_read_cpv_header failed\n",
  1542. -            name));
  1543. +            mode, name));
  1544.          goto fail;
  1545.      }
  1546.  
  1547. @@ -186,9 +190,9 @@ int cygwin_getent_passwd(
  1548.       * The idmapper script must never return this!
  1549.       */
  1550.      if (!strcmp(localaccountname, "Unknown+User")) {
  1551. -        eprintf("cygwin_getent_passwd(name='%s'): "
  1552. +        eprintf("cygwin_getent_passwd(mode='%s',name='%s'): "
  1553.              "idmapper returned illegal value '%s'\n",
  1554. -            name, localaccountname);
  1555. +            mode, name, localaccountname);
  1556.          goto fail;
  1557.      }
  1558.  
  1559. @@ -214,9 +218,10 @@ fail:
  1560.  
  1561.      if (res == 0) {
  1562.          DPRINTF(CYGWINIDLVL,
  1563. -            ("<-- cygwin_getent_passwd(name='%s'): "
  1564. +            ("<-- cygwin_getent_passwd(mode='%s',name='%s'): "
  1565.              "returning res_localuid=%u, res_localaccountname='%s', "
  1566.              "res_nfsowner='%s' res_nfsuid=%u\n",
  1567. +            mode,
  1568.              name,
  1569.              (unsigned int)(res_localuid?(*res_localuid):~0),
  1570.              res_localaccountname?res_localaccountname:"<NULL>",
  1571. @@ -225,14 +230,48 @@ fail:
  1572.      }
  1573.      else {
  1574.          DPRINTF(CYGWINIDLVL,
  1575. -            ("<-- cygwin_getent_passwd(name='%s'): no match found\n",
  1576. -            name));
  1577. +            ("<-- cygwin_getent_passwd(mode='%s',name='%s'): no match found\n",
  1578. +            mode, name));
  1579.      }
  1580.  
  1581.      return res;
  1582.  }
  1583.  
  1584. +int cygwin_local_getent_passwd(
  1585. +    const char *restrict name,
  1586. +    char *restrict res_localaccountname,
  1587. +    uid_t *restrict res_localuid,
  1588. +    char *restrict res_nfsowner,
  1589. +    uid_t *restrict res_nfsuid)
  1590. +{
  1591. +    return cygwin_getent_passwd(
  1592. +        "localname2localaccount",
  1593. +        name,
  1594. +        res_localaccountname,
  1595. +        res_localuid,
  1596. +        res_nfsowner,
  1597. +        res_nfsuid);
  1598. +}
  1599. +
  1600. +int cygwin_nfsserver_getent_passwd(
  1601. +    const char *restrict name,
  1602. +    char *restrict res_localaccountname,
  1603. +    uid_t *restrict res_localuid,
  1604. +    char *restrict res_nfsowner,
  1605. +    uid_t *restrict res_nfsuid)
  1606. +{
  1607. +    return cygwin_getent_passwd(
  1608. +        "nfsserver_owner2localaccount",
  1609. +        name,
  1610. +        res_localaccountname,
  1611. +        res_localuid,
  1612. +        res_nfsowner,
  1613. +        res_nfsuid);
  1614. +}
  1615. +
  1616. +static
  1617.  int cygwin_getent_group(
  1618. +    const char *restrict mode,
  1619.      const char *restrict name,
  1620.      char *restrict res_localgroupname,
  1621.      gid_t *restrict res_localgid,
  1622. @@ -256,14 +295,14 @@ int cygwin_getent_group(
  1623.      const char *nfsownergroup = NULL;
  1624.  
  1625.      DPRINTF(CYGWINIDLVL,
  1626. -        ("--> cygwin_getent_group(name='%s')\n",
  1627. -        name));
  1628. +        ("--> cygwin_getent_group(mode='%s',name='%s')\n",
  1629. +        mode, name));
  1630.  
  1631.      if (name[0] == '\0') {
  1632.          DPRINTF(0,
  1633. -            ("cygwin_getent_group(name='%s'): "
  1634. +            ("cygwin_getent_group(mode='%s',name='%s'): "
  1635.              "ERROR: Empty group name.\n",
  1636. -            name));
  1637. +            mode, name));
  1638.          goto fail;
  1639.      }
  1640.  
  1641. @@ -272,14 +311,16 @@ int cygwin_getent_group(
  1642.  
  1643.      /* fixme: better quoting for |name| needed */
  1644.      (void)snprintf(cmdbuff, sizeof(cmdbuff),
  1645. -        "%s nfsserver_owner_group2localgroup \"%s\"",
  1646. +        "%s %s \"%s\"",
  1647.          CYGWIN_IDMAPPER_SCRIPT,
  1648. +        mode,
  1649.          name);
  1650.      if ((script_pipe = subcmd_popen(cmdbuff)) == NULL) {
  1651.          int last_error = GetLastError();
  1652.          DPRINTF(0,
  1653. -            ("cygwin_getent_group(name='%s'): "
  1654. +            ("cygwin_getent_group(mode='%s',name='%s'): "
  1655.              "'%s' failed, GetLastError()='%d'\n",
  1656. +            mode,
  1657.              name,
  1658.              cmdbuff,
  1659.              last_error));
  1660. @@ -289,9 +330,9 @@ int cygwin_getent_group(
  1661.      if (!subcmd_readcmdoutput(script_pipe,
  1662.          buff, sizeof(buff), &num_buff_read)) {
  1663.          DPRINTF(0,
  1664. -            ("cygwin_getent_group(name='%s'): "
  1665. +            ("cygwin_getent_group(mode='%s',name='%s'): "
  1666.              "subcmd_readcmdoutput() failed\n",
  1667. -            name));
  1668. +            mode, name));
  1669.          goto fail;
  1670.      }
  1671.  
  1672. @@ -299,26 +340,26 @@ int cygwin_getent_group(
  1673.  
  1674.      if (num_buff_read < 10) {
  1675.          DPRINTF(0,
  1676. -            ("cygwin_getent_group(name='%s'): "
  1677. +            ("cygwin_getent_group(mode='%s',name='%s'): "
  1678.              "Could not read enough data, returned %d\n",
  1679. -            name, (int)num_buff_read));
  1680. +            mode, name, (int)num_buff_read));
  1681.          goto fail;
  1682.      }
  1683.  
  1684.      cpvp = cpv_create_parser(buff, 0/*CPVFLAG_DEBUG_OUTPUT*/);
  1685.      if (!cpvp) {
  1686.          DPRINTF(0,
  1687. -            ("cygwin_getent_group(name='%s'): "
  1688. +            ("cygwin_getent_group(mode='%s',name='%s'): "
  1689.              "Could not create parser\n",
  1690. -            name));
  1691. +            mode, name));
  1692.          goto fail;
  1693.      }
  1694.  
  1695.      if (cpv_read_cpv_header(cpvp)) {
  1696.          DPRINTF(0,
  1697. -            ("cygwin_getent_group(name='%s'): "
  1698. +            ("cygwin_getent_group(mode='%s',name='%s'): "
  1699.              "cpv_read_cpv_header failed\n",
  1700. -            name));
  1701. +            mode, name));
  1702.          goto fail;
  1703.      }
  1704.  
  1705. @@ -367,9 +408,9 @@ int cygwin_getent_group(
  1706.       * The idmapper script must never return this!
  1707.       */
  1708.      if (!strcmp(localgroupname, "Unknown+Group")) {
  1709. -        eprintf("cygwin_getent_group(name='%s'): "
  1710. +        eprintf("cygwin_getent_group(mode='%s',name='%s'): "
  1711.              "idmapper returned illegal value '%s'\n",
  1712. -            name, localgroupname);
  1713. +            mode, name, localgroupname);
  1714.          goto fail;
  1715.      }
  1716.  
  1717. @@ -395,8 +436,9 @@ fail:
  1718.  
  1719.      if (res == 0) {
  1720.          DPRINTF(CYGWINIDLVL,
  1721. -            ("<-- cygwin_getent_group(name='%s'): "
  1722. +            ("<-- cygwin_getent_group(mode='%s',name='%s'): "
  1723.              "returning res_localgid=%u, res_localgroupname='%s', res_nfsownergroup='%s', res_localgid=%u\n",
  1724. +            mode,
  1725.              name,
  1726.              (unsigned int)(res_localgid?*res_localgid:~0),
  1727.              res_localgroupname?res_localgroupname:"<NULL>",
  1728. @@ -405,12 +447,44 @@ fail:
  1729.      }
  1730.      else {
  1731.          DPRINTF(CYGWINIDLVL,
  1732. -            ("<-- cygwin_getent_group(name='%s'): no match found\n",
  1733. -            name));
  1734. +            ("<-- cygwin_getent_group(mode='%s',name='%s'): no match found\n",
  1735. +            mode, name));
  1736.      }
  1737.  
  1738.      return res;
  1739.  }
  1740. +
  1741. +int cygwin_local_getent_group(
  1742. +    const char *restrict name,
  1743. +    char *restrict res_localgroupname,
  1744. +    gid_t *restrict res_localgid,
  1745. +    char *restrict res_nfsownergroup,
  1746. +    gid_t *restrict res_nfsgid)
  1747. +{
  1748. +    return cygwin_getent_group(
  1749. +        "localgroup2localgroup",
  1750. +        name,
  1751. +        res_localgroupname,
  1752. +        res_localgid,
  1753. +        res_nfsownergroup,
  1754. +        res_nfsgid);
  1755. +}
  1756. +
  1757. +int cygwin_nfsserver_getent_group(
  1758. +    const char *restrict name,
  1759. +    char *restrict res_localgroupname,
  1760. +    gid_t *restrict res_localgid,
  1761. +    char *restrict res_nfsownergroup,
  1762. +    gid_t *restrict res_nfsgid)
  1763. +{
  1764. +    return cygwin_getent_group(
  1765. +        "nfsserver_owner_group2localgroup",
  1766. +        name,
  1767. +        res_localgroupname,
  1768. +        res_localgid,
  1769. +        res_nfsownergroup,
  1770. +        res_nfsgid);
  1771. +}
  1772.  #endif /* NFS41_DRIVER_FEATURE_IDMAPPER_CYGWIN */
  1773.  
  1774.  
  1775. @@ -507,7 +581,7 @@ idmapcache_entry *idmapcache_lookup(idmapcache_context *restrict ctx,
  1776.  
  1777.      ReleaseSRWLockShared(&ctx->lock);
  1778.  
  1779. -    return &found_node->entry;
  1780. +    return (found_node != NULL)?(&found_node->entry):(NULL);
  1781.  }
  1782.  
  1783.  static
  1784. @@ -643,3 +717,608 @@ idmapcache_entry *idmapcache_lookup_by_nfsid(idmapcache_context *restrict ctx,
  1785.  {
  1786.      return idmapcache_lookup(ctx, cmp_by_nfsid, &search_nfsid);
  1787.  }
  1788. +
  1789. +/*
  1790. + * Public idmapper API
  1791. + */
  1792. +
  1793. +idmapcache_entry *nfs41_idmap_user_lookup_by_win32name(struct idmap_context *context,
  1794. +    const char *restrict name)
  1795. +{
  1796. +    int status = ERROR_NOT_FOUND;
  1797. +    idmapcache_entry *ie;
  1798. +
  1799. +    DPRINTF(CYGWINIDLVL,
  1800. +        ("--> nfs41_idmap_user_lookup_by_win32name(name='%s')\n",
  1801. +        name));
  1802. +
  1803. +    ie = idmapcache_lookup_by_win32name(context->usercache, name);
  1804. +    if (ie != NULL) {
  1805. +        status = ERROR_SUCCESS;
  1806. +        goto out;
  1807. +    }
  1808. +
  1809. +    char localname[256];
  1810. +    uid_t localuid;
  1811. +    char nfsowner[256];
  1812. +    uid_t nfsuid;
  1813. +
  1814. +    if (!cygwin_local_getent_passwd(name,
  1815. +        localname,
  1816. +        &localuid,
  1817. +        nfsowner,
  1818. +        &nfsuid)) {
  1819. +        DPRINTF(0,
  1820. +            ("nfs41_idmap_user_lookup_by_win32name(name='%s'): "
  1821. +            "Adding new user entry localname='%s', localuid=%ld, nfsowner='%s', nfsuid=%ld\n",
  1822. +            name,
  1823. +            localname,
  1824. +            (long)localuid,
  1825. +            nfsowner,
  1826. +            (long)nfsuid));
  1827. +
  1828. +        ie = idmapcache_add(context->usercache,
  1829. +            localname,
  1830. +            localuid,
  1831. +            nfsowner,
  1832. +            nfsuid);
  1833. +        if (ie == NULL) {
  1834. +            DPRINTF(0,
  1835. +                ("nfs41_idmap_user_lookup_by_win32name(name='%s'): idmapcache_add() failed\n",
  1836. +                name));
  1837. +        }
  1838. +        else {
  1839. +            status = ERROR_SUCCESS;
  1840. +        }
  1841. +    }
  1842. +
  1843. +out:
  1844. +    if (ie != NULL) {
  1845. +        DPRINTF(CYGWINIDLVL,
  1846. +            ("<-- nfs41_idmap_user_lookup_by_win32name(name='%s'): "
  1847. +            "returning status=%d / user ie(=0x%p)={ win32name='%s', localuid=%ld, nfsname='%s', nfsid=%ld\n",
  1848. +            name,
  1849. +            status,
  1850. +            (void *)ie,
  1851. +            ie->win32name.buf,
  1852. +            (long)ie->localid,
  1853. +            ie->nfsname.buf,
  1854. +            (long)ie->nfsid));
  1855. +    }
  1856. +    else {
  1857. +        DPRINTF(CYGWINIDLVL,
  1858. +            ("<-- nfs41_idmap_user_lookup_by_win32name(name='%s'): "
  1859. +            "returning status=%d / ie=NULL\n",
  1860. +            name,
  1861. +            status));
  1862. +    }
  1863. +
  1864. +    return ie;
  1865. +}
  1866. +
  1867. +idmapcache_entry *nfs41_idmap_user_lookup_by_localid(struct idmap_context *context,
  1868. +    idmapcache_idnumber search_localid)
  1869. +{
  1870. +    int status = ERROR_NOT_FOUND;
  1871. +    idmapcache_entry *ie;
  1872. +
  1873. +    DPRINTF(CYGWINIDLVL,
  1874. +        ("--> nfs41_idmap_user_lookup_by_localid(search_localid=%ld)\n",
  1875. +        (long)search_localid));
  1876. +
  1877. +    ie = idmapcache_lookup_by_localid(context->usercache, search_localid);
  1878. +    if (ie != NULL) {
  1879. +        status = ERROR_SUCCESS;
  1880. +        goto out;
  1881. +    }
  1882. +
  1883. +    char localname[256];
  1884. +    uid_t localuid;
  1885. +    char nfsowner[256];
  1886. +    uid_t nfsuid;
  1887. +    char name[64];
  1888. +    (void)sprintf(name, "%ld", (long)search_localid);
  1889. +
  1890. +    if (!cygwin_local_getent_passwd(name,
  1891. +        localname,
  1892. +        &localuid,
  1893. +        nfsowner,
  1894. +        &nfsuid)) {
  1895. +        DPRINTF(0,
  1896. +            ("nfs41_idmap_user_lookup_by_localid(search_localid=%ld): "
  1897. +            "Adding new user entry localname='%s', localuid=%ld, nfsowner='%s', nfsuid=%ld\n",
  1898. +            (long)search_localid,
  1899. +            localname,
  1900. +            (long)localuid,
  1901. +            nfsowner,
  1902. +            (long)nfsuid));
  1903. +
  1904. +        ie = idmapcache_add(context->usercache,
  1905. +            localname,
  1906. +            localuid,
  1907. +            nfsowner,
  1908. +            nfsuid);
  1909. +        if (ie == NULL) {
  1910. +            DPRINTF(0,
  1911. +                ("nfs41_idmap_user_lookup_by_localid(search_localid=%ld): idmapcache_add() failed\n",
  1912. +                (long)search_localid));
  1913. +        }
  1914. +        else {
  1915. +            status = ERROR_SUCCESS;
  1916. +        }
  1917. +    }
  1918. +
  1919. +out:
  1920. +    if (ie != NULL) {
  1921. +        DPRINTF(CYGWINIDLVL,
  1922. +            ("<-- nfs41_idmap_user_lookup_by_localid(search_localid=%ld): "
  1923. +            "returning status=%d / user ie(=0x%p)={ win32name='%s', localuid=%ld, nfsname='%s', nfsid=%ld\n",
  1924. +            (long)search_localid,
  1925. +            status,
  1926. +            (void *)ie,
  1927. +            ie->win32name.buf,
  1928. +            (long)ie->localid,
  1929. +            ie->nfsname.buf,
  1930. +            (long)ie->nfsid));
  1931. +    }
  1932. +    else {
  1933. +        DPRINTF(CYGWINIDLVL,
  1934. +            ("<-- nfs41_idmap_user_lookup_by_localid(search_localid=%ld): "
  1935. +            "returning status=%d / ie=NULL\n",
  1936. +            (long)search_localid,
  1937. +            status));
  1938. +    }
  1939. +
  1940. +    return ie;
  1941. +}
  1942. +
  1943. +idmapcache_entry *nfs41_idmap_user_lookup_by_nfsname(struct idmap_context *context,
  1944. +    const char *restrict name)
  1945. +{
  1946. +    int status = ERROR_NOT_FOUND;
  1947. +    idmapcache_entry *ie;
  1948. +
  1949. +    DPRINTF(CYGWINIDLVL,
  1950. +        ("--> nfs41_idmap_user_lookup_by_nfsname(name='%s')\n",
  1951. +        name));
  1952. +
  1953. +    ie = idmapcache_lookup_by_nfsname(context->usercache, name);
  1954. +    if (ie != NULL) {
  1955. +        status = ERROR_SUCCESS;
  1956. +        goto out;
  1957. +    }
  1958. +
  1959. +    char localname[256];
  1960. +    uid_t localuid;
  1961. +    char nfsowner[256];
  1962. +    uid_t nfsuid;
  1963. +
  1964. +    if (!cygwin_nfsserver_getent_passwd(name,
  1965. +        localname,
  1966. +        &localuid,
  1967. +        nfsowner,
  1968. +        &nfsuid)) {
  1969. +        DPRINTF(0,
  1970. +            ("nfs41_idmap_user_lookup_by_nfsname(name='%s'): "
  1971. +            "Adding new user entry localname='%s', localuid=%ld, nfsowner='%s', nfsuid=%ld\n",
  1972. +            name,
  1973. +            localname,
  1974. +            (long)localuid,
  1975. +            nfsowner,
  1976. +            (long)nfsuid));
  1977. +
  1978. +        ie = idmapcache_add(context->usercache,
  1979. +            localname,
  1980. +            localuid,
  1981. +            nfsowner,
  1982. +            nfsuid);
  1983. +        if (ie == NULL) {
  1984. +            DPRINTF(0,
  1985. +                ("nfs41_idmap_user_lookup_by_nfsname(name='%s'): idmapcache_add() failed\n",
  1986. +                name));
  1987. +        }
  1988. +        else {
  1989. +            status = ERROR_SUCCESS;
  1990. +        }
  1991. +    }
  1992. +
  1993. +out:
  1994. +    if (ie != NULL) {
  1995. +        DPRINTF(CYGWINIDLVL,
  1996. +            ("<-- nfs41_idmap_user_lookup_by_nfsname(name='%s'): "
  1997. +            "returning status=%d / user ie(=0x%p)={ win32name='%s', localuid=%ld, nfsname='%s', nfsid=%ld\n",
  1998. +            name,
  1999. +            status,
  2000. +            (void *)ie,
  2001. +            ie->win32name.buf,
  2002. +            (long)ie->localid,
  2003. +            ie->nfsname.buf,
  2004. +            (long)ie->nfsid));
  2005. +    }
  2006. +    else {
  2007. +        DPRINTF(CYGWINIDLVL,
  2008. +            ("<-- nfs41_idmap_user_lookup_by_nfsname(name='%s'): "
  2009. +            "returning status=%d / ie=NULL\n",
  2010. +            name,
  2011. +            status));
  2012. +    }
  2013. +
  2014. +    return ie;
  2015. +}
  2016. +
  2017. +idmapcache_entry *nfs41_idmap_user_lookup_by_nfsid(struct idmap_context *context,
  2018. +    idmapcache_idnumber search_nfsid)
  2019. +{
  2020. +    int status = ERROR_NOT_FOUND;
  2021. +    idmapcache_entry *ie;
  2022. +
  2023. +    DPRINTF(CYGWINIDLVL,
  2024. +        ("--> nfs41_idmap_user_lookup_by_nfsid(search_nfsid=%ld)\n",
  2025. +        (long)search_nfsid));
  2026. +
  2027. +    ie = idmapcache_lookup_by_nfsid(context->usercache, search_nfsid);
  2028. +    if (ie != NULL) {
  2029. +        status = ERROR_SUCCESS;
  2030. +        goto out;
  2031. +    }
  2032. +
  2033. +    char localname[256];
  2034. +    uid_t localuid;
  2035. +    char nfsowner[256];
  2036. +    uid_t nfsuid;
  2037. +    char name[64];
  2038. +    (void)sprintf(name, "%ld", (long)search_nfsid);
  2039. +
  2040. +    if (!cygwin_nfsserver_getent_passwd(name,
  2041. +        localname,
  2042. +        &localuid,
  2043. +        nfsowner,
  2044. +        &nfsuid)) {
  2045. +        DPRINTF(0,
  2046. +            ("nfs41_idmap_user_lookup_by_nfsid(search_nfsid=%ld): "
  2047. +            "Adding new user entry localname='%s', localuid=%ld, nfsowner='%s', nfsuid=%ld\n",
  2048. +            (long)search_nfsid,
  2049. +            localname,
  2050. +            (long)localuid,
  2051. +            nfsowner,
  2052. +            (long)nfsuid));
  2053. +
  2054. +        ie = idmapcache_add(context->usercache,
  2055. +            localname,
  2056. +            localuid,
  2057. +            nfsowner,
  2058. +            nfsuid);
  2059. +        if (ie == NULL) {
  2060. +            DPRINTF(0,
  2061. +                ("nfs41_idmap_user_lookup_by_nfsid(search_nfsid=%ld): idmapcache_add() failed\n",
  2062. +                (long)search_nfsid));
  2063. +        }
  2064. +        else {
  2065. +            status = ERROR_SUCCESS;
  2066. +        }
  2067. +    }
  2068. +
  2069. +out:
  2070. +    if (ie != NULL) {
  2071. +        DPRINTF(CYGWINIDLVL,
  2072. +            ("<-- nfs41_idmap_user_lookup_by_nfsid(search_nfsid=%ld): "
  2073. +            "returning status=%d / user ie(=0x%p)={ win32name='%s', localuid=%ld, nfsname='%s', nfsid=%ld\n",
  2074. +            (long)search_nfsid,
  2075. +            status,
  2076. +            (void *)ie,
  2077. +            ie->win32name.buf,
  2078. +            (long)ie->localid,
  2079. +            ie->nfsname.buf,
  2080. +            (long)ie->nfsid));
  2081. +    }
  2082. +    else {
  2083. +        DPRINTF(CYGWINIDLVL,
  2084. +            ("<-- nfs41_idmap_user_lookup_by_nfsid(search_nfsid=%ld): "
  2085. +            "returning status=%d / ie=NULL\n",
  2086. +            (long)search_nfsid,
  2087. +            status));
  2088. +    }
  2089. +
  2090. +    return ie;
  2091. +}
  2092. +
  2093. +
  2094. +/* ---- */
  2095. +
  2096. +idmapcache_entry *nfs41_idmap_group_lookup_by_win32name(struct idmap_context *context,
  2097. +    const char *restrict name)
  2098. +{
  2099. +    int status = ERROR_NOT_FOUND;
  2100. +    idmapcache_entry *ie;
  2101. +
  2102. +    DPRINTF(CYGWINIDLVL,
  2103. +        ("--> nfs41_idmap_group_lookup_by_win32name(name='%s')\n", name));
  2104. +
  2105. +    ie = idmapcache_lookup_by_win32name(context->groupcache, name);
  2106. +    if (ie != NULL) {
  2107. +        status = ERROR_SUCCESS;
  2108. +        goto out;
  2109. +    }
  2110. +
  2111. +    char localname[256];
  2112. +    gid_t localgid;
  2113. +    char nfsownergroup[256];
  2114. +    gid_t nfsgid;
  2115. +
  2116. +    if (!cygwin_local_getent_group(name,
  2117. +        localname,
  2118. +        &localgid,
  2119. +        nfsownergroup,
  2120. +        &nfsgid)) {
  2121. +        DPRINTF(0,
  2122. +            ("nfs41_idmap_group_lookup_by_win32name(name='%s'): "
  2123. +            "Adding new group entry localname='%s', localgid=%ld, nfsownergroup='%s', nfsgid=%ld\n",
  2124. +            name,
  2125. +            localname,
  2126. +            (long)localgid,
  2127. +            nfsownergroup,
  2128. +            (long)nfsgid));
  2129. +
  2130. +        ie = idmapcache_add(context->groupcache,
  2131. +            localname,
  2132. +            localgid,
  2133. +            nfsownergroup,
  2134. +            nfsgid);
  2135. +        if (ie == NULL) {
  2136. +            DPRINTF(0,
  2137. +                ("nfs41_idmap_group_lookup_by_win32name(name='%s'): idmapcache_add() failed\n", name));
  2138. +        }
  2139. +        else {
  2140. +            status = ERROR_SUCCESS;
  2141. +        }
  2142. +    }
  2143. +
  2144. +out:
  2145. +    if (ie != NULL) {
  2146. +        DPRINTF(CYGWINIDLVL,
  2147. +            ("<-- nfs41_idmap_group_lookup_by_win32name(name='%s'): "
  2148. +            "returning status=%d / user ie(=0x%p)={ win32name='%s', localgid=%ld, nfsname='%s', nfsid=%ld\n",
  2149. +            name,
  2150. +            status,
  2151. +            (void *)ie,
  2152. +            ie->win32name.buf,
  2153. +            (long)ie->localid,
  2154. +            ie->nfsname.buf,
  2155. +            (long)ie->nfsid));
  2156. +    }
  2157. +    else {
  2158. +        DPRINTF(CYGWINIDLVL,
  2159. +            ("<-- nfs41_idmap_group_lookup_by_win32name(name='%s'): "
  2160. +            "returning status=%d / ie=NULL\n",
  2161. +            name,
  2162. +            status));
  2163. +    }
  2164. +
  2165. +    return ie;
  2166. +}
  2167. +
  2168. +idmapcache_entry *nfs41_idmap_group_lookup_by_localid(struct idmap_context *context,
  2169. +    idmapcache_idnumber search_localid)
  2170. +{
  2171. +    int status = ERROR_NOT_FOUND;
  2172. +    idmapcache_entry *ie;
  2173. +
  2174. +    DPRINTF(CYGWINIDLVL,
  2175. +        ("--> nfs41_idmap_group_lookup_by_localid(search_localid=%ld)\n",
  2176. +        (long)search_localid));
  2177. +
  2178. +    ie = idmapcache_lookup_by_localid(context->groupcache, search_localid);
  2179. +    if (ie != NULL) {
  2180. +        status = ERROR_SUCCESS;
  2181. +        goto out;
  2182. +    }
  2183. +
  2184. +    char localname[256];
  2185. +    gid_t localgid;
  2186. +    char nfsownergroup[256];
  2187. +    gid_t nfsgid;
  2188. +    char name[64];
  2189. +    (void)sprintf(name, "%ld", (long)search_localid);
  2190. +
  2191. +    if (!cygwin_local_getent_group(name,
  2192. +        localname,
  2193. +        &localgid,
  2194. +        nfsownergroup,
  2195. +        &nfsgid)) {
  2196. +        DPRINTF(0,
  2197. +            ("nfs41_idmap_group_lookup_by_localid(search_localid=%ld): "
  2198. +            "Adding new group entry localname='%s', localgid=%ld, nfsownergroup='%s', nfsgid=%ld\n",
  2199. +            (long)search_localid,
  2200. +            localname,
  2201. +            (long)localgid,
  2202. +            nfsownergroup,
  2203. +            (long)nfsgid));
  2204. +
  2205. +        ie = idmapcache_add(context->groupcache,
  2206. +            localname,
  2207. +            localgid,
  2208. +            nfsownergroup,
  2209. +            nfsgid);
  2210. +        if (ie == NULL) {
  2211. +            DPRINTF(0,
  2212. +                ("nfs41_idmap_group_lookup_by_localid(search_localid=%ld): idmapcache_add() failed\n",
  2213. +                (long)search_localid));
  2214. +        }
  2215. +        else {
  2216. +            status = ERROR_SUCCESS;
  2217. +        }
  2218. +    }
  2219. +
  2220. +out:
  2221. +    if (ie != NULL) {
  2222. +        DPRINTF(CYGWINIDLVL,
  2223. +            ("<-- nfs41_idmap_group_lookup_by_localid(search_localid=%ld): "
  2224. +            "returning status=%d / user ie(=0x%p)={ win32name='%s', localgid=%ld, nfsname='%s', nfsid=%ld\n",
  2225. +            (long)search_localid,
  2226. +            status,
  2227. +            (void *)ie,
  2228. +            ie->win32name.buf,
  2229. +            (long)ie->localid,
  2230. +            ie->nfsname.buf,
  2231. +            (long)ie->nfsid));
  2232. +    }
  2233. +    else {
  2234. +        DPRINTF(CYGWINIDLVL,
  2235. +            ("<-- nfs41_idmap_group_lookup_by_localid(search_localid=%ld): "
  2236. +            "returning status=%d / ie=NULL\n",
  2237. +            (long)search_localid,
  2238. +            status));
  2239. +    }
  2240. +
  2241. +    return ie;
  2242. +}
  2243. +
  2244. +idmapcache_entry *nfs41_idmap_group_lookup_by_nfsname(struct idmap_context *context,
  2245. +    const char *restrict name)
  2246. +{
  2247. +    int status = ERROR_NOT_FOUND;
  2248. +    idmapcache_entry *ie;
  2249. +
  2250. +    DPRINTF(CYGWINIDLVL,
  2251. +        ("--> nfs41_idmap_group_lookup_by_nfsname(name='%s')\n",
  2252. +        name));
  2253. +
  2254. +    ie = idmapcache_lookup_by_nfsname(context->groupcache, name);
  2255. +    if (ie != NULL) {
  2256. +        status = ERROR_SUCCESS;
  2257. +        goto out;
  2258. +    }
  2259. +
  2260. +    char localname[256];
  2261. +    gid_t localgid;
  2262. +    char nfsownergroup[256];
  2263. +    gid_t nfsgid;
  2264. +
  2265. +    if (!cygwin_nfsserver_getent_group(name,
  2266. +        localname,
  2267. +        &localgid,
  2268. +        nfsownergroup,
  2269. +        &nfsgid)) {
  2270. +        DPRINTF(0,
  2271. +            ("nfs41_idmap_group_lookup_by_nfsname(name='%s'): "
  2272. +            "Adding new group entry localname='%s', localgid=%ld, nfsownergroup='%s', nfsgid=%ld\n",
  2273. +            name,
  2274. +            localname,
  2275. +            (long)localgid,
  2276. +            nfsownergroup,
  2277. +            (long)nfsgid));
  2278. +
  2279. +        ie = idmapcache_add(context->groupcache,
  2280. +            localname,
  2281. +            localgid,
  2282. +            nfsownergroup,
  2283. +            nfsgid);
  2284. +        if (ie == NULL) {
  2285. +            DPRINTF(0,
  2286. +                ("nfs41_idmap_group_lookup_by_nfsname(name='%s'): idmapcache_add() failed\n",
  2287. +                name));
  2288. +        }
  2289. +        else {
  2290. +            status = ERROR_SUCCESS;
  2291. +        }
  2292. +    }
  2293. +
  2294. +out:
  2295. +    if (ie != NULL) {
  2296. +        DPRINTF(CYGWINIDLVL,
  2297. +            ("<-- nfs41_idmap_group_lookup_by_nfsname(name='%s'): "
  2298. +            "returning status=%d / user ie(=0x%p)={ win32name='%s', localgid=%ld, nfsname='%s', nfsid=%ld\n",
  2299. +            name,
  2300. +            status,
  2301. +            (void *)ie,
  2302. +            ie->win32name.buf,
  2303. +            (long)ie->localid,
  2304. +            ie->nfsname.buf,
  2305. +            (long)ie->nfsid));
  2306. +    }
  2307. +    else {
  2308. +        DPRINTF(CYGWINIDLVL,
  2309. +            ("<-- nfs41_idmap_group_lookup_by_nfsname(name='%s'): "
  2310. +            "returning status=%d / ie=NULL\n",
  2311. +            name,
  2312. +            status));
  2313. +    }
  2314. +
  2315. +    return ie;
  2316. +}
  2317. +
  2318. +idmapcache_entry *nfs41_idmap_group_lookup_by_nfsid(struct idmap_context *context,
  2319. +    idmapcache_idnumber search_nfsid)
  2320. +{
  2321. +    int status = ERROR_NOT_FOUND;
  2322. +    idmapcache_entry *ie;
  2323. +
  2324. +    DPRINTF(CYGWINIDLVL,
  2325. +        ("--> nfs41_idmap_group_lookup_by_nfsid(search_nfsid=%ld)\n",
  2326. +        (long)search_nfsid));
  2327. +
  2328. +    ie = idmapcache_lookup_by_nfsid(context->groupcache, search_nfsid);
  2329. +    if (ie != NULL) {
  2330. +        status = ERROR_SUCCESS;
  2331. +        goto out;
  2332. +    }
  2333. +
  2334. +    char localname[256];
  2335. +    gid_t localgid;
  2336. +    char nfsownergroup[256];
  2337. +    gid_t nfsgid;
  2338. +    char name[64];
  2339. +    (void)sprintf(name, "%ld", (long)search_nfsid);
  2340. +
  2341. +    if (!cygwin_nfsserver_getent_group(name,
  2342. +        localname,
  2343. +        &localgid,
  2344. +        nfsownergroup,
  2345. +        &nfsgid)) {
  2346. +        DPRINTF(0,
  2347. +            ("nfs41_idmap_group_lookup_by_nfsid(search_nfsid=%ld): "
  2348. +            "Adding new group entry localname='%s', localgid=%ld, nfsownergroup='%s', nfsgid=%ld\n",
  2349. +            (long)search_nfsid,
  2350. +            localname,
  2351. +            (long)localgid,
  2352. +            nfsownergroup,
  2353. +            (long)nfsgid));
  2354. +
  2355. +        ie = idmapcache_add(context->groupcache,
  2356. +            localname,
  2357. +            localgid,
  2358. +            nfsownergroup,
  2359. +            nfsgid);
  2360. +        if (ie == NULL) {
  2361. +            DPRINTF(0,
  2362. +                ("nfs41_idmap_group_lookup_by_nfsid(search_nfsid=%ld): idmapcache_add() failed\n",
  2363. +                (long)search_nfsid));
  2364. +        }
  2365. +        else {
  2366. +            status = ERROR_SUCCESS;
  2367. +        }
  2368. +    }
  2369. +
  2370. +out:
  2371. +    if (ie != NULL) {
  2372. +        DPRINTF(CYGWINIDLVL,
  2373. +            ("<-- nfs41_idmap_group_lookup_by_nfsid(search_nfsid=%ld): "
  2374. +            "returning status=%d / user ie(=0x%p)={ win32name='%s', localgid=%ld, nfsname='%s', nfsid=%ld\n",
  2375. +            (long)search_nfsid,
  2376. +            status,
  2377. +            (void *)ie,
  2378. +            ie->win32name.buf,
  2379. +            (long)ie->localid,
  2380. +            ie->nfsname.buf,
  2381. +            (long)ie->nfsid));
  2382. +    }
  2383. +    else {
  2384. +        DPRINTF(CYGWINIDLVL,
  2385. +            ("<-- nfs41_idmap_group_lookup_by_nfsid(search_nfsid=%ld): "
  2386. +            "returning status=%d / ie=NULL\n",
  2387. +            (long)search_nfsid,
  2388. +            status));
  2389. +    }
  2390. +
  2391. +    return ie;
  2392. +}
  2393. diff --git a/daemon/nfs41_daemon.c b/daemon/nfs41_daemon.c
  2394. index dde0a71..055eb2c 100644
  2395. --- a/daemon/nfs41_daemon.c
  2396. +++ b/daemon/nfs41_daemon.c
  2397. @@ -82,6 +82,11 @@ static int map_current_user_to_ids(nfs41_idmapper *idmapper,
  2398.      char username[UTF8_PRINCIPALLEN+1];
  2399.      char pgroupname[UTF8_PRINCIPALLEN+1];
  2400.      int status = NO_ERROR;
  2401. +    idmapcache_entry *user_ie = NULL;
  2402. +    idmapcache_entry *group_ie = NULL;
  2403. +
  2404. +    /* fixme: This should be a function argument */
  2405. +    extern nfs41_daemon_globals nfs41_dg;
  2406.  
  2407.      if (!get_token_user_name(impersonation_tok, username)) {
  2408.          status = GetLastError();
  2409. @@ -97,35 +102,45 @@ static int map_current_user_to_ids(nfs41_idmapper *idmapper,
  2410.          goto out_map_default_ids;
  2411.      }
  2412.  
  2413. -    if (nfs41_idmap_name_to_uid(idmapper, username, puid)) {
  2414. -        /* instead of failing for auth_sys, fall back to 'nobody' uid/gid */
  2415. +    user_ie = nfs41_idmap_user_lookup_by_win32name(nfs41_dg.idmapper,
  2416. +        username);
  2417. +    group_ie = nfs41_idmap_group_lookup_by_win32name(nfs41_dg.idmapper,
  2418. +        pgroupname);
  2419. +
  2420. +    if (user_ie == NULL) {
  2421. +        /* instead of failing, fall back to 'nobody'/'nogroup' uid/gid */
  2422.          DPRINTF(1,
  2423.              ("map_current_user_to_ids: "
  2424. -                "nfs41_idmap_name_to_uid(username='%s') failed, "
  2425. -                "returning nobody/nogroup defaults\n",
  2426. +                "nfs41_idmap_user_lookup_by_nfsname(username='%s') failed, "
  2427. +                "returning 'nobody'/'nogroup' defaults\n",
  2428.                  username));
  2429.          status = NO_ERROR;
  2430.          goto out_map_default_ids;
  2431.      }
  2432.  
  2433. -    if (nfs41_idmap_group_to_gid(
  2434. -        idmapper,
  2435. -        pgroupname,
  2436. -        pgid)) {
  2437. +    if (group_ie == NULL) {
  2438. +        /* instead of failing, fall back to 'nobody'/'nogroup' uid/gid */
  2439.          DPRINTF(1,
  2440.              ("map_current_user_to_ids: "
  2441. -                "nfs41_idmap_group_to_gid(pgroupname='%s') failed, "
  2442. -                "returning nogroup\n",
  2443. +                "nfs41_idmap_group_lookup_by_nfsname(pgroupname='%s') failed, "
  2444. +                "returning 'nobody'/'nogroup' defaults\n",
  2445.                  pgroupname));
  2446. -        *pgid = nfs41_dg.default_gid;
  2447. +        status = NO_ERROR;
  2448. +        goto out_map_default_ids;
  2449.      }
  2450.  
  2451. +    *puid = user_ie->nfsid;
  2452. +    *pgid = group_ie->nfsid;
  2453.  out:
  2454.      DPRINTF(1,
  2455.          ("map_current_user_to_ids: "
  2456.              "mapping user=(name='%s' ==> uid=%d)/pgroup=(name='%s' ==> gid=%d)\n",
  2457.              username, (int)*puid,
  2458.              pgroupname, (int)*pgid));
  2459. +    if (user_ie != NULL)
  2460. +        idmapcache_entry_refcount_dec(user_ie);
  2461. +    if (group_ie != NULL)
  2462. +        idmapcache_entry_refcount_dec(group_ie);
  2463.      return status;
  2464.  
  2465.  out_map_default_ids:
  2466. diff --git a/daemon/open.c b/daemon/open.c
  2467. index a349b25..809ef0f 100644
  2468. --- a/daemon/open.c
  2469. +++ b/daemon/open.c
  2470. @@ -707,8 +707,7 @@ void open_get_localuidgid(IN nfs41_daemon_globals *restrict nfs41dg,
  2471.      int status = 0;
  2472.      char owner[NFS4_FATTR4_OWNER_LIMIT+1];
  2473.      char owner_group[NFS4_FATTR4_OWNER_LIMIT+1];
  2474. -    uid_t map_uid = ~0UL;
  2475. -    gid_t map_gid = ~0UL;
  2476. +    idmapcache_entry *ie;
  2477.  
  2478.  #if 1
  2479.      EASSERT(info->attrmask.count >= 2);
  2480. @@ -770,11 +769,11 @@ void open_get_localuidgid(IN nfs41_daemon_globals *restrict nfs41dg,
  2481.      EASSERT_MSG(IS_PRINCIPAL_NAME(owner),
  2482.          ("owner='%s' is not a principal\n", owner));
  2483.  
  2484. -    if (nfs41_idmap_name_to_uid(
  2485. -        nfs41dg->idmapper,
  2486. -        owner,
  2487. -        &map_uid) == 0) {
  2488. -         *owner_local_uid = map_uid;
  2489. +    ie = nfs41_idmap_user_lookup_by_nfsname(nfs41dg->idmapper,
  2490. +        owner);
  2491. +    if (ie != NULL) {
  2492. +         *owner_local_uid = ie->localid;
  2493. +        idmapcache_entry_refcount_dec(ie);
  2494.      }
  2495.      else {
  2496.          *owner_local_uid = NFS_USER_NOBODY_UID;
  2497. @@ -795,11 +794,11 @@ void open_get_localuidgid(IN nfs41_daemon_globals *restrict nfs41dg,
  2498.      EASSERT_MSG(IS_PRINCIPAL_NAME(owner_group),
  2499.          ("owner_group='%s' is not a principal\n", owner_group));
  2500.  
  2501. -    if (nfs41_idmap_group_to_gid(
  2502. -        nfs41dg->idmapper,
  2503. -        owner_group,
  2504. -        &map_gid) == 0) {
  2505. -        *owner_group_local_gid = map_gid;
  2506. +    ie = nfs41_idmap_group_lookup_by_nfsname(nfs41dg->idmapper,
  2507. +        owner_group);
  2508. +    if (ie != NULL) {
  2509. +        *owner_group_local_gid = ie->localid;
  2510. +        idmapcache_entry_refcount_dec(ie);
  2511.      }
  2512.      else {
  2513.          *owner_group_local_gid = NFS_GROUP_NOGROUP_GID;
  2514. diff --git a/daemon/sid.c b/daemon/sid.c
  2515. index 6b80cc6..f52bb9a 100644
  2516. --- a/daemon/sid.c
  2517. +++ b/daemon/sid.c
  2518. @@ -238,7 +238,6 @@ typedef struct _sidcache_entry
  2519.  {
  2520.  #define SIDCACHE_ENTRY_NAME_SIZE (UTF8_PRINCIPALLEN + 1)
  2521.      char    win32name[SIDCACHE_ENTRY_NAME_SIZE]; /* must fit something like "user@domain" */
  2522. -    char    aliasname[SIDCACHE_ENTRY_NAME_SIZE];
  2523.      PSID    sid;
  2524.      DWORD   sid_len;
  2525.  #pragma warning( push )
  2526. @@ -266,13 +265,8 @@ void sidcache_init(void)
  2527.      InitializeCriticalSection(&group_sidcache.lock);
  2528.  }
  2529.  
  2530. -void sidcache_add(sidcache *cache, const char* win32name, PSID value)
  2531. -{
  2532. -    sidcache_addwithalias(cache, win32name, NULL, value);
  2533. -}
  2534. -
  2535.  /* copy SID |value| into cache */
  2536. -void sidcache_addwithalias(sidcache *cache, const char *win32name, const char *aliasname, PSID value)
  2537. +void sidcache_add(sidcache *cache, const char *win32name, PSID value)
  2538.  {
  2539.      int i;
  2540.      ssize_t freeEntryIndex;
  2541. @@ -293,7 +287,6 @@ void sidcache_addwithalias(sidcache *cache, const char *win32name, const char *a
  2542.              ((currentTimestamp - e->timestamp) >= SIDCACHE_TTL)) {
  2543.              e->sid = NULL;
  2544.              e->win32name[0] = '\0';
  2545. -            e->aliasname[0] = '\0';
  2546.              e->sid_len = 0;
  2547.          }
  2548.      }
  2549. @@ -308,22 +301,6 @@ void sidcache_addwithalias(sidcache *cache, const char *win32name, const char *a
  2550.                  freeEntryIndex = i;
  2551.                  break;
  2552.              }
  2553. -            if (aliasname) {
  2554. -                if (!strcmp(e->win32name, aliasname)) {
  2555. -                    freeEntryIndex = i;
  2556. -                    break;
  2557. -                }
  2558. -                if ((e->aliasname[0] != '\0') &&
  2559. -                    (!strcmp(e->aliasname, aliasname))) {
  2560. -                    freeEntryIndex = i;
  2561. -                    break;
  2562. -                }
  2563. -            }
  2564. -            if ((e->aliasname[0] != '\0') &&
  2565. -                (!strcmp(e->aliasname, win32name))) {
  2566. -                freeEntryIndex = i;
  2567. -                break;
  2568. -            }
  2569.          }
  2570.          else {
  2571.              /* (cache->entries[i].sid == NULL) --> empty slot... */
  2572. @@ -346,17 +323,12 @@ void sidcache_addwithalias(sidcache *cache, const char *win32name, const char *a
  2573.      if (!CopySid(sid_len, e->sid, value)) {
  2574.          e->sid = NULL;
  2575.          e->win32name[0] = '\0';
  2576. -        e->aliasname[0] = '\0';
  2577.          e->sid_len = 0;
  2578.          goto done;
  2579.      }
  2580.  
  2581.      e->sid_len = sid_len;
  2582.      (void)strcpy(e->win32name, win32name);
  2583. -    if (aliasname)
  2584. -        (void)strcpy(e->aliasname, aliasname);
  2585. -    else
  2586. -        e->aliasname[0] = '\0';
  2587.      e->timestamp = currentTimestamp;
  2588.  
  2589.      cache->cacheIndex = (cache->cacheIndex + 1) % SIDCACHE_SIZE;
  2590. @@ -380,8 +352,7 @@ PSID *sidcache_getcached_byname(sidcache *cache, const char *win32name)
  2591.          e = &cache->entries[i];
  2592.  
  2593.          if ((e->sid != NULL) &&
  2594. -            ((!strcmp(e->win32name, win32name)) ||
  2595. -                ((e->aliasname[0] != '\0') && (!strcmp(e->aliasname, win32name)))) &&
  2596. +            (strcmp(e->win32name, win32name) == 0) &&
  2597.              ((currentTimestamp - e->timestamp) < SIDCACHE_TTL)) {
  2598.              PSID malloced_sid = malloc(e->sid_len);
  2599.              if (!malloced_sid)
  2600. @@ -434,15 +405,15 @@ done:
  2601.  
  2602.  int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *sid_len, PSID *sid, LPCSTR nfsname)
  2603.  {
  2604. -    const char *orig_nfsname = nfsname;
  2605. +    const char *win32name = NULL;
  2606.  
  2607.      int status = ERROR_INTERNAL_ERROR;
  2608.      SID_NAME_USE sid_type = 0;
  2609. -    char nfsname_buff[UTF8_PRINCIPALLEN+1];
  2610.  #ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  2611.      signed long user_uid = -1;
  2612.      signed long group_gid = -1;
  2613.  #endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  2614. +    idmapcache_entry *nfs_ie = NULL;
  2615.  
  2616.      DPRINTF(ACLLVL,
  2617.          ("--> map_nfs4servername_2_sid(query=0x%x,nfsname='%s')\n",
  2618. @@ -451,64 +422,56 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
  2619.      EASSERT_MSG(IS_PRINCIPAL_NAME(nfsname),
  2620.          ("nfsname='%s' is not a principal\n", nfsname));
  2621.  
  2622. +
  2623. +    if ((nfs_ie == NULL) && (query & OWNER_SECURITY_INFORMATION)) {
  2624. +        nfs_ie = nfs41_idmap_user_lookup_by_nfsname(nfs41dg->idmapper,
  2625. +            nfsname);
  2626. +    }
  2627. +    if ((nfs_ie == NULL) && (query & GROUP_SECURITY_INFORMATION)) {
  2628. +        nfs_ie = nfs41_idmap_group_lookup_by_nfsname(nfs41dg->idmapper,
  2629. +            nfsname);
  2630. +    }
  2631. +
  2632. +    if (nfs_ie == NULL) {
  2633. +        DPRINTF(0,
  2634. +            ("map_nfs4servername_2_sid(nfsname='%s'): "
  2635. +            "nfs41_idmap_group_lookup_by_nfsname() failed\n",
  2636. +            nfsname));
  2637. +        status = ERROR_NOT_FOUND;
  2638. +        goto out;
  2639. +    }
  2640. +    win32name = nfs_ie->win32name.buf;
  2641. +
  2642.  #ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  2643. -    /* use our own idmapper script to map nfsv4 owner string to local Windows account */
  2644.      if (query & OWNER_SECURITY_INFORMATION) {
  2645. -        uid_t udummy = ~0UL;
  2646. -
  2647.  #ifdef NFS41_DRIVER_SID_CACHE
  2648. -        *sid = sidcache_getcached_byname(&user_sidcache, nfsname);
  2649. +        *sid = sidcache_getcached_byname(&user_sidcache, win32name);
  2650.          if (*sid) {
  2651.              *sid_len = GetLengthSid(*sid);
  2652. -            DPRINTF(1, ("map_nfs4servername_2_sid: returning cached sid for user '%s'\n", nfsname));
  2653. +            DPRINTF(1,
  2654. +                ("map_nfs4servername_2_sid: returning cached user sid for win32name='%s'\n",
  2655. +                win32name));
  2656.              status = 0;
  2657.              goto out;
  2658.          }
  2659.  #endif /* NFS41_DRIVER_SID_CACHE */
  2660. -
  2661. -#ifndef NFS41_DRIVER_SID_CACHE
  2662. -        /* gisburn: fixme: We must cache this, or the performance impact will be devastating!! */
  2663. -#endif /* !NFS41_DRIVER_SID_CACHE */
  2664. -        if (!cygwin_getent_passwd(nfsname, nfsname_buff, &udummy, NULL, NULL)) {
  2665. -            if (strcmp(nfsname, nfsname_buff)) {
  2666. -                DPRINTF(1,
  2667. -                    ("map_nfs4servername_2_sid: remap user '%s' --> '%s'\n",
  2668. -                    nfsname,
  2669. -                    nfsname_buff));
  2670. -                nfsname = nfsname_buff;
  2671. -            }
  2672. -        }
  2673.      }
  2674.  #endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  2675.  
  2676.  
  2677.  #ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  2678. -    /* use our own idmapper script to map nfsv4 owner string to local Windows account */
  2679.      if (query & GROUP_SECURITY_INFORMATION) {
  2680. -        gid_t gdummy = ~0UL;
  2681. -
  2682.  #ifdef NFS41_DRIVER_SID_CACHE
  2683. -        *sid = sidcache_getcached_byname(&group_sidcache, nfsname);
  2684. +        *sid = sidcache_getcached_byname(&group_sidcache, win32name);
  2685.          if (*sid) {
  2686.              *sid_len = GetLengthSid(*sid);
  2687. -            DPRINTF(1, ("map_nfs4servername_2_sid: returning cached sid for group '%s'\n", nfsname));
  2688. +            DPRINTF(1,
  2689. +                ("map_nfs4servername_2_sid: returning cached group sid for win32name='%s'\n",
  2690. +                win32name));
  2691.              status = 0;
  2692.              goto out;
  2693.          }
  2694.  #endif /* NFS41_DRIVER_SID_CACHE */
  2695. -
  2696. -#ifndef NFS41_DRIVER_SID_CACHE
  2697. -        /* gisburn: fixme: We must cache this, or the performance impact will be devastating!! */
  2698. -#endif /* !NFS41_DRIVER_SID_CACHE */
  2699. -        if (!cygwin_getent_group(nfsname, nfsname_buff, &gdummy, NULL, NULL)) {
  2700. -            if (strcmp(nfsname, nfsname_buff)) {
  2701. -                DPRINTF(1,
  2702. -                    ("map_nfs4servername_2_sid: remap group '%s' --> '%s'\n",
  2703. -                    nfsname,
  2704. -                    nfsname_buff));
  2705. -                nfsname = nfsname_buff;
  2706. -            }
  2707. -        }
  2708.      }
  2709.  #endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  2710.  
  2711. @@ -519,17 +482,17 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
  2712.      }
  2713.      *sid_len = MAX_SID_BUFFER_SIZE;
  2714.  
  2715. -    status = lookupprincipalnameutf8(NULL, nfsname, *sid, sid_len,
  2716. +    status = lookupprincipalnameutf8(NULL, win32name, *sid, sid_len,
  2717.          &sid_type);
  2718.  
  2719.      if (status) {
  2720.          /* |lookupprincipalnameutf8()| success */
  2721.  
  2722.          DPRINTF(ACLLVL,
  2723. -            ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2724. +            ("map_nfs4servername_2_sid(query=0x%x,win32name='%s'): "
  2725.              "lookupprincipalnameutf8() returned status=%d "
  2726.              "GetLastError=%d *sid_len=%d\n",
  2727. -            query, nfsname, status, GetLastError(), *sid_len));
  2728. +            query, win32name, status, (int)GetLastError(), *sid_len));
  2729.  
  2730.          status = 0;
  2731.          *sid_len = GetLengthSid(*sid);
  2732. @@ -538,10 +501,10 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
  2733.  
  2734.      /* |lookupprincipalnameutf8()| failed... */
  2735.      DPRINTF(ACLLVL,
  2736. -        ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2737. +        ("map_nfs4servername_2_sid(query=0x%x,win32name='%s'): "
  2738.          "lookupprincipalnameutf8() returned status=%d "
  2739.          "GetLastError=%d\n",
  2740. -        query, nfsname, status, GetLastError()));
  2741. +        query, win32name, status, (int)GetLastError()));
  2742.  
  2743.      status = GetLastError();
  2744.      switch(status) {
  2745. @@ -550,9 +513,9 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
  2746.           * This should never happen, as |MAX_SID_BUFFER_SIZE| should be
  2747.           * larger than the largest possible SID buffer size for Windows
  2748.           */
  2749. -        eprintf("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2750. +        eprintf("map_nfs4servername_2_sid(query=0x%x,win32name='%s'): "
  2751.                  "lookupprincipalnameutf8() failed with "
  2752. -                "ERROR_INSUFFICIENT_BUFFER\n", query, nfsname);
  2753. +                "ERROR_INSUFFICIENT_BUFFER\n", query, win32name);
  2754.  
  2755.          status = ERROR_INTERNAL_ERROR;
  2756.          goto out;
  2757. @@ -560,50 +523,25 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
  2758.      case ERROR_NONE_MAPPED:
  2759.  #ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  2760.          DPRINTF(1,
  2761. -            ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2762. +            ("map_nfs4servername_2_sid(query=0x%x,win32name='%s'): "
  2763.              "none mapped, "
  2764.              "trying Unix_User+/Unix_Group+ mapping\n",
  2765. -            query, nfsname));
  2766. +            query, win32name));
  2767.  
  2768.          if ((user_uid == -1) && (query & OWNER_SECURITY_INFORMATION)) {
  2769. -            uid_t map_uid = ~0UL;
  2770. -
  2771. -            if (nfs41_idmap_name_to_uid(nfs41dg->idmapper,
  2772. -                nfsname, &map_uid) == 0) {
  2773. -                user_uid = map_uid;
  2774. -            }
  2775. -            else {
  2776. -                DPRINTF(0,
  2777. -                    ("map_nfs4servername_2_sid(query=0x%x,name='%s'): "
  2778. -                    "nfs41_idmap_name_to_uid() failed\n",
  2779. -                    query, nfsname));
  2780. -                /* fixme: try harder here, "1234" should to to |atol()| */
  2781. -            }
  2782. +           user_uid = nfs_ie->localid;
  2783.          }
  2784.  
  2785.          if ((group_gid == -1) && (query & GROUP_SECURITY_INFORMATION)) {
  2786. -            gid_t map_gid = ~0UL;
  2787. -
  2788. -            if (nfs41_idmap_group_to_gid(
  2789. -                nfs41dg->idmapper,
  2790. -                nfsname,
  2791. -                &map_gid) == 0) {
  2792. -                group_gid = map_gid;
  2793. -            }
  2794. -            else {
  2795. -                DPRINTF(0,
  2796. -                    ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): nfs41_idmap_group_to_gid() failed\n",
  2797. -                    query, nfsname));
  2798. -                /* fixme: try harder here, "1234" should to to |atol()| */
  2799. -            }
  2800. +           user_uid = nfs_ie->localid;
  2801.          }
  2802.  
  2803.          if (user_uid != -1) {
  2804.              if (allocate_unixuser_sid(user_uid, sid)) {
  2805.                  DPRINTF(ACLLVL,
  2806. -                    ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2807. +                    ("map_nfs4servername_2_sid(query=0x%x,win32name='%s'): "
  2808.                      "allocate_unixuser_sid(uid=%ld) success\n",
  2809. -                    query, nfsname, user_uid));
  2810. +                    query, win32name, user_uid));
  2811.                  status = ERROR_SUCCESS;
  2812.                  sid_type = SidTypeUser;
  2813.                  goto out_cache;
  2814. @@ -611,18 +549,18 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
  2815.  
  2816.              status = GetLastError();
  2817.              DPRINTF(ACLLVL,
  2818. -                ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2819. +                ("map_nfs4servername_2_sid(query=0x%x,win32name='%s'): "
  2820.                  "allocate_unixuser_sid(uid=%ld) failed, error=%d\n",
  2821. -                query, nfsname, user_uid, status));
  2822. +                query, win32name, user_uid, status));
  2823.              goto out;
  2824.          }
  2825.  
  2826.          if (group_gid != -1) {
  2827.              if (allocate_unixgroup_sid(group_gid, sid)) {
  2828.                  DPRINTF(ACLLVL,
  2829. -                    ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2830. +                    ("map_nfs4servername_2_sid(query=0x%x,win32name='%s'): "
  2831.                      "allocate_unixgroup_sid(gid=%ld) success\n",
  2832. -                    query, nfsname, group_gid));
  2833. +                    query, win32name, group_gid));
  2834.                  status = ERROR_SUCCESS;
  2835.                  sid_type = SidTypeGroup;
  2836.                  goto out_cache;
  2837. @@ -630,17 +568,17 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
  2838.  
  2839.              status = GetLastError();
  2840.              DPRINTF(ACLLVL,
  2841. -                ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2842. +                ("map_nfs4servername_2_sid(query=0x%x,win32name='%s'): "
  2843.                  "allocate_unixgroup_sid(gid=%ld) failed, error=%d\n",
  2844. -                query, nfsname, group_gid, status));
  2845. +                query, win32name, group_gid, status));
  2846.              goto out;
  2847.          }
  2848.  #endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  2849.  
  2850.          DPRINTF(1,
  2851. -            ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): none mapped, "
  2852. +            ("map_nfs4servername_2_sid(query=0x%x,win32name='%s'): none mapped, "
  2853.              "using WinNullSid mapping\n",
  2854. -            query, nfsname));
  2855. +            query, win32name));
  2856.  
  2857.          status = create_unknownsid(WinNullSid, sid, sid_len);
  2858.          if (status)
  2859. @@ -648,8 +586,8 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
  2860.          break;
  2861.      default:
  2862.          DPRINTF(1,
  2863. -            ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): error %d not handled\n",
  2864. -            query, nfsname, GetLastError()));
  2865. +            ("map_nfs4servername_2_sid(query=0x%x,win32name='%s'): error=%d not handled\n",
  2866. +            query, win32name, (int)GetLastError()));
  2867.          break;
  2868.      }
  2869.  out_cache:
  2870. @@ -668,54 +606,36 @@ out_cache:
  2871.               * - https://stackoverflow.com/questions/39373188/lookupaccountnamew-returns-sidtypealias-but-expected-sidtypegroup
  2872.               */
  2873.              DPRINTF(1,
  2874. -                ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2875. +                ("map_nfs4servername_2_sid(query=0x%x,win32name='%s'): "
  2876.                  "SID_TYPE='SidTypeAlias' mapped to 'SidTypeGroup'\n",
  2877. -                query, orig_nfsname));
  2878. +                query, win32name));
  2879.              sid_type = SidTypeGroup;
  2880.          }
  2881. -
  2882. +#if 0
  2883.  #ifdef NFS41_DRIVER_WS2022_HACKS
  2884.          if ((query & OWNER_SECURITY_INFORMATION) &&
  2885.              (sid_type == SidTypeWellKnownGroup)) {
  2886.              if (!strcmp(orig_nfsname, "SYSTEM")) {
  2887.                  DPRINTF(1,
  2888. -                    ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2889. +                    ("map_nfs4servername_2_sid(query=0x%x,win32name='%s'): "
  2890.                      "SID_TYPE='SidTypeWellKnownGroup' mapped to 'SidTypeUser' for user\n",
  2891.                      query, orig_nfsname));
  2892.                  sid_type = SidTypeUser;
  2893.              }
  2894.          }
  2895.  #endif /* NFS41_DRIVER_WS2022_HACKS */
  2896. -
  2897. +#endif
  2898.          switch (sid_type) {
  2899.              case SidTypeUser:
  2900. -                if (isdigit(orig_nfsname[0])) {
  2901. -                    DPRINTF(1,
  2902. -                        ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2903. -                        "adding usercache nfsname='%s' orig_nfsname='%s'\n",
  2904. -                        query, orig_nfsname, nfsname, orig_nfsname));
  2905. -                    sidcache_addwithalias(&user_sidcache, nfsname, orig_nfsname, *sid);
  2906. -                }
  2907. -                else {
  2908. -                    sidcache_add(&user_sidcache, orig_nfsname, *sid);
  2909. -                }
  2910. +                sidcache_add(&user_sidcache, win32name, *sid);
  2911.                  break;
  2912.              case SidTypeGroup:
  2913. -                if (isdigit(orig_nfsname[0])) {
  2914. -                    DPRINTF(1,
  2915. -                        ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2916. -                        "adding groupcache nfsname='%s' orig_nfsname='%s'\n",
  2917. -                        query, orig_nfsname, nfsname, orig_nfsname));
  2918. -                    sidcache_addwithalias(&group_sidcache, nfsname, orig_nfsname, *sid);
  2919. -                }
  2920. -                else {
  2921. -                    sidcache_add(&group_sidcache, orig_nfsname, *sid);
  2922. -                }
  2923. +                sidcache_add(&group_sidcache, win32name, *sid);
  2924.                  break;
  2925.              default:
  2926. -                eprintf("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2927. +                eprintf("map_nfs4servername_2_sid(query=0x%x,win32name='%s'): "
  2928.                      "Unknown SID_TYPE=%d\n",
  2929. -                    query, orig_nfsname, sid_type);
  2930. +                    query, win32name, sid_type);
  2931.                  break;
  2932.          }
  2933.      }
  2934. @@ -724,8 +644,8 @@ out_cache:
  2935.  out:
  2936.      if (DPRINTF_LEVEL_ENABLED(ACLLVL)) {
  2937.          if (status) {
  2938. -            dprintf_out("<-- map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2939. -                "status=%d\n", query, nfsname, status);
  2940. +            dprintf_out("<-- map_nfs4servername_2_sid(query=0x%x,win32name='%s'): "
  2941. +                "status=%d\n", query, win32name, status);
  2942.          }
  2943.          else {
  2944.              PSTR sidstr = NULL;
  2945. @@ -738,15 +658,18 @@ out:
  2946.                  sidstr = errsidstrbuf;
  2947.              }
  2948.  
  2949. -            dprintf_out("<-- map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  2950. +            dprintf_out("<-- map_nfs4servername_2_sid(query=0x%x,win32name='%s'): "
  2951.                  "status=%d sidstr='%s' *sid_len=%d\n",
  2952. -                query, nfsname, status, sidstr, *sid_len);
  2953. +                query, win32name, status, sidstr, *sid_len);
  2954.  
  2955.              if (sidstr && (sidstr != errsidstrbuf))
  2956.                  LocalFree(sidstr);
  2957.          }
  2958.      }
  2959.  
  2960. +    if (nfs_ie)
  2961. +        idmapcache_entry_refcount_dec(nfs_ie);
  2962. +
  2963.      return status;
  2964.  
  2965.  out_free_sid:
  2966. diff --git a/daemon/sid.h b/daemon/sid.h
  2967. index 572967b..17d5f33 100644
  2968. --- a/daemon/sid.h
  2969. +++ b/daemon/sid.h
  2970. @@ -76,7 +76,6 @@ bool unixgroup_sid2gid(PSID psid, gid_t *pgid);
  2971.  #endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  2972.  void sidcache_init(void);
  2973.  void sidcache_add(sidcache *cache, const char* win32name, PSID value);
  2974. -void sidcache_addwithalias(sidcache *cache, const char *win32name, const char *aliasname, PSID value);
  2975.  PSID *sidcache_getcached_byname(sidcache *cache, const char *win32name);
  2976.  bool sidcache_getcached_bysid(sidcache *cache, PSID sid, char *out_win32name);
  2977.  
  2978. diff --git a/daemon/util.c b/daemon/util.c
  2979. index 0610651..f54f407 100644
  2980. --- a/daemon/util.c
  2981. +++ b/daemon/util.c
  2982. @@ -869,6 +869,8 @@ int chgrp_to_primarygroup(
  2983.      IN nfs41_open_state *state)
  2984.  {
  2985.      int chgrp_status = NO_ERROR;
  2986. +    idmapcache_entry *group_ie = NULL;
  2987. +    char win32groupname[256];
  2988.  
  2989.      /*
  2990.       * |RPCSEC_AUTH_NONE| does not have any
  2991. @@ -879,42 +881,43 @@ int chgrp_to_primarygroup(
  2992.          return NO_ERROR;
  2993.      }
  2994.  
  2995. -    char *s;
  2996. -    stateid_arg stateid;
  2997. -    nfs41_file_info createchgrpattrs = {
  2998. -        .attrmask.count = 2,
  2999. -        .attrmask.arr[0] = 0,
  3000. -        .attrmask.arr[1] = FATTR4_WORD1_OWNER_GROUP,
  3001. -        .owner_group = createchgrpattrs.owner_group_buf
  3002. -    };
  3003. -
  3004.      /* fixme: we should store the |owner_group| name in |upcall| */
  3005.      if (!get_token_primarygroup_name(currentthread_token,
  3006. -        createchgrpattrs.owner_group)) {
  3007. +        win32groupname)) {
  3008.          eprintf("chgrp_to_primarygroup(state->file.name.name='%s'): "
  3009.              "get_token_primarygroup_name() failed.\n",
  3010.              state->file.name.name);
  3011. -        goto create_symlink_chgrp_out;
  3012. +        goto out;
  3013.      }
  3014.  
  3015. -    /*
  3016. -     * Find '@' so we can overwrite/override the domain name
  3017. -     * FIXME: We need to use a bi-directional idmapper to handle this better
  3018. -     */
  3019. -    s = strchr(createchgrpattrs.owner_group, '@');
  3020. -    if (s != NULL) {
  3021. -        s++; /* Skip '@' */
  3022. -    }
  3023. -    else {
  3024. -        /* If we do not have an '@' yet (no domain name), then add one */
  3025. -        s = createchgrpattrs.owner_group+strlen(createchgrpattrs.owner_group);
  3026. -        s = stpcpy(s, "@");
  3027. +    EASSERT_MSG(IS_PRINCIPAL_NAME(win32groupname),
  3028. +        ("chgrp_to_primarygroup: win32groupname='%s' is not a principal\n",
  3029. +        win32groupname));
  3030. +
  3031. +    group_ie = nfs41_idmap_group_lookup_by_win32name(nfs41dg->idmapper,
  3032. +        win32groupname);
  3033. +    if (group_ie == NULL) {
  3034. +        eprintf("chgrp_to_primarygroup(state->file.name.name='%s'): "
  3035. +            "nfs41_idmap_group_lookup_by_win32name(name='%s') failed\n",
  3036. +            state->file.name.name,
  3037. +            win32groupname);
  3038. +        goto out;
  3039.      }
  3040. -    (void)stpcpy(s, nfs41dg->localdomain_name);
  3041. -    DPRINTF(1, ("chgrp_to_primarygroup(state->file.name.name='%s'): "
  3042. +
  3043. +    DPRINTF(1,
  3044. +        ("chgrp_to_primarygroup(state->file.name.name='%s'): "
  3045.          "owner_group='%s'\n",
  3046.          state->file.name.name,
  3047. -        createchgrpattrs.owner_group));
  3048. +        group_ie->nfsname.buf));
  3049. +
  3050. +    stateid_arg stateid;
  3051. +    nfs41_file_info createchgrpattrs = {
  3052. +        .attrmask.count = 2,
  3053. +        .attrmask.arr[0] = 0,
  3054. +        .attrmask.arr[1] = FATTR4_WORD1_OWNER_GROUP,
  3055. +        .owner_group = createchgrpattrs.owner_group_buf
  3056. +    };
  3057. +    (void)strcpy(createchgrpattrs.owner_group, group_ie->nfsname.buf);
  3058.  
  3059.      nfs41_open_stateid_arg(state, &stateid);
  3060.      chgrp_status = nfs41_setattr(state->session,
  3061. @@ -924,12 +927,13 @@ int chgrp_to_primarygroup(
  3062.              "nfs41_setattr(owner_group='%s') "
  3063.              "failed with error '%s'.\n",
  3064.              state->file.name.name,
  3065. -            createchgrpattrs.owner_group,
  3066. +            group_ie->nfsname.buf,
  3067.              nfs_error_string(chgrp_status));
  3068.      }
  3069.  
  3070. -create_symlink_chgrp_out:
  3071. -    ;
  3072. +out:
  3073. +    if (group_ie != NULL)
  3074. +        idmapcache_entry_refcount_dec(group_ie);
  3075.  
  3076.      return chgrp_status;
  3077.  }

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