aboutsummaryrefslogtreecommitdiff
path: root/src/util/os_installation.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-07-07 16:02:57 +0000
committerChristian Grothoff <christian@grothoff.org>2011-07-07 16:02:57 +0000
commit9e7b81a3cbc81c555811c2a9386e340570612f36 (patch)
treedd0302e4a65278c26fc2f0d16853c254941d247d /src/util/os_installation.c
parent1c5ace41aa144afd32221db565c6f627765afdd0 (diff)
downloadgnunet-9e7b81a3cbc81c555811c2a9386e340570612f36.tar.gz
gnunet-9e7b81a3cbc81c555811c2a9386e340570612f36.zip
move SUID test code to util
Diffstat (limited to 'src/util/os_installation.c')
-rw-r--r--src/util/os_installation.c80
1 files changed, 76 insertions, 4 deletions
diff --git a/src/util/os_installation.c b/src/util/os_installation.c
index cbbc61433..ac5688aab 100644
--- a/src/util/os_installation.c
+++ b/src/util/os_installation.c
@@ -193,8 +193,15 @@ get_path_from_dyld_image ()
193} 193}
194#endif 194#endif
195 195
196/**
197 * Return the actual path to a file found in the current
198 * PATH environment variable.
199 *
200 * @param binary the name of the file to find
201 * @return path to binary, NULL if not found
202 */
196static char * 203static char *
197get_path_from_PATH () 204get_path_from_PATH (const char *binary)
198{ 205{
199 char *path; 206 char *path;
200 char *pos; 207 char *pos;
@@ -212,7 +219,7 @@ get_path_from_PATH ()
212 while (NULL != (end = strchr (pos, PATH_SEPARATOR))) 219 while (NULL != (end = strchr (pos, PATH_SEPARATOR)))
213 { 220 {
214 *end = '\0'; 221 *end = '\0';
215 sprintf (buf, "%s/%s", pos, "gnunet-arm"); 222 sprintf (buf, "%s/%s", pos, binary);
216 if (GNUNET_DISK_file_test (buf) == GNUNET_YES) 223 if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
217 { 224 {
218 pos = GNUNET_strdup (pos); 225 pos = GNUNET_strdup (pos);
@@ -222,7 +229,7 @@ get_path_from_PATH ()
222 } 229 }
223 pos = end + 1; 230 pos = end + 1;
224 } 231 }
225 sprintf (buf, "%s/%s", pos, "gnunet-arm"); 232 sprintf (buf, "%s/%s", pos, binary);
226 if (GNUNET_DISK_file_test (buf) == GNUNET_YES) 233 if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
227 { 234 {
228 pos = GNUNET_strdup (pos); 235 pos = GNUNET_strdup (pos);
@@ -281,7 +288,7 @@ os_get_gnunet_path ()
281 if (ret != NULL) 288 if (ret != NULL)
282 return ret; 289 return ret;
283#endif 290#endif
284 ret = get_path_from_PATH (); 291 ret = get_path_from_PATH ("gnunet-arm");
285 if (ret != NULL) 292 if (ret != NULL)
286 return ret; 293 return ret;
287 /* other attempts here */ 294 /* other attempts here */
@@ -430,4 +437,69 @@ GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind)
430 return tmp; 437 return tmp;
431} 438}
432 439
440
441/**
442 * Check whether the suid bit is set on a file.
443 * Attempts to find the file using the current
444 * PATH environment variable as a search path.
445 *
446 * @param binary the name of the file to check
447 * @return GNUNET_YES if the file is SUID,
448 * GNUNET_NO if not,
449 * GNUNET_SYSERR on error
450 */
451int
452GNUNET_OS_check_helper_binary (const char *binary)
453{
454 struct stat statbuf;
455 char *p;
456#ifdef MINGW
457 SOCKET rawsock;
458 char *binaryexe;
459
460 GNUNET_asprintf (&binaryexe, "%s.exe", binary);
461 p = get_path_from_PATH (binaryexe);
462 free (binaryexe);
463#else
464 p = get_path_from_PATH (binary);
465#endif
466 if (p == NULL)
467 {
468 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
469 "tcp",
470 _("Could not find binary `%s' in PATH!\n"),
471 binary);
472 return GNUNET_NO;
473 }
474 if (0 != STAT (p, &statbuf))
475 {
476 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
477 _("stat (%s) failed: %s\n"),
478 p,
479 STRERROR (errno));
480 GNUNET_free (p);
481 return GNUNET_SYSERR;
482 }
483 GNUNET_free (p);
484#ifndef MINGW
485 if ( (0 != (statbuf.st_mode & S_ISUID)) &&
486 (statbuf.st_uid == 0) )
487 return GNUNET_YES;
488 return GNUNET_NO;
489#else
490 rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
491 if (INVALID_SOCKET == rawsock)
492 {
493 DWORD err = GetLastError ();
494 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
495 "tcp",
496 "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) failed! GLE = %d\n", err);
497 return GNUNET_NO; /* not running as administrator */
498 }
499 closesocket (rawsock);
500 return GNUNET_YES;
501#endif
502}
503
504
433/* end of os_installation.c */ 505/* end of os_installation.c */