]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Issue 15, part 5. New files for cygwin/cpio
authorCharles Wilson <cwilso11@gmail.com>
Thu, 19 Mar 2009 02:43:53 +0000 (22:43 -0400)
committerCharles Wilson <cwilso11@gmail.com>
Thu, 19 Mar 2009 02:43:53 +0000 (22:43 -0400)
  Added cpio/cpio_cygwin.[c|h] which are simply copies
  of the relevant portions of cpio/cpio_windows.[c|h]
  Modified cpio/cpio_platform.h to #include as needed.
  Modified cpio/cpio.c to call new bsdcpio_is_privileged()
  function on cygwin also.

SVN-Revision: 801

cpio/cpio.c
cpio/cpio_cygwin.c [new file with mode: 0644]
cpio/cpio_cygwin.h [new file with mode: 0644]
cpio/cpio_platform.h

index b3fd1db0b75d926a4fc167121d00a5a396cd11ec..df63630f6b349c004c692abac2548cd3f9fa1eb8 100644 (file)
@@ -157,7 +157,7 @@ main(int argc, char *argv[])
        cpio->extract_flags |= ARCHIVE_EXTRACT_PERM;
        cpio->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
        cpio->extract_flags |= ARCHIVE_EXTRACT_ACL;
-#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) || defined(__CYGWIN__)
        if (bsdcpio_is_privileged())
 #else
        if (geteuid() == 0)
diff --git a/cpio/cpio_cygwin.c b/cpio/cpio_cygwin.c
new file mode 100644 (file)
index 0000000..5032afd
--- /dev/null
@@ -0,0 +1,139 @@
+/*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#if defined(__CYGWIN__)
+#define _WIN32_WINNT   0x500
+#define WINVER         0x500
+
+#include "cpio_platform.h"
+#include <errno.h>
+#include <stddef.h>
+#include <sys/utime.h>
+#include <sys/stat.h>
+#include <process.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <windows.h>
+#include <sddl.h>
+
+#include "cpio.h"
+
+#ifndef LIST_H
+static int
+_is_privileged(HANDLE thandle, const char *sidlist[])
+{
+       TOKEN_USER *tuser;
+       TOKEN_GROUPS  *tgrp;
+       DWORD bytes;
+       PSID psid;
+       DWORD i, g;
+       int member;
+
+       psid = NULL;
+       tuser = NULL;
+       tgrp = NULL;
+       member = 0;
+       for (i = 0; sidlist[i] != NULL && member == 0; i++) {
+               if (psid != NULL)
+                       LocalFree(psid);
+               /* mingw/cygwin: incorrectly prototypes arg 1 as LPSTR
+                * instead of LPCSTR. Work around it here
+                */
+               if (ConvertStringSidToSidA((char *)sidlist[i], &psid) == 0) {
+                       errno = EPERM;
+                       return (-1);
+               }
+               if (tuser == NULL) {
+                       GetTokenInformation(thandle, TokenUser, NULL, 0, &bytes);
+                       tuser = malloc(bytes);
+                       if (tuser == NULL) {
+                               errno = ENOMEM;
+                               member = -1;
+                               break;
+                       }
+                       if (GetTokenInformation(thandle, TokenUser, tuser, bytes, &bytes) == 0) {
+                               errno = EPERM;
+                               member = -1;
+                               break;
+                       }
+               }
+               member = EqualSid(tuser->User.Sid, psid);
+               if (member)
+                       break;
+               if (tgrp == NULL) {
+                       GetTokenInformation(thandle, TokenGroups, NULL, 0, &bytes);
+                       tgrp = malloc(bytes);
+                       if (tgrp == NULL) {
+                               errno = ENOMEM;
+                               member = -1;
+                               break;
+                       }
+                       if (GetTokenInformation(thandle, TokenGroups, tgrp, bytes, &bytes) == 0) {
+                               errno = EPERM;
+                               member = -1;
+                               break;
+                       }
+               }
+               for (g = 0; g < tgrp->GroupCount; g++) {
+                       member = EqualSid(tgrp->Groups[g].Sid, psid);
+                       if (member)
+                               break;
+               }
+       }
+       LocalFree(psid);
+       free(tuser);
+       free(tgrp);
+
+       return (member);
+}
+
+int
+bsdcpio_is_privileged()
+{
+       HANDLE thandle;
+       int ret;
+       const char *sidlist[] = {
+               "S-1-5-32-544", /* Administrators */
+               "S-1-5-32-551", /* Backup Operators */
+               NULL
+       };
+
+       if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &thandle) == 0) {
+               cpio_warnc(EPERM, "Failed to check privilege");
+               return (0);
+       }
+       ret = _is_privileged(thandle, sidlist);
+       if (ret < 0) {
+               cpio_warnc(errno, "Failed to check privilege");
+               return (0);
+       }
+       return (ret);
+}
+
+#endif /* LIST_H */
+
+#endif
diff --git a/cpio/cpio_cygwin.h b/cpio/cpio_cygwin.h
new file mode 100644 (file)
index 0000000..9ee41b4
--- /dev/null
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef CPIO_CYGWIN_H
+#define CPIO_CYGWIN_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int             bsdcpio_is_privileged();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CPIO_CYGWIN_H */
index a676851051ee5227eac39044856b84608273c204..8ade73130e92d23eab47bd842abdd4df036b578e 100644 (file)
@@ -89,7 +89,9 @@
 #define __LA_DEAD
 #endif
 
-#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(__CYGWIN__)
+#include "cpio_cygwin.h"
+#elif defined(_WIN32)  /* && !__CYGWIN__ */
 #include "cpio_windows.h"
 #endif