Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-ID: <3E2F19E0.8010301@csgsystems.com> Date: Wed, 22 Jan 2003 23:23:28 +0100 From: Christian Mueller User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.2.1) Gecko/20021130 X-Accept-Language: en-us, en MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: NTEA extensions for uid/gid Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: 4 (****) USER_AGENT_MOZILLA_UA,__EVITE_CTYPE,X_ACCEPT_LANG,USER_AGENT X-Scanned-By: MIMEDefang 2.28 (www . roaringpenguin . com / mimedefang) Hi all, after ntsec became the default for cygwin (and some further changes to ruserok()), I ran into problems running servers such as rshd depending on .rhosts and ruserok() because I don't use ntsec and ntea doesn't store the file's uid/gid. As a result, I can't use rshd anymore because it complains that the .rhosts file is not owned by the correct user. I discussed this on the Cygwin user group but my impression was that I'm the only one having this problem at this point and possibly one of the few using ntea. I don't want to use ntsec because I use my Cygwin home directory for Cygwin *and* Windows programs and ntsec displays screwed-up file permissions for files created by Windows programs. BTW, my user is part of the admin group because I can't change things such as network settings on my laptop without being an "administrator". Thus, I went ahead and modified ntea.cc and security.cc to support uid/gid in addition to the file mode. The modified version now uses three extended attributes: .UNIXATTR - file mode (same as in current versions) .UNIXUID - UID (file owner) .UNIXGID - GID (file group) I added a new function to ntea.cc, NTReadEAMulti(), which reads all requested EAs in one step, thus there's no additional overhead besides the few extra bytes to be read by NTReadEARaw() but that shouldn't have any noticable impact on performance. I did not combine the existing file mode with the uid/gid values into a structure because this would have caused trouble with earlier versions of Cygwin -- NTReadEA() currently returns an error if the extended attibute is bigger than the buffer provided. Also, I didn't write a NTWriteEAMulti() variant, yet, because I wanted to get feedback from the Cygwin group before putting more effort into this issue. It works as it is right now but a function NTWriteEAMulti() would certainly speed up setting attributes. What I'm looking for right now is some feedback on this idea. Naturally, I would like those modifications to end up in the Cygwin core distribution but this probably needs to be discussed properly before being considered. I added the source changes at the bottom of this email. They are not complete, yet, but already work for me and should be good enough for discussion. Thanks, --Christian ===================================================================== ----------- security.h: ----------- typedef struct { const char *attrname; void *attrbuf; size_t maxlen; size_t len; } ea_multi_t; -------- ntea.cc: -------- /* * NTReadEAMulti - read multiple EAs in one step. This function is * more efficient than NTReadEA when multiple * attributes are required because it reads the * EAs only once. * * Parameters: * file - pointer to filename * eam - array of ea_multi_t structures with * the EAs to read * Return value: * > 0 - number of EAs found * 0 - no EAs found * * The ea_multi_t array will be updated with the EAs read; the * len fields will contain the length of each attribute, 0 * if this particular EA was not found. */ int __stdcall NTReadEAMulti (const char *file, int cnt, ea_multi_t *eam) { HANDLE hFileSource; PFILE_FULL_EA_INFORMATION ea, sea; int cnt_found = 0; int easize; int i; /* Reset returned EA length in eam */ for (i = 0; i < cnt; i++) eam[i].len = 0; hFileSource = CreateFile (file, FILE_READ_EA, FILE_SHARE_READ | FILE_SHARE_WRITE, &sec_none_nih, // sa OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (hFileSource == INVALID_HANDLE_VALUE) return 0; /* Read in raw array of EAs */ ea = sea = NTReadEARaw (hFileSource, &easize); /* Search for requested attributes */ while (sea) { for (i = 0; i < cnt; i++) { if (strcasematch (ea->EaName, eam[i].attrname)) /* EA found */ { eam[i].len = min(eam[i].maxlen, ea->EaValueLength); memcpy (eam[i].attrbuf, ea->EaName + (ea->EaNameLength + 1), eam[i].len); cnt_found++; break; } } if (ea->NextEntryOffset == 0 || ((int) ea->NextEntryOffset > easize)) break; ea = (PFILE_FULL_EA_INFORMATION) ((char *) ea + ea->NextEntryOffset); } if (sea) free (sea); CloseHandle (hFileSource); return cnt_found; } ------------ security.cc: ------------ int get_file_attribute (int use_ntsec, const char *file, int *attribute, __uid32_t *uidret, __gid32_t *gidret) { .... if (allow_ntea) { __uid32_t uid; __gid32_t gid; int attr = *attribute; ea_multi_t eam[] = { { ".UNIXATTR", attribute, sizeof(*attribute), 0 }, { ".UNIXUID", &uid, sizeof(uid), 0 }, { ".UNIXGID", &gid, sizeof(gid), 0 } }; res = NTReadEAMulti (file, sizeof(eam) / sizeof(*eam), eam); *attribute |= attr; if (uidret && eam[1].len > 0) *uidret = uid; if (gidret && eam[2].len > 0) *gidret = gid; } .... } int set_file_attribute (int use_ntsec, const char *file, __uid32_t uid, __gid32_t gid, int attribute) { .... else if (allow_ntea) { __uid32_t l_uid = myself->uid; __gid32_t l_gid = myself->gid; ea_multi_t eam[] = { { ".UNIXUID", &l_uid, sizeof(l_uid), 0 }, { ".UNIXGID", &l_gid, sizeof(l_gid), 0 } }; NTReadEAMulti(file, sizeof(eam) / sizeof(*eam), eam); if (uid != ILLEGAL_UID) l_uid = uid; if (gid != ILLEGAL_GID) l_gid = gid; if (!NTWriteEA (file, ".UNIXATTR", (char *) &attribute, sizeof (attribute)) || !NTWriteEA (file, ".UNIXUID", (char *) &l_uid, sizeof (l_uid)) || !NTWriteEA (file, ".UNIXGID", (char *) &l_gid, sizeof (l_gid))) { __seterrno (); ret = -1; } } .... } -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/