Ticket #204: chown-grp.txt

File chown-grp.txt, 15.2 KB (added by YDARIO, 16 years ago)

Patch file for chown/chgrp

Line 
1Index: src/lib/libc.def
2===================================================================
3--- src/lib/libc.def    (revision 3650)
4+++ src/lib/libc.def    (working copy)
5@@ -1960,3 +1960,6 @@
6     "___libc_Back_signalLostPoke" @1958
7 
8 
9+    "___libc_Back_fsFileOwnerSet" @1959
10+    "___libc_Back_fsFileOwnerSetFH" @1960
11+    "___libc_Back_fsSymlinkOwnerSet" @1961
12Index: src/lib/misc/chown.c
13===================================================================
14--- src/lib/misc/chown.c        (revision 3650)
15+++ src/lib/misc/chown.c        (working copy)
16@@ -32,6 +32,7 @@
17 #include "libc-alias.h"
18 #include <unistd.h>
19 #include <sys/stat.h>
20+#include <errno.h>
21 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_IO
22 #include <InnoTekLIBC/logstrict.h>
23 
24@@ -40,8 +41,6 @@
25 /**
26  * Change the owner and group over a file.
27  *
28- * This is stub. It only validates the path and returns without changing anything.
29- *
30  * @returns 0 on success.
31  * @returns -1 and errno on failure.
32  * @param   path    Path to the file to change owner/group of.
33@@ -51,10 +50,9 @@
34 int     _STD(chown)(const char *path, uid_t owner, gid_t group)
35 {
36     LIBCLOG_ENTER("path=%p:{%s} owner=%d group=%d\n", (void *)path, path, owner, group);
37-    struct stat st;
38-    int rc = stat(path, &st);
39+    int rc = __libc_Back_fsFileOwnerSet(path, owner, group);
40     if (!rc)
41-        LIBCLOG_RETURN_INT(rc);
42-    LIBCLOG_ERROR_RETURN_INT(rc);
43+        LIBCLOG_RETURN_INT(0);
44+    errno = -rc;
45+    LIBCLOG_ERROR_RETURN_INT(-1);
46 }
47-
48Index: src/lib/io/lchown.c
49===================================================================
50--- src/lib/io/lchown.c (revision 3650)
51+++ src/lib/io/lchown.c (working copy)
52@@ -32,6 +32,7 @@
53 #include "libc-alias.h"
54 #include <unistd.h>
55 #include <sys/stat.h>
56+#include <errno.h>
57 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_IO
58 #include <InnoTekLIBC/logstrict.h>
59 
60@@ -40,8 +41,6 @@
61 /**
62  * Change the owner and group over a symbolic link.
63  *
64- * This is stub. It only validates the path and returns without changing anything.
65- *
66  * @returns 0 on success.
67  * @returns -1 and errno on failure.
68  * @param   path    Path to the link to change owner/group of.
69@@ -51,10 +50,9 @@
70 int     _STD(lchown)(const char *path, uid_t owner, gid_t group)
71 {
72     LIBCLOG_ENTER("path=%p:{%s} owner=%d group=%d\n", (void *)path, path, owner, group);
73-    struct stat st;
74-    int rc = lstat(path, &st);
75+    int rc = __libc_Back_fsSymlinkOwnerSet(path, owner, group);
76     if (!rc)
77         LIBCLOG_RETURN_INT(0);
78+    errno = -rc;
79     LIBCLOG_ERROR_RETURN_INT(-1);
80 }
81-
82Index: src/lib/sys/b_fsSymlinkModeSet.c
83===================================================================
84--- src/lib/sys/b_fsSymlinkModeSet.c    (revision 3650)
85+++ src/lib/sys/b_fsSymlinkModeSet.c    (working copy)
86@@ -59,3 +59,29 @@
87     LIBCLOG_ERROR_RETURN_INT(rc);
88 }
89 
90+
91+/**
92+ * Sets the file group/owner of a file.
93+ *
94+ * @returns 0 on success.
95+ * @returns Negative error code (errno.h) on failure.
96+ * @param   fh      Handle to file.
97+ * @param   Mode    The filemode.
98+ */
99+int __libc_Back_fsSymlinkOwnerSet(const char *pszPath, uid_t owner, gid_t group)
100+{
101+    LIBCLOG_ENTER("pszPath=%p:{%s} Owner=%#d Group=%#d\n", (void *)pszPath, pszPath, owner, group);
102+
103+    /*
104+     * Resolve the path.
105+     */
106+    char szNativePath[PATH_MAX];
107+    int rc = __libc_back_fsResolve(pszPath, BACKFS_FLAGS_RESOLVE_FULL_SYMLINK | BACKFS_FLAGS_RESOLVE_DIR_MAYBE, szNativePath, NULL);
108+    if (!rc)
109+        rc = __libc_back_fsNativeFileOwnerSet(szNativePath, owner, group);
110+
111+    if (!rc)
112+        LIBCLOG_RETURN_INT(rc);
113+    LIBCLOG_ERROR_RETURN_INT(rc);
114+}
115+
116Index: src/lib/sys/b_fsFileModeSet.c
117===================================================================
118--- src/lib/sys/b_fsFileModeSet.c       (revision 3650)
119+++ src/lib/sys/b_fsFileModeSet.c       (working copy)
120@@ -59,3 +59,29 @@
121     LIBCLOG_ERROR_RETURN_INT(rc);
122 }
123 
124+
125+/**
126+ * Sets the file group/owner of a file.
127+ *
128+ * @returns 0 on success.
129+ * @returns Negative error code (errno.h) on failure.
130+ * @param   pszPath The path to the file to set the mode of.
131+ * @param   owner    The new owner, if -1 do not change it.
132+ * @param   group    The new group, if -1 do not change it.
133+ */
134+int __libc_Back_fsFileOwnerSet(const char *pszPath, uid_t owner, gid_t group)
135+{
136+    LIBCLOG_ENTER("pszPath=%p:{%s} Owner=%#d Owner=%#d\n", (void *)pszPath, pszPath, owner, group);
137+
138+    /*
139+     * Resolve the path.
140+     */
141+    char szNativePath[PATH_MAX];
142+    int rc = __libc_back_fsResolve(pszPath, BACKFS_FLAGS_RESOLVE_FULL | BACKFS_FLAGS_RESOLVE_DIR_MAYBE, szNativePath, NULL);
143+    if (!rc)
144+        rc = __libc_back_fsNativeFileOwnerSet(szNativePath, owner, group);
145+
146+    if (!rc)
147+        LIBCLOG_RETURN_INT(rc);
148+    LIBCLOG_ERROR_RETURN_INT(rc);
149+}
150Index: src/lib/sys/b_fsNativeFileModeSet.c
151===================================================================
152--- src/lib/sys/b_fsNativeFileModeSet.c (revision 3650)
153+++ src/lib/sys/b_fsNativeFileModeSet.c (working copy)
154@@ -214,3 +227,148 @@
155     LIBCLOG_RETURN_INT(0);
156 }
157 
158+/**
159+ * Sets the file group/owner of a native file.
160+ *
161+ * @returns 0 on success.
162+ * @returns Negative error code (errno.h) on failure.
163+ * @param   pszNativePath   Path to the file to change.
164+ * @param   owner    The new owner, if -1 do not change it.
165+ * @param   group    The new group, if -1 do not change it.
166+ */
167+int __libc_back_fsNativeFileOwnerSet(const char *pszNativePath, uid_t owner, gid_t group)
168+{
169+    LIBCLOG_ENTER("pszNativePath=%p:{%s} Owner=%#d Group=%#d\n", (void *)pszNativePath, pszNativePath, owner, group);
170+    FS_VAR();
171+
172+    /*
173+     * Validate input, refusing named pipes.
174+     */
175+    if (    (pszNativePath[0] == '/' || pszNativePath[0] == '\\')
176+        &&  (pszNativePath[1] == 'p' || pszNativePath[1] == 'P')
177+        &&  (pszNativePath[2] == 'i' || pszNativePath[2] == 'I')
178+        &&  (pszNativePath[3] == 'p' || pszNativePath[3] == 'P')
179+        &&  (pszNativePath[4] == 'e' || pszNativePath[4] == 'E')
180+        &&  (pszNativePath[5] == '/' || pszNativePath[5] == '\\'))
181+        LIBCLOG_ERROR_RETURN_INT(-ENOENT);
182+
183+    /*
184+     * If potential device, then perform real check.
185+     * (Devices are subject to mode in POSIX.)
186+     */
187+    /** @todo copy device check from the path resolver. */
188+
189+    /** @todo YD add right access check */
190+
191+    /*
192+     * This call isn't available in Non-Unix mode - we don't handle symlinks there.
193+     * YD true?
194+     */
195+    if (__predict_false(__libc_gfNoUnix != 0))
196+        LIBCLOG_ERROR_RETURN(-ENOSYS, "ret -ENOSYS - __libc_gfNoUnix=%d\n", __libc_gfNoUnix);
197+
198+    /*
199+     * Do we have UnixEAs on this path?
200+     */
201+    if (__predict_false(!__libc_back_fsInfoSupportUnixEAs(pszNativePath)))
202+        LIBCLOG_ERROR_RETURN(-ENOTSUP, "ret -ENOTSUP - no Unix EAs on '%s'\n", pszNativePath);
203+
204+    /*
205+     * update owner if specified
206+     */
207+    FS_SAVE_LOAD();
208+    int rc;
209+    if (owner != -1)
210+    {
211+            /* construct FEA2 stuff. */
212+            #pragma pack(1)
213+            struct __LIBC_FSUNIXATTRIBSSETMODE
214+            {
215+                ULONG   cbList;
216+                ULONG   off;
217+                BYTE    fEA;
218+                BYTE    cbName;
219+                USHORT  cbValue;
220+                CHAR    szName[sizeof(EA_UID)];
221+                USHORT  usType;
222+                USHORT  cbData;
223+                uint32_t u32Mode;
224+            } EAs =
225+            {
226+                sizeof(EAs), 0, FEA_NEEDEA, sizeof(EA_UID) - 1, sizeof(uint32_t) + 4, EA_UID, EAT_BINARY, sizeof(uint32_t), owner
227+            };
228+            #pragma pack()
229+            EAOP2 EaOp2;
230+            EaOp2.fpGEA2List = NULL;
231+            EaOp2.fpFEA2List = (PFEA2LIST)&EAs;
232+            EaOp2.oError = 0;
233+
234+            /* finally, try update / add the EA. */
235+            rc = DosSetPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZE, &EaOp2, sizeof(EaOp2), 0);
236+            if (__predict_false(rc != NO_ERROR))
237+            {
238+                LIBCLOG_ERROR("DosSetPathInfo('%s',,,,) -> %d, oError=%#lx\n", pszNativePath, rc, EaOp2.oError);
239+                if (rc == ERROR_EAS_NOT_SUPPORTED)
240+                    rc = 0;
241+                else
242+                    rc = -__libc_native2errno(rc);
243+            }
244+
245+        if (__predict_false(rc != 0))
246+        {
247+            FS_RESTORE();
248+            LIBCLOG_ERROR_RETURN_INT(rc);
249+        }
250+    }
251+   
252+    /*
253+     * update group if specified
254+     */
255+    if (group != -1)
256+    {
257+            /* construct FEA2 stuff. */
258+            #pragma pack(1)
259+            struct __LIBC_FSUNIXATTRIBSSETMODE
260+            {
261+                ULONG   cbList;
262+                ULONG   off;
263+                BYTE    fEA;
264+                BYTE    cbName;
265+                USHORT  cbValue;
266+                CHAR    szName[sizeof(EA_GID)];
267+                USHORT  usType;
268+                USHORT  cbData;
269+                uint32_t u32Mode;
270+            } EAs =
271+            {
272+                sizeof(EAs), 0, FEA_NEEDEA, sizeof(EA_GID) - 1, sizeof(uint32_t) + 4, EA_GID, EAT_BINARY, sizeof(uint32_t), group
273+            };
274+            #pragma pack()
275+            EAOP2 EaOp2;
276+            EaOp2.fpGEA2List = NULL;
277+            EaOp2.fpFEA2List = (PFEA2LIST)&EAs;
278+            EaOp2.oError = 0;
279+
280+            /* finally, try update / add the EA. */
281+            rc = DosSetPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZE, &EaOp2, sizeof(EaOp2), 0);
282+            if (__predict_false(rc != NO_ERROR))
283+            {
284+                LIBCLOG_ERROR("DosSetPathInfo('%s',,,,) -> %d, oError=%#lx\n", pszNativePath, rc, EaOp2.oError);
285+                if (rc == ERROR_EAS_NOT_SUPPORTED)
286+                    rc = 0;
287+                else
288+                    rc = -__libc_native2errno(rc);
289+            }
290+
291+        if (__predict_false(rc != 0))
292+        {
293+            FS_RESTORE();
294+            LIBCLOG_ERROR_RETURN_INT(rc);
295+        }
296+    }
297+
298+    FS_RESTORE();
299+
300+    LIBCLOG_RETURN_INT(0);
301+}
302+
303Index: src/lib/sys/b_fs.h
304===================================================================
305--- src/lib/sys/b_fs.h  (revision 3650)
306+++ src/lib/sys/b_fs.h  (working copy)
307@@ -388,12 +388,23 @@
308  *
309  * @returns 0 on success.
310  * @returns Negative error code (errno.h) on failure.
311- * @param   fh      Handle to file.
312+ * @param   pszNativePath   Path to the file to change.
313  * @param   Mode    The filemode.
314  */
315 int __libc_back_fsNativeFileModeSet(const char *pszNativePath, mode_t Mode);
316 
317 /**
318+ * Sets the file group/owner of a native file.
319+ *
320+ * @returns 0 on success.
321+ * @returns Negative error code (errno.h) on failure.
322+ * @param   pszNativePath   Path to the file to change.
323+ * @param   owner    The new owner, if -1 do not change it.
324+ * @param   group    The new group, if -1 do not change it.
325+ */
326+int __libc_back_fsNativeFileOwnerSet(const char *pszNativePath, uid_t owner, gid_t group);
327+
328+/**
329  * Sets the file times of a native file.
330  *
331  * @returns 0 on success.
332Index: src/lib/sys/b_fsFileModeSetFH.c
333===================================================================
334--- src/lib/sys/b_fsFileModeSetFH.c     (revision 3650)
335+++ src/lib/sys/b_fsFileModeSetFH.c     (working copy)
336@@ -209,3 +209,163 @@
337     LIBCLOG_RETURN_INT(0);
338 }
339 
340+
341+
342+/**
343+ * Sets the owner/group of a file by filehandle.
344+ *
345+ * @returns 0 on success.
346+ * @returns Negative error code (errno.h) on failure.
347+ * @param   fh      Handle to file.
348+ * @param   owner    The new owner, if -1 do not change it.
349+ * @param   group    The new group, if -1 do not change it.
350+ */
351+int __libc_Back_fsFileOwnerSetFH(int fh, uid_t owner, gid_t group)
352+{
353+    LIBCLOG_ENTER("fh=%d Owner=%#d Group=%#d\n", fh, owner, group);
354+
355+    /*
356+     * Get filehandle.
357+     */
358+    PLIBCFH pFH;
359+    int rc = __libc_FHEx(fh, &pFH);
360+    if (rc)
361+        LIBCLOG_ERROR_RETURN_INT(rc);
362+
363+    /*
364+     * Check the type.
365+     */
366+    switch (pFH->fFlags & __LIBC_FH_TYPEMASK)
367+    {
368+        /* fail */
369+        case F_SOCKET:
370+        case F_PIPE: /* treat as socket for now */
371+            LIBCLOG_ERROR_RETURN_INT(-EINVAL);
372+        /* ignore */
373+        case F_DEV:
374+            LIBCLOG_RETURN_INT(0);
375+
376+        /* use the path access. */
377+        case F_DIR:
378+            if (__predict_false(!pFH->pszNativePath))
379+                LIBCLOG_ERROR_RETURN_INT(-EINVAL);
380+            rc = __libc_back_fsNativeFileOwnerSet(pFH->pszNativePath, owner, group);
381+            if (rc)
382+                LIBCLOG_ERROR_RETURN_INT(rc);
383+            LIBCLOG_RETURN_INT(rc);
384+
385+        /* treat */
386+        default:
387+        case F_FILE:
388+            break;
389+    }
390+
391+    /** @todo YD add right access check */
392+
393+    if (!pFH->pOps)
394+    {
395+        /*
396+         * Standard OS/2 file handle.
397+         */
398+        FS_VAR();
399+        FS_SAVE_LOAD();
400+       /*
401+        * update owner if specified
402+        */
403+       FS_SAVE_LOAD();
404+       int rc;
405+       if (owner != -1)
406+       {
407+               /* construct FEA2 stuff. */
408+               #pragma pack(1)
409+               struct __LIBC_FSUNIXATTRIBSSETMODE
410+               {
411+                   ULONG   cbList;
412+                   ULONG   off;
413+                   BYTE    fEA;
414+                   BYTE    cbName;
415+                   USHORT  cbValue;
416+                   CHAR    szName[sizeof(EA_UID)];
417+                   USHORT  usType;
418+                   USHORT  cbData;
419+                   uint32_t u32Mode;
420+               } EAs =
421+               {
422+                   sizeof(EAs), 0, FEA_NEEDEA, sizeof(EA_UID) - 1, sizeof(uint32_t) + 4, EA_UID, EAT_BINARY, sizeof(uint32_t), owner
423+               };
424+               #pragma pack()
425+               EAOP2 EaOp2;
426+               EaOp2.fpGEA2List = NULL;
427+               EaOp2.fpFEA2List = (PFEA2LIST)&EAs;
428+               EaOp2.oError = 0;
429+   
430+               /* finally, try update / add the EA. */
431+               rc = DosSetFileInfo(fh, FIL_QUERYEASIZE, &EaOp2, sizeof(EaOp2));
432+               if (__predict_false(rc != NO_ERROR))
433+               {
434+                   LIBCLOG_ERROR("DosSetFileInfo('%d',,,,) -> %d, oError=%#lx\n", fh, rc, EaOp2.oError);
435+                   if (rc == ERROR_EAS_NOT_SUPPORTED)
436+                       rc = 0;
437+                   else
438+                       rc = -__libc_native2errno(rc);
439+               }
440+   
441+           if (__predict_false(rc != 0))
442+           {
443+               FS_RESTORE();
444+               LIBCLOG_ERROR_RETURN_INT(rc);
445+           }
446+       }
447+       
448+       /*
449+        * update group if specified
450+        */
451+       if (group != -1)
452+       {
453+               /* construct FEA2 stuff. */
454+               #pragma pack(1)
455+               struct __LIBC_FSUNIXATTRIBSSETMODE
456+               {
457+                   ULONG   cbList;
458+                   ULONG   off;
459+                   BYTE    fEA;
460+                   BYTE    cbName;
461+                   USHORT  cbValue;
462+                   CHAR    szName[sizeof(EA_GID)];
463+                   USHORT  usType;
464+                   USHORT  cbData;
465+                   uint32_t u32Mode;
466+               } EAs =
467+               {
468+                   sizeof(EAs), 0, FEA_NEEDEA, sizeof(EA_GID) - 1, sizeof(uint32_t) + 4, EA_GID, EAT_BINARY, sizeof(uint32_t), group
469+               };
470+               #pragma pack()
471+               EAOP2 EaOp2;
472+               EaOp2.fpGEA2List = NULL;
473+               EaOp2.fpFEA2List = (PFEA2LIST)&EAs;
474+               EaOp2.oError = 0;
475+   
476+               /* finally, try update / add the EA. */
477+               rc = DosSetFileInfo(fh, FIL_QUERYEASIZE, &EaOp2, sizeof(EaOp2));
478+               if (__predict_false(rc != NO_ERROR))
479+               {
480+                   LIBCLOG_ERROR("DosSetFileInfo('%d',,,,) -> %d, oError=%#lx\n", fh, rc, EaOp2.oError);
481+                   if (rc == ERROR_EAS_NOT_SUPPORTED)
482+                       rc = 0;
483+                   else
484+                       rc = -__libc_native2errno(rc);
485+               }
486+   
487+           if (__predict_false(rc != 0))
488+           {
489+               FS_RESTORE();
490+               LIBCLOG_ERROR_RETURN_INT(rc);
491+           }
492+       }
493
494+    FS_RESTORE();
495+    }
496+
497+    LIBCLOG_RETURN_INT(0);
498+}
499+