diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-07-07 16:02:57 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-07-07 16:02:57 +0000 |
commit | 9e7b81a3cbc81c555811c2a9386e340570612f36 (patch) | |
tree | dd0302e4a65278c26fc2f0d16853c254941d247d /src/util/os_installation.c | |
parent | 1c5ace41aa144afd32221db565c6f627765afdd0 (diff) | |
download | gnunet-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.c | 80 |
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 | */ | ||
196 | static char * | 203 | static char * |
197 | get_path_from_PATH () | 204 | get_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 | */ | ||
451 | int | ||
452 | GNUNET_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 */ |