1 /* sysutils.c - system helpers
2 * Copyright (C) 1991-2001, 2003-2004,
3 * 2006-2008 Free Software Foundation, Inc.
4 * Copyright (C) 2013-2016 Werner Koch
6 * This file is part of GnuPG.
8 * This file is free software; you can redistribute it and/or modify
9 * it under the terms of either
11 * - the GNU Lesser General Public License as published by the Free
12 * Software Foundation; either version 3 of the License, or (at
13 * your option) any later version.
17 * - the GNU General Public License as published by the Free
18 * Software Foundation; either version 2 of the License, or (at
19 * your option) any later version.
21 * or both in parallel, as here.
23 * This file is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, see <https://www.gnu.org/licenses/>.
34 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth. */
46 # include <sys/stat.h>
48 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
49 # include <asm/sysinfo.h>
50 # include <asm/unistd.h>
54 # include <sys/time.h>
55 # include <sys/resource.h>
57 #ifdef HAVE_W32_SYSTEM
59 # define WINVER 0x0500 /* Required for AllowSetForegroundWindow. */
61 # ifdef HAVE_WINSOCK2_H
62 # include <winsock2.h>
65 #else /*!HAVE_W32_SYSTEM*/
66 # include <sys/socket.h>
69 #ifdef HAVE_INOTIFY_INIT
70 # include <sys/inotify.h>
71 #endif /*HAVE_INOTIFY_INIT*/
84 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
86 /* Flag to tell whether special file names are enabled. See gpg.c for
87 * an explanation of these file names. */
88 static int allow_special_filenames;
91 static GPGRT_INLINE gpg_error_t
92 my_error_from_syserror (void)
94 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
97 static GPGRT_INLINE gpg_error_t
100 return gpg_err_make (default_errsource, (e));
105 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
106 #warning using trap_unaligned
108 setsysinfo(unsigned long op, void *buffer, unsigned long size,
109 int *start, void *arg, unsigned long flag)
111 return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
119 buf[0] = SSIN_UACPROC;
120 buf[1] = UAC_SIGBUS | UAC_NOPRINT;
121 setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
132 disable_core_dumps (void)
134 #ifdef HAVE_DOSISH_SYSTEM
137 # ifdef HAVE_SETRLIMIT
140 /* We only set the current limit unless we were not able to
141 retrieve the old value. */
142 if (getrlimit (RLIMIT_CORE, &limit))
145 if( !setrlimit (RLIMIT_CORE, &limit) )
147 if( errno != EINVAL && errno != ENOSYS )
148 log_fatal (_("can't disable core dumps: %s\n"), strerror(errno) );
155 enable_core_dumps (void)
157 #ifdef HAVE_DOSISH_SYSTEM
160 # ifdef HAVE_SETRLIMIT
163 if (getrlimit (RLIMIT_CORE, &limit))
165 limit.rlim_cur = limit.rlim_max;
166 setrlimit (RLIMIT_CORE, &limit);
167 return 1; /* We always return true because this function is
168 merely a debugging aid. */
175 /* Allow the use of special "-&nnn" style file names. */
177 enable_special_filenames (void)
179 allow_special_filenames = 1;
183 /* Return a string which is used as a kind of process ID. */
185 get_session_marker (size_t *rlen)
187 static byte marker[SIZEOF_UNSIGNED_LONG*2];
188 static int initialized;
192 gcry_create_nonce (marker, sizeof marker);
195 *rlen = sizeof (marker);
199 /* Return a random number in an unsigned int. */
201 get_uint_nonce (void)
205 gcry_create_nonce (&value, sizeof value);
211 #if 0 /* not yet needed - Note that this will require inclusion of
212 cmacros.am in Makefile.am */
214 check_permissions(const char *path,int extension,int checkonly)
216 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
225 if(extension && path[0]!=DIRSEP_C)
227 if(strchr(path,DIRSEP_C))
228 tmppath=make_filename(path,NULL);
230 tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
233 tmppath=m_strdup(path);
235 /* It's okay if the file doesn't exist */
236 if(stat(tmppath,&statbuf)!=0)
242 isdir=S_ISDIR(statbuf.st_mode);
244 /* Per-user files must be owned by the user. Extensions must be
245 owned by the user or root. */
246 if((!extension && statbuf.st_uid != getuid()) ||
247 (extension && statbuf.st_uid!=0 && statbuf.st_uid!=getuid()))
250 log_info(_("Warning: unsafe ownership on %s \"%s\"\n"),
251 isdir?"directory":extension?"extension":"file",path);
255 /* This works for both directories and files - basically, we don't
256 care what the owner permissions are, so long as the group and
257 other permissions are 0 for per-user files, and non-writable for
259 if((extension && (statbuf.st_mode & (S_IWGRP|S_IWOTH)) !=0) ||
260 (!extension && (statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0))
264 /* However, if the directory the directory/file is in is owned
265 by the user and is 700, then this is not a problem.
266 Theoretically, we could walk this test up to the root
267 directory /, but for the sake of sanity, I'm stopping at one
270 dir= make_dirname (tmppath);
271 if(stat(dir,&statbuf)==0 && statbuf.st_uid==getuid() &&
272 S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
282 log_info(_("Warning: unsafe permissions on %s \"%s\"\n"),
283 isdir?"directory":extension?"extension":"file",path);
294 #endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
301 /* Wrapper around the usual sleep function. This one won't wake up
302 before the sleep time has really elapsed. When build with Pth it
303 merely calls pth_sleep and thus suspends only the current
306 gnupg_sleep (unsigned int seconds)
309 npth_sleep (seconds);
311 /* Fixme: make sure that a sleep won't wake up to early. */
312 # ifdef HAVE_W32_SYSTEM
313 Sleep (seconds*1000);
321 /* Wrapper around the platforms usleep function. This one won't wake
322 * up before the sleep time has really elapsed. When build with nPth
323 * it merely calls npth_usleep and thus suspends only the current
326 gnupg_usleep (unsigned int usecs)
328 #if defined(USE_NPTH)
332 #elif defined(HAVE_W32_SYSTEM)
334 Sleep ((usecs + 999) / 1000);
336 #elif defined(HAVE_NANOSLEEP)
344 req.tv_nsec = usecs * 1000;
346 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
350 #else /*Standard Unix*/
356 tv.tv_sec = usecs / 1000000;
357 tv.tv_usec = usecs % 1000000;
358 select (0, NULL, NULL, NULL, &tv);
365 /* This function is a NOP for POSIX systems but required under Windows
366 as the file handles as returned by OS calls (like CreateFile) are
367 different from the libc file descriptors (like open). This function
368 translates system file handles to libc file handles. FOR_WRITE
369 gives the direction of the handle. */
371 translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
373 #if defined(HAVE_W32CE_SYSTEM)
376 #elif defined(HAVE_W32_SYSTEM)
379 if (fd == GNUPG_INVALID_FD)
382 /* Note that _open_osfhandle is currently defined to take and return
384 x = _open_osfhandle ((long)fd, for_write ? 1 : 0);
386 log_error ("failed to translate osfhandle %p\n", (void *) fd);
388 #else /*!HAVE_W32_SYSTEM */
394 /* This is the same as translate_sys2libc_fd but takes an integer
395 which is assumed to be such an system handle. On WindowsCE the
396 passed FD is a rendezvous ID and the function finishes the pipe
399 translate_sys2libc_fd_int (int fd, int for_write)
401 #if HAVE_W32CE_SYSTEM
402 fd = (int) _assuan_w32ce_finish_pipe (fd, for_write);
403 return translate_sys2libc_fd ((void*)fd, for_write);
404 #elif HAVE_W32_SYSTEM
406 return fd; /* Do not do this for error, stdin, stdout, stderr. */
408 return translate_sys2libc_fd ((void*)fd, for_write);
416 /* Check whether FNAME has the form "-&nnnn", where N is a non-zero
417 * number. Returns this number or -1 if it is not the case. If the
418 * caller wants to use the file descriptor for writing FOR_WRITE shall
419 * be set to 1. If NOTRANSLATE is set the Windows spefic mapping is
422 check_special_filename (const char *fname, int for_write, int notranslate)
424 if (allow_special_filenames
425 && fname && *fname == '-' && fname[1] == '&')
430 for (i=0; digitp (fname+i); i++ )
433 return notranslate? atoi (fname)
434 /**/ : translate_sys2libc_fd_int (atoi (fname), for_write);
440 /* Replacement for tmpfile(). This is required because the tmpfile
441 function of Windows' runtime library is broken, insecure, ignores
442 TMPDIR and so on. In addition we create a file with an inheritable
447 #ifdef HAVE_W32_SYSTEM
449 #ifdef HAVE_W32CE_SYSTEM
450 wchar_t buffer[MAX_PATH+7+12+1];
451 # define mystrlen(a) wcslen (a)
454 char buffer[MAX_PATH+7+12+1];
455 # define mystrlen(a) strlen (a)
459 int pid = GetCurrentProcessId ();
462 SECURITY_ATTRIBUTES sec_attr;
464 memset (&sec_attr, 0, sizeof sec_attr );
465 sec_attr.nLength = sizeof sec_attr;
466 sec_attr.bInheritHandle = TRUE;
468 n = GetTempPath (MAX_PATH+1, buffer);
469 if (!n || n > MAX_PATH || mystrlen (buffer) > MAX_PATH)
471 gpg_err_set_errno (ENOENT);
474 p = buffer + mystrlen (buffer);
475 #ifdef HAVE_W32CE_SYSTEM
476 wcscpy (p, L"_gnupg");
479 p = stpcpy (p, "_gnupg");
481 /* We try to create the directory but don't care about an error as
482 it may already exist and the CreateFile would throw an error
484 CreateDirectory (buffer, NULL);
487 for (attempts=0; attempts < 10; attempts++)
490 value = (GetTickCount () ^ ((pid<<16) & 0xffff0000));
491 for (i=0; i < 8; i++)
493 *p++ = tohex (((value >> 28) & 0x0f));
496 #ifdef HAVE_W32CE_SYSTEM
501 file = CreateFile (buffer,
502 GENERIC_READ | GENERIC_WRITE,
506 FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
508 if (file != INVALID_HANDLE_VALUE)
511 #ifdef HAVE_W32CE_SYSTEM
513 fp = _wfdopen (fd, L"w+b");
515 int fd = _open_osfhandle ((long)file, 0);
521 fp = fdopen (fd, "w+b");
527 gpg_err_set_errno (save);
532 Sleep (1); /* One ms as this is the granularity of GetTickCount. */
534 gpg_err_set_errno (ENOENT);
537 #else /*!HAVE_W32_SYSTEM*/
539 #endif /*!HAVE_W32_SYSTEM*/
543 /* Make sure that the standard file descriptors are opened. Obviously
544 some folks close them before an exec and the next file we open will
545 get one of them assigned and thus any output (i.e. diagnostics) end
546 up in that file (e.g. the trustdb). Not actually a gpg problem as
547 this will happen with almost all utilities when called in a wrong
548 way. However we try to minimize the damage here and raise
549 awareness of the problem.
551 Must be called before we open any files! */
553 gnupg_reopen_std (const char *pgmname)
555 #if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
562 if (fstat (STDIN_FILENO, &statbuf) == -1 && errno ==EBADF)
564 if (open ("/dev/null",O_RDONLY) == STDIN_FILENO)
570 if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
572 if (open ("/dev/null",O_WRONLY) == STDOUT_FILENO)
578 if (fstat (STDERR_FILENO, &statbuf)==-1 && errno==EBADF)
580 if (open ("/dev/null", O_WRONLY) == STDERR_FILENO)
586 /* It's hard to log this sort of thing since the filehandle we would
587 complain to may be closed... */
590 else if (!did_stdout)
598 fprintf (complain, "%s: WARNING: standard input reopened\n", pgmname);
600 fprintf (complain, "%s: WARNING: standard output reopened\n", pgmname);
602 fprintf (complain, "%s: WARNING: standard error reopened\n", pgmname);
604 if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
605 fprintf(complain,"%s: fatal: unable to reopen standard input,"
606 " output, or error\n", pgmname);
609 if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
611 #else /* !(HAVE_STAT && !HAVE_W32_SYSTEM) */
617 /* Hack required for Windows. */
619 gnupg_allow_set_foregound_window (pid_t pid)
622 log_info ("%s called with invalid pid %lu\n",
623 "gnupg_allow_set_foregound_window", (unsigned long)pid);
624 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
625 else if (!AllowSetForegroundWindow ((pid_t)pid == (pid_t)(-1)?ASFW_ANY:pid))
626 log_info ("AllowSetForegroundWindow(%lu) failed: %s\n",
627 (unsigned long)pid, w32_strerror (-1));
632 gnupg_remove (const char *fname)
634 #ifdef HAVE_W32CE_SYSTEM
638 wfname = utf8_to_wchar (fname);
643 rc = DeleteFile (wfname);
647 return -1; /* ERRNO is automagically provided by gpg-error.h. */
650 return remove (fname);
655 /* Wrapper for rename(2) to handle Windows peculiarities. If
656 * BLOCK_SIGNALS is not NULL and points to a variable set to true, all
657 * signals will be blocked by calling gnupg_block_all_signals; the
658 * caller needs to call gnupg_unblock_all_signals if that variable is
659 * still set to true on return. */
661 gnupg_rename_file (const char *oldname, const char *newname, int *block_signals)
665 if (block_signals && *block_signals)
666 gnupg_block_all_signals ();
668 #ifdef HAVE_DOSISH_SYSTEM
672 gnupg_remove (newname);
674 if (rename (oldname, newname))
676 if (GetLastError () == ERROR_SHARING_VIOLATION)
678 /* Another process has the file open. We do not use a
679 * lock for read but instead we wait until the other
680 * process has closed the file. This may take long but
681 * that would also be the case with a dotlock approach for
682 * read and write. Note that we don't need this on Unix
683 * due to the inode concept.
685 * So let's wait until the rename has worked. The retry
686 * intervals are 50, 100, 200, 400, 800, 50ms, ... */
687 if (!wtime || wtime >= 800)
693 log_info (_("waiting for file '%s' to become accessible ...\n"),
699 err = my_error_from_syserror ();
705 gnupg_remove (newname);
707 if (rename (oldname, newname) )
708 err = my_error_from_syserror ();
712 if (block_signals && *block_signals && err)
714 gnupg_unblock_all_signals ();
719 log_error (_("renaming '%s' to '%s' failed: %s\n"),
720 oldname, newname, gpg_strerror (err));
725 #ifndef HAVE_W32_SYSTEM
727 modestr_to_mode (const char *modestr)
731 if (modestr && *modestr)
734 if (*modestr && *modestr++ == 'r')
736 if (*modestr && *modestr++ == 'w')
738 if (*modestr && *modestr++ == 'x')
740 if (*modestr && *modestr++ == 'r')
742 if (*modestr && *modestr++ == 'w')
744 if (*modestr && *modestr++ == 'x')
746 if (*modestr && *modestr++ == 'r')
748 if (*modestr && *modestr++ == 'w')
750 if (*modestr && *modestr++ == 'x')
759 /* A wrapper around mkdir which takes a string for the mode argument.
760 This makes it easier to handle the mode argument which is not
761 defined on all systems. The format of the modestring is
765 '-' is a don't care or not set. 'r', 'w', 'x' are read allowed,
766 write allowed, execution allowed with the first group for the user,
767 the second for the group and the third for all others. If the
768 string is shorter than above the missing mode characters are meant
771 gnupg_mkdir (const char *name, const char *modestr)
773 #ifdef HAVE_W32CE_SYSTEM
777 wname = utf8_to_wchar (name);
780 if (!CreateDirectoryW (wname, NULL))
783 return -1; /* ERRNO is automagically provided by gpg-error.h. */
787 #elif MKDIR_TAKES_ONE_ARG
789 /* Note: In the case of W32 we better use CreateDirectory and try to
790 set appropriate permissions. However using mkdir is easier
791 because this sets ERRNO. */
794 return mkdir (name, modestr_to_mode (modestr));
799 /* A wrapper around chmod which takes a string for the mode argument.
800 This makes it easier to handle the mode argument which is not
801 defined on all systems. The format of the modestring is the same
802 as for gnupg_mkdir. */
804 gnupg_chmod (const char *name, const char *modestr)
806 #ifdef HAVE_W32_SYSTEM
811 return chmod (name, modestr_to_mode (modestr));
816 /* Our version of mkdtemp. The API is identical to POSIX.1-2008
817 version. We do not use a system provided mkdtemp because we have a
818 good RNG instantly available and this way we don't have diverging
821 gnupg_mkdtemp (char *tmpl)
823 /* A lower bound on the number of temporary files to attempt to
824 generate. The maximum total number of temporary file names that
825 can exist for a given template is 62**6 (5*36**3 for Windows).
826 It should never be necessary to try all these combinations.
827 Instead if a reasonable number of names is tried (we define
828 reasonable as 62**3 or 5*36**3) fail to give the system
829 administrator the chance to remove the problems. */
830 #ifdef HAVE_W32_SYSTEM
831 static const char letters[] =
832 "abcdefghijklmnopqrstuvwxyz0123456789";
833 # define NUMBER_OF_LETTERS 36
834 # define ATTEMPTS_MIN (5 * 36 * 36 * 36)
836 static const char letters[] =
837 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
838 # define NUMBER_OF_LETTERS 62
839 # define ATTEMPTS_MIN (62 * 62 * 62)
845 int save_errno = errno;
846 /* The number of times to attempt to generate a temporary file. To
847 conform to POSIX, this must be no smaller than TMP_MAX. */
848 #if ATTEMPTS_MIN < TMP_MAX
849 unsigned int attempts = TMP_MAX;
851 unsigned int attempts = ATTEMPTS_MIN;
855 if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
857 gpg_err_set_errno (EINVAL);
861 /* This is where the Xs start. */
862 XXXXXX = &tmpl[len - 6];
864 /* Get a random start value. */
865 gcry_create_nonce (&value, sizeof value);
867 /* Loop until a directory was created. */
868 for (count = 0; count < attempts; value += 7777, ++count)
872 /* Fill in the random bits. */
873 XXXXXX[0] = letters[v % NUMBER_OF_LETTERS];
874 v /= NUMBER_OF_LETTERS;
875 XXXXXX[1] = letters[v % NUMBER_OF_LETTERS];
876 v /= NUMBER_OF_LETTERS;
877 XXXXXX[2] = letters[v % NUMBER_OF_LETTERS];
878 v /= NUMBER_OF_LETTERS;
879 XXXXXX[3] = letters[v % NUMBER_OF_LETTERS];
880 v /= NUMBER_OF_LETTERS;
881 XXXXXX[4] = letters[v % NUMBER_OF_LETTERS];
882 v /= NUMBER_OF_LETTERS;
883 XXXXXX[5] = letters[v % NUMBER_OF_LETTERS];
885 if (!gnupg_mkdir (tmpl, "-rwx"))
887 gpg_err_set_errno (save_errno);
894 /* We got out of the loop because we ran out of combinations to try. */
895 gpg_err_set_errno (EEXIST);
901 gnupg_setenv (const char *name, const char *value, int overwrite)
903 #ifdef HAVE_W32CE_SYSTEM
909 # ifdef HAVE_W32_SYSTEM
910 /* Windows maintains (at least) two sets of environment variables.
911 One set can be accessed by GetEnvironmentVariable and
912 SetEnvironmentVariable. This set is inherited by the children.
913 The other set is maintained in the C runtime, and is accessed
914 using getenv and putenv. We try to keep them in sync by
915 modifying both sets. */
919 exists = GetEnvironmentVariable (name, tmpbuf, sizeof tmpbuf);
921 if ((! exists || overwrite) && !SetEnvironmentVariable (name, value))
923 gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
930 return setenv (name, value, overwrite);
931 # else /*!HAVE_SETENV*/
932 if (! getenv (name) || overwrite)
939 gpg_err_set_errno (EINVAL);
942 buf = strconcat (name, "=", value, NULL);
946 # warning no setenv - using putenv but leaking memory.
951 # endif /*!HAVE_SETENV*/
957 gnupg_unsetenv (const char *name)
959 #ifdef HAVE_W32CE_SYSTEM
963 # ifdef HAVE_W32_SYSTEM
964 /* Windows maintains (at least) two sets of environment variables.
965 One set can be accessed by GetEnvironmentVariable and
966 SetEnvironmentVariable. This set is inherited by the children.
967 The other set is maintained in the C runtime, and is accessed
968 using getenv and putenv. We try to keep them in sync by
969 modifying both sets. */
970 if (!SetEnvironmentVariable (name, NULL))
972 gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
977 # ifdef HAVE_UNSETENV
978 return unsetenv (name);
979 # else /*!HAVE_UNSETENV*/
985 gpg_err_set_errno (EINVAL);
988 buf = xtrystrdup (name);
992 # warning no unsetenv - trying putenv but leaking memory.
996 # endif /*!HAVE_UNSETENV*/
1001 /* Return the current working directory as a malloced string. Return
1002 NULL and sets ERRNo on error. */
1011 buffer = xtrymalloc (size+1);
1014 #ifdef HAVE_W32CE_SYSTEM
1015 strcpy (buffer, "/"); /* Always "/". */
1018 if (getcwd (buffer, size) == buffer)
1021 if (errno != ERANGE)
1030 #ifdef HAVE_W32CE_SYSTEM
1031 /* There is a isatty function declaration in cegcc but it does not
1032 make sense, thus we redefine it. */
1034 _gnupg_isatty (int fd)
1042 #ifdef HAVE_W32CE_SYSTEM
1043 /* Replacement for getenv which takes care of the our use of getenv.
1044 The code is not thread safe but we expect it to work in all cases
1045 because it is called for the first time early enough. */
1047 _gnupg_getenv (const char *name)
1049 static int initialized;
1050 static char *assuan_debug;
1054 assuan_debug = read_w32_registry_string (NULL,
1055 "\\Software\\GNU\\libassuan",
1060 if (!strcmp (name, "ASSUAN_DEBUG"))
1061 return assuan_debug;
1066 #endif /*HAVE_W32CE_SYSTEM*/
1069 #ifdef HAVE_W32_SYSTEM
1070 /* Return the user's security identifier from the current process. */
1072 w32_get_user_sid (void)
1076 HANDLE token = NULL;
1077 TOKEN_USER *user = NULL;
1079 DWORD tokenlen, sidlen;
1081 proc = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
1085 if (!OpenProcessToken (proc, TOKEN_QUERY, &token))
1088 if (!GetTokenInformation (token, TokenUser, NULL, 0, &tokenlen)
1089 && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
1092 user = xtrymalloc (tokenlen);
1096 if (!GetTokenInformation (token, TokenUser, user, tokenlen, &tokenlen))
1098 if (!IsValidSid (user->User.Sid))
1100 sidlen = GetLengthSid (user->User.Sid);
1101 sid = xtrymalloc (sidlen);
1104 if (!CopySid (sidlen, sid, user->User.Sid))
1111 CloseHandle (token);
1122 #endif /*HAVE_W32_SYSTEM*/
1126 /* Support for inotify under Linux. */
1128 /* Store a new inotify file handle for SOCKET_NAME at R_FD or return
1131 gnupg_inotify_watch_socket (int *r_fd, const char *socket_name)
1133 #if HAVE_INOTIFY_INIT
1142 return my_error (GPG_ERR_INV_VALUE);
1144 fname = xtrystrdup (socket_name);
1146 return my_error_from_syserror ();
1148 fd = inotify_init ();
1151 err = my_error_from_syserror ();
1156 /* We need to watch the directory for the file because there won't
1157 * be an IN_DELETE_SELF for a socket file. To handle a removal of
1158 * the directory we also watch the directory itself. */
1159 p = strrchr (fname, '/');
1162 if (inotify_add_watch (fd, fname,
1163 (IN_DELETE|IN_DELETE_SELF|IN_EXCL_UNLINK)) == -1)
1165 err = my_error_from_syserror ();
1175 #else /*!HAVE_INOTIFY_INIT*/
1179 return my_error (GPG_ERR_NOT_SUPPORTED);
1181 #endif /*!HAVE_INOTIFY_INIT*/
1185 /* Read an inotify event and return true if it matches NAME or if it
1186 * sees an IN_DELETE_SELF event for the directory of NAME. */
1188 gnupg_inotify_has_name (int fd, const char *name)
1190 #if USE_NPTH && HAVE_INOTIFY_INIT
1191 #define BUFSIZE_FOR_INOTIFY (sizeof (struct inotify_event) + 255 + 1)
1193 struct inotify_event ev;
1194 char _buf[sizeof (struct inotify_event) + 255 + 1];
1196 struct inotify_event *evp;
1199 n = npth_read (fd, &buf, sizeof buf);
1200 /* log_debug ("notify read: n=%d\n", n); */
1202 while (n >= sizeof (struct inotify_event))
1204 /* log_debug (" mask=%x len=%u name=(%s)\n", */
1205 /* evp->mask, (unsigned int)evp->len, evp->len? evp->name:""); */
1206 if ((evp->mask & IN_UNMOUNT))
1208 /* log_debug (" found (dir unmounted)\n"); */
1209 return 3; /* Directory was unmounted. */
1211 if ((evp->mask & IN_DELETE_SELF))
1213 /* log_debug (" found (dir removed)\n"); */
1214 return 2; /* Directory was removed. */
1216 if ((evp->mask & IN_DELETE))
1218 if (evp->len >= strlen (name) && !strcmp (evp->name, name))
1220 /* log_debug (" found (file removed)\n"); */
1221 return 1; /* File was removed. */
1224 n -= sizeof (*evp) + evp->len;
1225 evp = (struct inotify_event *)(void *)
1226 ((char *)evp + sizeof (*evp) + evp->len);
1229 #else /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/
1234 #endif /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/
1236 return 0; /* Not found. */
1240 /* Return a malloc'ed string that is the path to the passed
1241 * unix-domain socket (or return NULL if this is not a valid
1242 * unix-domain socket). We use a plain int here because it is only
1245 * FIXME: This function needs to be moved to libassuan. */
1246 #ifndef HAVE_W32_SYSTEM
1248 gnupg_get_socket_name (int fd)
1250 struct sockaddr_un un;
1251 socklen_t len = sizeof(un);
1254 if (getsockname (fd, (struct sockaddr*)&un, &len) != 0)
1255 log_error ("could not getsockname(%d): %s\n", fd,
1256 gpg_strerror (my_error_from_syserror ()));
1257 else if (un.sun_family != AF_UNIX)
1258 log_error ("file descriptor %d is not a unix-domain socket\n", fd);
1259 else if (len <= offsetof (struct sockaddr_un, sun_path))
1260 log_error ("socket name not present for file descriptor %d\n", fd);
1261 else if (len > sizeof(un))
1262 log_error ("socket name for file descriptor %d was truncated "
1263 "(passed %zu bytes, wanted %u)\n", fd, sizeof(un), len);
1266 size_t namelen = len - offsetof (struct sockaddr_un, sun_path);
1268 /* log_debug ("file descriptor %d has path %s (%zu octets)\n", fd, */
1269 /* un.sun_path, namelen); */
1270 name = xtrymalloc (namelen + 1);
1272 log_error ("failed to allocate memory for name of fd %d: %s\n",
1273 fd, gpg_strerror (my_error_from_syserror ()));
1276 memcpy (name, un.sun_path, namelen);
1283 #endif /*!HAVE_W32_SYSTEM*/