Peter Eriksson
2020-May-25 21:36 UTC
[Samba] Question about smbc_stat() and smbc_statvfs() in libsmbclient
I?ve been writing some code that uses libsmbclient to talk to SMB servers and I?m a little bit confused why ?smbc_stat()? sets the st_uid & st_gid to the uid & gid of the process calling it, instead of trying to map the real owner & group of the path or setting it to -1:-1 if it can?t do that... But there is probably some good reason for this? Ie, if I call something like this:> main() { > struct stat sb; > ?(connect to share etc) > smbc_stat(?smb://user at server/share/dir <smb://user at server/share/dir>?, &sb); > printf(?uid = %d, gid = %d\n?, sb.st_uid, sb.st_gid); > }Then my local uid&gid will be printed and not the owner of ?dir? (not even the user I?m connecting as). I can get the real owner & group via:> const char *owner_attr = "system.nt_sec_desc.owner+"; > const char *group_attr = "system.nt_sec_desc.group+"; > char buf[256]; > > smbc_getxattr(path, owner_attr, buf, sizeof(buf)): > printf("Owner='%s'\n", path, buf); > smbc_getxattr(path, group_attr, buf, sizeof(buf)) < 0) > printf(?Group=%s\n?, buf);(And then manually translating the username & group in but to an uid/gid - so I can work around it but it?s annoying anyway :-) Also, the smbc_statvfs() function assigns the ?f_frsize? to some silly value (2 for me) instead of a more realistic value. I?m assuming this is because that value never is sent over the ?wire?? - Peter
Jeremy Allison
2020-May-27 14:18 UTC
[Samba] Question about smbc_stat() and smbc_statvfs() in libsmbclient
On Mon, May 25, 2020 at 11:36:18PM +0200, Peter Eriksson via samba wrote:> I?ve been writing some code that uses libsmbclient to talk to SMB servers > and I?m a little bit confused why ?smbc_stat()? sets the > st_uid & st_gid to the uid & gid of the process calling it, > instead of trying to map the real owner & group of the path or setting it to -1:-1 if it can?t do that... > > But there is probably some good reason for this?That's really old code that was designed to talk to SMB1 servers that might predate real identity. This is a thornier problem than it looks. smbc_stat() does one network call to get the file info. For SMB2+ in order to convert the owner information (which is in SID form) to a uid/gid that has any meaning to the local filesystem you have to do extra network calls/mapping, as you describe below.> Ie, if I call something like this: > > > main() { > > struct stat sb; > > ?(connect to share etc) > > smbc_stat(?smb://user at server/share/dir <smb://user at server/share/dir>?, &sb); > > printf(?uid = %d, gid = %d\n?, sb.st_uid, sb.st_gid); > > } > > Then my local uid&gid will be printed and not the owner of ?dir? (not even the user I?m connecting as). > > > I can get the real owner & group via: > > > const char *owner_attr = "system.nt_sec_desc.owner+"; > > const char *group_attr = "system.nt_sec_desc.group+"; > > char buf[256]; > > > > smbc_getxattr(path, owner_attr, buf, sizeof(buf)): > > printf("Owner='%s'\n", path, buf); > > smbc_getxattr(path, group_attr, buf, sizeof(buf)) < 0) > > printf(?Group=%s\n?, buf); > > (And then manually translating the username & group in but to an uid/gid - so I can work around it but it?s annoying anyway :-)So that's doing a set of network RPC's to look up the SIDs from the server to get names. If you think about this, there's no guarantee that the remote names on the server have meaning on the local system - that's why SIDs have a global namespace. But there's no way to squeeze a SID into a uid/gid without a pre-defined lossy mapping.
Peter Eriksson
2020-May-28 08:43 UTC
[Samba] Question about smbc_stat() and smbc_statvfs() in libsmbclient
Re: the smbc_stat() returning wrong st_uid/st_gid: Yeah, I get why it?s difficult, but perhaps it should just return -1/-1 instead? It too is wrong but probably less confusing than seeing the local user?s uid/gid there?? Anyway, I?ve been working on a ?grand unifying :-)? ACL managing (CLI) tool since I got tired of all the different and quite frankly confusing/frustrating tools to manage ACL currently available. So I can now use the same command on all platforms. It current builds and works for Linux, FreeBSD, Solaris & MacOS and I?ve also recently added SMB support to it (via libsmbclient, currently requires Kerberos. I?ve been using smbc_getxattr() and smbc_setxattr() for reading and writing SMB ACLs, but there are some problems with that so I?ve started wondering if perhaps there is some better way I _should_ use instead? Something that doesn?t gets in the way and re-orders ACLs under my feet for example... ( Problems with ACLs being reordered: https://bugzilla.samba.org/show_bug.cgi?id=14397 ) My tool: https://github.com/ptrrkssn/acltool - Peter> On 27 May 2020, at 16:18, Jeremy Allison <jra at samba.org> wrote: > > On Mon, May 25, 2020 at 11:36:18PM +0200, Peter Eriksson via samba wrote: >> I?ve been writing some code that uses libsmbclient to talk to SMB servers >> and I?m a little bit confused why ?smbc_stat()? sets the >> st_uid & st_gid to the uid & gid of the process calling it, >> instead of trying to map the real owner & group of the path or setting it to -1:-1 if it can?t do that... >> >> But there is probably some good reason for this? > > That's really old code that was designed to talk > to SMB1 servers that might predate real identity. > > This is a thornier problem than it looks. > > smbc_stat() does one network call to get the file > info. For SMB2+ in order to convert the owner > information (which is in SID form) to a uid/gid > that has any meaning to the local filesystem you > have to do extra network calls/mapping, as you > describe below. > >> Ie, if I call something like this: >> >>> main() { >>> struct stat sb; >>> ?(connect to share etc) >>> smbc_stat(?smb://user at server/share/dir <smb://user at server/share/dir>?, &sb); >>> printf(?uid = %d, gid = %d\n?, sb.st_uid, sb.st_gid); >>> } >> >> Then my local uid&gid will be printed and not the owner of ?dir? (not even the user I?m connecting as). >> >> >> I can get the real owner & group via: >> >>> const char *owner_attr = "system.nt_sec_desc.owner+"; >>> const char *group_attr = "system.nt_sec_desc.group+"; >>> char buf[256]; >>> >>> smbc_getxattr(path, owner_attr, buf, sizeof(buf)): >>> printf("Owner='%s'\n", path, buf); >>> smbc_getxattr(path, group_attr, buf, sizeof(buf)) < 0) >>> printf(?Group=%s\n?, buf); >> >> (And then manually translating the username & group in but to an uid/gid - so I can work around it but it?s annoying anyway :-) > > So that's doing a set of network RPC's to look up > the SIDs from the server to get names. > > If you think about this, there's no guarantee that > the remote names on the server have meaning on the > local system - that's why SIDs have a global namespace. > > But there's no way to squeeze a SID into a uid/gid > without a pre-defined lossy mapping.
Reasonably Related Threads
- Question about smbc_stat() and smbc_statvfs() in libsmbclient
- Question about smbc_stat() and smbc_statvfs() in libsmbclient
- UID&GID no same at two server...
- Segmentation fault in smbc_getxattr()->...->convert_sid_to_string() in samba-3.2.6
- Out of memory error while calling smbc_getxattr().