|
|
| version 1.13, 2025/04/02 03:26:22 | version 1.19, 2025/04/10 01:24:38 |
|---|---|
| Line 24 | Line 24 |
| * along with FreeM. If not, see <https://www.gnu.org/licenses/>. | * along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
| * | * |
| * $Log$ | * $Log$ |
| * Revision 1.19 2025/04/10 01:24:38 snw | |
| * Remove C++ style comments | |
| * | |
| * Revision 1.18 2025/04/09 19:52:02 snw | |
| * Eliminate as many warnings as possible while building with -Wall | |
| * | |
| * Revision 1.17 2025/04/04 21:28:16 snw | |
| * Remove custom_user and custom_group vars from freem and shed privileges per environment catalog settings | |
| * | |
| * Revision 1.16 2025/04/04 19:43:18 snw | |
| * Switch to using environment catalog to determine user and group for environment, and remove -u and -g flags from freem | |
| * | |
| * Revision 1.15 2025/04/03 20:48:14 snw | |
| * Improve daemon error diagnostics and bump to 0.63.0-rc3 | |
| * | |
| * Revision 1.14 2025/04/02 04:50:49 snw | |
| * Allow vendor routines to be upgraded | |
| * | |
| * Revision 1.13 2025/04/02 03:26:22 snw | * Revision 1.13 2025/04/02 03:26:22 snw |
| * Don't corrupt the terminal if FreeM runs before fmadm configure has been run | * Don't corrupt the terminal if FreeM runs before fmadm configure has been run |
| * | * |
| Line 59 | Line 77 |
| * SPDX-License-Identifier: AGPL-3.0-or-later | * SPDX-License-Identifier: AGPL-3.0-or-later |
| **/ | **/ |
| #define _GNU_SOURCE | |
| #include <stdlib.h> | #include <stdlib.h> |
| #include <stddef.h> | #include <stddef.h> |
| #include "mpsdef.h" | #include "mpsdef.h" |
| Line 131 int main (int argc, char **argv, char ** | Line 150 int main (int argc, char **argv, char ** |
| gid_t d_gid; | gid_t d_gid; |
| uid_t d_uid; | uid_t d_uid; |
| short custom_user = FALSE; | |
| short custom_group = FALSE; | |
| #if defined(HAVE_GETOPT_LONG) | #if defined(HAVE_GETOPT_LONG) |
| struct option long_options[] = { | struct option long_options[] = { |
| {"help", no_argument, 0, 'h'}, | {"help", no_argument, 0, 'h'}, |
| Line 162 int main (int argc, char **argv, char ** | Line 178 int main (int argc, char **argv, char ** |
| char *symname = (char *) calloc(STRLEN, sizeof(char)); | char *symname = (char *) calloc(STRLEN, sizeof(char)); |
| char *symval = (char *) calloc(STRLEN, sizeof(char)); | char *symval = (char *) calloc(STRLEN, sizeof(char)); |
| int namelen; | |
| int vallen; | |
| char cli_rtn_path[PATH_MAX] = {0}; | char cli_rtn_path[PATH_MAX] = {0}; |
| char *cli_rtn_file; | char *cli_rtn_file; |
| char cli_rtn_name[256]; | char cli_rtn_name[256]; |
| char env_ena[25]; | |
| routine_mode = FALSE; | routine_mode = FALSE; |
| strcpy (m_dialect, "FREEM"); | strcpy (m_dialect, "FREEM"); |
| Line 199 int main (int argc, char **argv, char ** | Line 214 int main (int argc, char **argv, char ** |
| while (1) { | while (1) { |
| c = getopt_long (argc, argv, "hsfiqRr:n:e:vx:dkpS:u:g:", long_options, &option_index); | c = getopt_long (argc, argv, "hsfiqRr:n:e:vx:dkpS", long_options, &option_index); |
| if (c == -1) break; | if (c == -1) break; |
| if (c == '?') freem_usage (); | if (c == '?') freem_usage (); |
| Line 222 int main (int argc, char **argv, char ** | Line 237 int main (int argc, char **argv, char ** |
| break; | break; |
| case 'e': /* specify FreeM environment */ | case 'e': /* specify FreeM environment */ |
| strncpy (shm_env, optarg, 255); | strncpy (shm_env, optarg, sizeof (shm_env) - 1); |
| break; | break; |
| case 'R': | case 'R': |
| Line 312 int main (int argc, char **argv, char ** | Line 327 int main (int argc, char **argv, char ** |
| case 'S': /* --shmsize */ | case 'S': /* --shmsize */ |
| shm_init_size = atol (optarg); | shm_init_size = atol (optarg); |
| break; | break; |
| case 'u': /* --user */ | |
| strncpy (d_username, optarg, 40); | |
| custom_user = TRUE; | |
| break; | |
| case 'g': /* --group */ | |
| strncpy (d_groupname, optarg, 40); | |
| custom_group = TRUE; | |
| break; | |
| } | } |
| Line 335 int main (int argc, char **argv, char ** | Line 339 int main (int argc, char **argv, char ** |
| extern char *optarg; | extern char *optarg; |
| extern int optind, optopt; | extern int optind, optopt; |
| while ((c = getopt (argc, argv, "hsfiqRr:n:e:vx:dkS:u:g:")) != -1) { | while ((c = getopt (argc, argv, "hsfiqRr:n:e:vx:dkS:")) != -1) { |
| if (c == '?') freem_usage (); | if (c == '?') freem_usage (); |
| Line 358 int main (int argc, char **argv, char ** | Line 362 int main (int argc, char **argv, char ** |
| break; | break; |
| case 'e': /* specify FreeM environment */ | case 'e': /* specify FreeM environment */ |
| strncpy (shm_env, optarg, 255); | strncpy (shm_env, optarg, sizeof (shm_env) - 1); |
| break; | break; |
| case 'R': | case 'R': |
| Line 443 int main (int argc, char **argv, char ** | Line 447 int main (int argc, char **argv, char ** |
| shm_init_size = atol (optarg); | shm_init_size = atol (optarg); |
| break; | break; |
| case 'u': /* --user */ | |
| strncpy (d_username, optarg, 40); | |
| custom_user = TRUE; | |
| break; | |
| case 'g': /* --group */ | |
| strncpy (d_groupname, optarg, 40); | |
| custom_group = TRUE; | |
| break; | |
| } | } |
| } | } |
| } | } |
| Line 467 int main (int argc, char **argv, char ** | Line 460 int main (int argc, char **argv, char ** |
| #endif | #endif |
| snprintf (config_file, 4096, "%s/freem/%s/freem.conf", SYSCONFDIR, shm_env); | snprintf (config_file, 4096, "%s/freem/%s/freem.conf", SYSCONFDIR, shm_env); |
| snprintf (env_config_file, 4096, "%s/freem/env.conf", SYSCONFDIR); | |
| if (run_daemon == TRUE && geteuid() == 0) { | if (!file_exists (env_config_file)) { |
| fprintf (stderr, "freem: environment catalog does not exist; may need to run fmadm configure\n"); | |
| exit (1); | |
| } | |
| if (custom_group) { | if (!file_exists (config_file)) { |
| d_grp = getgrnam (d_groupname); | fprintf (stderr, "freem: configuration file for %s does not exist; may need to run fmadm configure\n", shm_env); |
| exit (1); | |
| } | |
| if (d_grp == NULL) { | if (read_profile_string (env_config_file, shm_env, "user", d_username) == FALSE) { |
| fprintf (stderr, "freem: invalid group '%s'\n", d_groupname); | fprintf (stderr, "freem: could not determine owning user for environment %s\n", shm_env); |
| exit (1); | exit (1); |
| } | } |
| d_gid = d_grp->gr_gid; | |
| } | |
| if (custom_user) { | if (read_profile_string (env_config_file, shm_env, "group", d_groupname) == FALSE) { |
| d_user = getpwnam (d_username); | fprintf (stderr, "freem: could not determine owning group for environment %s\n", shm_env); |
| exit (1); | |
| } | |
| if (d_user == NULL) { | if (read_profile_string (env_config_file, shm_env, "enabled", env_ena) == FALSE) { |
| fprintf (stderr, "freem: invalid user '%s'\n", d_username); | fprintf (stderr, "freem: could not discover enabled state for environment %s\n", shm_env); |
| exit (1); | exit (1); |
| } | } |
| d_uid = d_user->pw_uid; | if (strcmp (env_ena, "true") != 0) { |
| } | fprintf (stderr, "freem: environment %s is administratively disabled\n", shm_env); |
| else { | exit (1); |
| d_uid = 0; | } |
| } | |
| d_grp = getgrnam (d_groupname); | |
| if (d_grp == NULL) { | |
| fprintf (stderr, "freem: invalid group '%s'\n", d_groupname); | |
| exit (1); | |
| } | |
| d_gid = d_grp->gr_gid; | |
| d_user = getpwnam (d_username); | |
| if (d_user == NULL) { | |
| fprintf (stderr, "freem: invalid user '%s'\n", d_username); | |
| exit (1); | |
| } | |
| d_uid = d_user->pw_uid; | |
| #if defined(__linux__) | |
| if (run_daemon == FALSE && group_member (d_gid) == 0) { | |
| fprintf (stderr, "freem: you must be a member of the %s group to use environment %s\n", d_groupname, shm_env); | |
| exit (1); | |
| } | |
| #endif | |
| if (run_daemon == TRUE) { | |
| if (geteuid () != 0 && nofork == FALSE) { | |
| fprintf (stderr, "freem: forking daemon must be run as root\n"); | |
| exit (1); | |
| } | |
| } | } |
| if ((nofork == TRUE) && (run_daemon == FALSE)) { | if ((nofork == TRUE) && (run_daemon == FALSE)) { |
| Line 552 int main (int argc, char **argv, char ** | Line 576 int main (int argc, char **argv, char ** |
| if (geteuid () == 0) { | if (geteuid () == 0) { |
| /* shed privileges */ | /* shed privileges */ |
| if (custom_group) { | |
| fprintf (stderr, "freem: switching to group %s\n", d_groupname); | fprintf (stderr, "freem: switching to group %s\n", d_groupname); |
| m_log (1, "switching groups"); | m_log (1, "switching groups"); |
| if (setgid (d_gid) == -1) { | if (setgid (d_gid) == -1) { |
| fprintf (stderr, "freem: failure switching GID\n"); | fprintf (stderr, "freem: failure switching GID\n"); |
| m_log (1, "failure switching GIDs"); | m_log (1, "failure switching GIDs"); |
| exit (1); | exit (1); |
| } | |
| } | } |
| if (custom_user) { | if (d_uid != geteuid ()) { |
| fprintf (stderr, "freem: switching to username %s\n", d_username); | fprintf (stderr, "freem: switching to username %s\n", d_username); |
| m_log (1, "switching users"); | m_log (1, "switching users"); |
| Line 600 int main (int argc, char **argv, char ** | Line 624 int main (int argc, char **argv, char ** |
| errsav = errno; | errsav = errno; |
| if (pid_fd < 0) { | if (pid_fd < 0) { |
| fprintf (stderr, "freem: could not open PID file %s [%s]\n", pid_file_path, strerror (errsav)); | |
| m_log (1, "freem: could not open PID file"); | m_log (1, "freem: could not open PID file"); |
| m_log (1, strerror (errsav)); | m_log (1, strerror (errsav)); |
| exit (1); | exit (1); |
| Line 607 int main (int argc, char **argv, char ** | Line 632 int main (int argc, char **argv, char ** |
| if (lockf (pid_fd, F_TLOCK, 0) < 0) { | if (lockf (pid_fd, F_TLOCK, 0) < 0) { |
| errsav = errno; | errsav = errno; |
| fprintf (stderr, "freem: could not lock PID file [%s]\n", strerror (errsav)); | |
| m_log (1, "freem: could not lock PID file - perhaps already running?"); | m_log (1, "freem: could not lock PID file - perhaps already running?"); |
| m_log (1, strerror (errsav)); | m_log (1, strerror (errsav)); |
| exit (1); | exit (1); |
| Line 644 int main (int argc, char **argv, char ** | Line 670 int main (int argc, char **argv, char ** |
| skip_init = 1; | skip_init = 1; |
| /* initialize FreeM environment */ | /* initialize FreeM environment */ |
| strncpy (nsnbuf, nsname, 255); | strncpy (nsnbuf, nsname, sizeof (nsnbuf)); |
| if (init (nsnbuf) == FALSE) { | if (init (nsnbuf) == FALSE) { |
| set_io (UNIX); | if (fm_initialized) set_io (UNIX); |
| fprintf (stderr, "\nError initializing FreeM.\n"); | fprintf (stderr, "\nError initializing FreeM.\n"); |
| exit (1); | exit (1); |
| Line 682 int main (int argc, char **argv, char ** | Line 708 int main (int argc, char **argv, char ** |
| /* isolate the path from the routine file */ | /* isolate the path from the routine file */ |
| strncpy (cli_rtn_path, argv[optind], strrchr (argv[optind], '/') - argv[optind]); | strncpy (cli_rtn_path, argv[optind], strrchr (argv[optind], '/') - argv[optind]); |
| /* set_io (UNIX); | |
| printf ("cli_rtn_name = '%s' cli_rtn_path = '%s'\n", cli_rtn_name, cli_rtn_path); | |
| set_io (MUMPS); | |
| */ | |
| } | } |
| /* do we have a file extension? */ | /* do we have a file extension? */ |
| Line 735 int main (int argc, char **argv, char ** | Line 757 int main (int argc, char **argv, char ** |
| if (!skip_init) { | if (!skip_init) { |
| /* initialize FreeM environment */ | /* initialize FreeM environment */ |
| strncpy (nsnbuf, nsname, 255); | strncpy (nsnbuf, nsname, sizeof (nsnbuf)); |
| if (init (nsnbuf) == FALSE) { | if (init (nsnbuf) == FALSE) { |
| set_io (UNIX); | set_io (UNIX); |
| fprintf (stderr, "\nError initializing FreeM.\n"); | fprintf (stderr, "\nError initializing FreeM.\n"); |
| Line 844 int main (int argc, char **argv, char ** | Line 866 int main (int argc, char **argv, char ** |
| #if !defined(_AIX) | #if !defined(_AIX) |
| if(import_env == TRUE) { | if (import_env == TRUE) { |
| int i_maxlen = 255; | int i_maxlen = 255; |
| for(env = envp; *env != 0; env++) { | for (env = envp; *env != 0; env++) { |
| varname = strtok (*env, "="); | |
| namelen = 0; | varval = strtok (NULL, "="); |
| vallen = 0; | |
| varname = strtok(*env, "="); | |
| varval = strtok(NULL, "="); | |
| if(varval != NULL) { | |
| namelen = strlen (varname); | |
| vallen = strlen (varval); | |
| if (varval != NULL) { | |
| snprintf (symname, i_maxlen, "ENV.%s\201\201", varname); | snprintf (symname, i_maxlen, "ENV.%s\201\201", varname); |
| strncpy (symval, varval, i_maxlen); | strncpy (symval, varval, i_maxlen - 1); |
| stcnv_c2m (symval); | stcnv_c2m (symval); |