When map_username() is called - two times consecutively with the same search key - and a hit was found in the username map file - and this hit doesn't abort the search early by using the !-syntax - and the hitting entry is not the last one in the map file it is likely that the second (and possibly further calls with the same key) will not get properly mapped. This is due to the fact that the search loop indeed stores the proper results in its cache but this will get overwritten when it exists in order to provide some form of negative caching. The solution is to do this negative caching only if the search fails: --- source3/auth/user_util.c.ORI 2012-07-30 19:13:16.000000000 +0200 +++ source3/auth/user_util.c 2012-09-05 12:07:18.000000000 +0200 @@ -429,8 +430,13 @@ * that we don't scan the file again for the same user. */ + /* Do this only if mapping failed. Otherwise we will fuck up the + * already cached successful mapping. + */ + if( ! mapped_user ) { set_last_from_to(user_in, user_in); store_map_in_gencache(ctx, user_in, user_in); + } return mapped_user; }
How can I reproduce this? For me everything works just fine without the patch.
samba-3.6.9, source3/auth/user_util.c: Line 361, first invokation with user "xxx", scanning map file begins: DEBUG(4,("Scanning username map %s\n",mapfile)); while((s=fgets_slash(buf,sizeof(buf),f))!=NULL) { Line 400, a hit is found ("xxx" maps to "yyy"), username mapping (user_in and unixname) are stored properly ("xxx" and "yyy") in the cache, and mapped user is copied to p_user_out ("yyy"): if (strchr_m(dosname,'*') || user_in_list(ctx, user_in, (const char **)dosuserlist)) { DEBUG(3,("Mapped user %s to %s\n",user_in,unixname)); mapped_user = True; set_last_from_to(user_in, unixname); store_map_in_gencache(ctx, user_in, unixname); TALLOC_FREE(*p_user_out); *p_user_out = talloc_strdup(ctx, unixname); if (!*p_user_out) { TALLOC_FREE(dosuserlist); x_fclose(f); return false; } Line 415, we DO NOT EXIT but continue searching (otherwise we would leave here and all would be well): if ( return_if_mapped ) { TALLOC_FREE(dosuserlist); x_fclose(f); return True; } Line 423, loop terminates, cache is filled with user_in (xxx) two times. This means: If the _NEXT_ invokation of map_username() is done with "xxx" it will terminate with a negative hit from cache (since the cache lists wrongly "xxx" would map to "xxx"). But _THIS_ invokation will return properly since the mapped user ("yyy") has already been copied to p_user_out and mapped_user is True: } x_fclose(f); /* * Setup the last_from and last_to as an optimization so * that we don't scan the file again for the same user. */ set_last_from_to(user_in, user_in); store_map_in_gencache(ctx, user_in, user_in);
May I have a question how this bug relates to bug 8881 ? If any relationship is here?
Reproducer: Join the machine to an AD. Create a user in AD and create a local unix user, here 'bob'. mkdir /srv/samba/guru/bob chown bob: /srv/samba/guru/bob Add to smb.conf: [guru] path = /srv/samba/guru writeable = yes echo "bob = DOMAIN+user" > /etc/samba/ntusers Add to global section in smb.conf username map = /etc/samba/ntusers Login as DOMAIN+user and connect with smbclient -k //mymachine.domain.site/guru
I think bug #8881 is a duplicate.
Created attachment 8745 [details] v4-0-test patch
Created attachment 8746 [details] v3-6-test patch
*** Bug 8881 has been marked as a duplicate of this bug. ***
Karolin, please add to 4.0.x and 3.6.x. Thanks!
This patch fixed my issues from bug 8881. Thank you for your work on this!
Pushed to v3-6-test and autobuild-v4-0-test.
Pushed to v4-0-test. Closing out bug report. Thanks!