Ejemplo n.º 1
0
static void
amgtar_selfcheck(
    application_argument_t *argument)
{
    amgtar_build_exinclude(&argument->dle, 1, NULL, NULL, NULL, NULL);

    printf("OK amgtar\n");
    if (gnutar_path) {
	check_file(gnutar_path, X_OK);
    } else {
	printf(_("ERROR [GNUTAR program not available]\n"));
    }

    set_root_privs(1);
    if (gnutar_listdir && strlen(gnutar_listdir) == 0)
	gnutar_listdir = NULL;
    if (gnutar_listdir) {
	check_dir(gnutar_listdir, R_OK|W_OK);
    } else {
	printf(_("ERROR [No GNUTAR-LISTDIR]\n"));
    }

    if (argument->dle.disk) {
	char *qdisk = quote_string(argument->dle.disk);
	fprintf(stdout, "OK %s\n", qdisk);
	amfree(qdisk);
    }
    if (gnutar_directory) {
	check_dir(gnutar_directory, R_OK);
    } else if (argument->dle.device) {
	check_dir(argument->dle.device, R_OK);
    }
    set_root_privs(0);
}
Ejemplo n.º 2
0
/*
 * Forks a bsdtcp to the host listed in rc->hostname
 * Returns negative on error, with an errmsg in rc->errmsg.
 */
static int
runbsdtcp(
    struct sec_handle *	rh,
    in_port_t port)
{
    int			server_socket;
    in_port_t		my_port;
    struct tcp_conn *	rc = rh->rc;

    set_root_privs(1);

    server_socket = stream_client_privileged(rc->hostname,
				     port,
				     STREAM_BUFSIZE,
				     STREAM_BUFSIZE,
				     &my_port,
				     0);
    set_root_privs(0);

    if(server_socket < 0) {
	security_seterror(&rh->sech,
	    "%s", strerror(errno));
	
	return -1;
    }

    if(my_port >= IPPORT_RESERVED) {
	security_seterror(&rh->sech,
			  _("did not get a reserved port: %d"), my_port);
    }

    rc->read = rc->write = server_socket;
    return 0;
}
Ejemplo n.º 3
0
off_t
final_size_dump(
    int		level,
    char *	topdir)
{
    struct fs_usage fsusage;
    off_t mapsize;
    char *s;
    int   rc;
    int   saved_errno;

    /* calculate the map sizes */

    s = g_strconcat(topdir, "/.", NULL);
    set_root_privs(1);
    rc = get_fs_usage(s, NULL, &fsusage);
    saved_errno = errno;
    set_root_privs(0);

    if (rc == -1) {
	error("statfs %s: %s", s, strerror(saved_errno));
	/*NOTREACHED*/
    }
    amfree(s);

    mapsize = (fsusage.fsu_files + (off_t)7) / (off_t)8;    /* in bytes */
    mapsize = (mapsize + (off_t)1023) / (off_t)1024;  /* in kbytes */

    /* the dump contains three maps plus the files */

    return (mapsize * (off_t)3) + dumpstats[level].total_size;
}
Ejemplo n.º 4
0
static void
amstar_selfcheck(
    application_argument_t *argument)
{
    fprintf(stdout, "OK amstar\n");
    if (argument->dle.disk) {
	char *qdisk = quote_string(argument->dle.disk);
	fprintf(stdout, "OK %s\n", qdisk);
	amfree(qdisk);
    }
    if (argument->dle.device) {
	char *qdevice = quote_string(argument->dle.device);
	fprintf(stdout, "OK %s\n", qdevice);
	amfree(qdevice);
    }
    if (star_directory) {
	char *qdirectory = quote_string(star_directory);
	fprintf(stdout, "OK %s\n", qdirectory);
	amfree(qdirectory);
    }

    if (argument->dle.include_list &&
	argument->dle.include_list->nb_element >= 0) {
	fprintf(stdout, "ERROR include-list not supported for backup\n");
    }

    if (!star_path) {
	fprintf(stdout, "ERROR STAR-PATH not defined\n");
    } else {
	check_file(star_path, X_OK);
    }

    if (argument->calcsize) {
	char *calcsize = vstralloc(amlibexecdir, "/", "calcsize", NULL);
	check_file(calcsize, X_OK);
	check_suid(calcsize);
	amfree(calcsize);
    }

    {
	char *amandates_file;
	amandates_file = getconf_str(CNF_AMANDATES);
	check_file(amandates_file, R_OK|W_OK);
    }

    set_root_privs(1);
    if (argument->dle.device) {
	check_dir(argument->dle.device, R_OK);
    }
    set_root_privs(0);
}
Ejemplo n.º 5
0
/*
 * Forks a krb5 to the host listed in rc->hostname
 * Returns negative on error, with an errmsg in rc->errmsg.
 */
static int
runkrb5(
    struct sec_handle *	rh)
{
    struct servent *	sp;
    int			server_socket;
    in_port_t		my_port, port;
    struct tcp_conn *	rc = rh->rc;
    const char *err;

    if ((sp = getservbyname(AMANDA_KRB5_SERVICE_NAME, "tcp")) == NULL)
	port = htons(AMANDA_KRB5_DEFAULT_PORT);
    else
	port = sp->s_port;

    if ((err = get_tgt(keytab_name, principal_name)) != NULL) {
        security_seterror(&rh->sech, "%s: could not get TGT: %s",
            rc->hostname, err);
        return -1;
    }

    set_root_privs(1);
    server_socket = stream_client(rc->hostname,
				     (in_port_t)(ntohs(port)),
				     STREAM_BUFSIZE,
				     STREAM_BUFSIZE,
				     &my_port,
				     0);
    set_root_privs(0);

    if(server_socket < 0) {
	security_seterror(&rh->sech,
	    "%s", strerror(errno));
	
	return -1;
    }

    rc->read = rc->write = server_socket;

    if (gss_client(rh) < 0) {
	return -1;
    }


    return 0;
}
Ejemplo n.º 6
0
/*
 * Forks a bsdtcp to the host listed in rc->hostname
 * Returns negative on error, with an errmsg in rc->errmsg.
 */
static int
runbsdtcp(
    struct sec_handle *	rh,
    const char *src_ip,
    in_port_t port)
{
    int			server_socket;
    in_port_t		my_port;
    struct tcp_conn *	rc = rh->rc;

    set_root_privs(1);

    server_socket = stream_client_addr(src_ip,
				     rh->next_res,
				     port,
				     STREAM_BUFSIZE,
				     STREAM_BUFSIZE,
				     &my_port,
				     0,
				     1);
    set_root_privs(0);
    rh->next_res = rh->next_res->ai_next;

    if(server_socket < 0) {
	security_seterror(&rh->sech,
	    "%s", strerror(errno));
	return -1;
    }

    if(my_port >= IPPORT_RESERVED) {
	security_seterror(&rh->sech,
			  _("did not get a reserved port: %d"), my_port);
    }

    rc->read = rc->write = server_socket;
    return 0;
}
Ejemplo n.º 7
0
int
main(
    int		argc,
    char **	argv)
{
    config_overrides_t *cfg_ovr;
    char *hostname;
    char *auth;
    char *service;
    int opt;
    extern int optind;
    extern char *optarg;
    FILE *input_file;
    int use_connect = 0;
    int got_input_file = 0;

    /*
     * Configure program for internationalization:
     *   1) Only set the message locale for now.
     *   2) Set textdomain for all amanda related programs to "amanda"
     *      We don't want to be forced to support dozens of message catalogs.
     */  
    setlocale(LC_MESSAGES, "C");
    textdomain("amanda"); 

    safe_fd(-1, 0);
    safe_cd();

    set_pname("amservice");
    /* drop root privileges */
    if (!set_root_privs(0)) {
	error(_("amservice must be run setuid root"));
    }

    /* Don't die when child closes pipe */
    signal(SIGPIPE, SIG_IGN);

    dbopen(DBG_SUBDIR_SERVER);

    add_amanda_log_handler(amanda_log_stderr);

    our_features = am_init_feature_set();
    our_feature_string = am_feature_to_string(our_features);

    /* process arguments */

    cfg_ovr = new_config_overrides(argc/2);
    input_file = stdin;
    while((opt = getopt_long(argc, argv, "o:f:s", long_options, NULL)) != EOF) {
	switch(opt) {
	case 1:		printf("amservice-%s\n", VERSION);
			return(0);
			break;
	case 'o':	add_config_override_opt(cfg_ovr, optarg);
			break;
	case 'f':	if (got_input_file == 1) {
			    g_critical("Invalid two -f argument");
			    exit(1);
			}
			got_input_file = 1;
			if (*optarg == '/') {
			    input_file = fopen(optarg, "r");
			} else {
			    char *name = g_strjoin(NULL, get_original_cwd(), "/",
						   optarg, NULL);
			    input_file = fopen(name, "r");
			    amfree(name);
			}
			if (!input_file) {
			    g_critical("Cannot open output file '%s': %s",
				optarg, strerror(errno));
			    exit(1);
			}
			break;
	case 's':	use_connect = 1;
			break;
	}
    }

    if (use_connect && !got_input_file) {
	g_critical("The -s option require -f");
	exit(1);
    }

    argc -= optind, argv += optind;
    if(argc < 3) usage();

    /* set a default config */
    set_config_overrides(cfg_ovr);
    config_init(CONFIG_INIT_CLIENT, NULL);
    dbrename(get_config_name(), DBG_SUBDIR_SERVER);

    if (config_errors(NULL) >= CFGERR_WARNINGS) {
	config_print_errors();
	if (config_errors(NULL) >= CFGERR_ERRORS) {
	    g_critical(_("errors processing config file"));
	}
    }

    conf_ctimeout = (time_t)getconf_int(CNF_CTIMEOUT);

    hostname = argv[0];
    auth = argv[1];
    service = argv[2];

    /* start client side checks */

    copy_stream = use_connect && got_input_file;
    client_protocol(hostname, auth, service, input_file);

    amfree(our_feature_string);
    am_release_feature_set(our_features);
    our_features = NULL;
    if (got_input_file)
	fclose(input_file);

    dbclose();
    return(remote_errors != 0);
}
Ejemplo n.º 8
0
/*
 * Forks a ssh to the host listed in rc->hostname
 * Returns negative on error, with an errmsg in rc->errmsg.
 */
static int
runssh(
    struct tcp_conn *	rc,
    const char *	amandad_path,
    const char *	client_username,
    const char *	ssh_keys,
    const char *        client_port)
{
    int rpipe[2], wpipe[2];
    char *xamandad_path = (char *)amandad_path;
    char *xclient_username = (char *)client_username;
    char *xssh_keys = (char *)ssh_keys;
    char *xclient_port = (char *)client_port;
    GPtrArray *myargs;
    gchar *ssh_options[100] = {SSH_OPTIONS, NULL};
    gchar **ssh_option;
    gchar *cmd;

    memset(rpipe, -1, sizeof(rpipe));
    memset(wpipe, -1, sizeof(wpipe));
    if (pipe(rpipe) < 0 || pipe(wpipe) < 0) {
	g_free(rc->errmsg);
	rc->errmsg = g_strdup_printf(_("pipe: %s"), strerror(errno));
	return (-1);
    }

    if(!xamandad_path || strlen(xamandad_path) <= 1) 
	xamandad_path = g_strjoin(NULL, amlibexecdir, "/", "amandad", NULL);
    if(!xclient_username || strlen(xclient_username) <= 1)
	xclient_username = CLIENT_LOGIN;
    if(!xclient_port || strlen(xclient_port) <= 1)
	xclient_port = NULL;

    myargs = g_ptr_array_sized_new(20);
    g_ptr_array_add(myargs, SSH);
    for (ssh_option = ssh_options; *ssh_option != NULL; ssh_option++) {
	g_ptr_array_add(myargs, *ssh_option);
    }
    g_ptr_array_add(myargs, "-l");
    g_ptr_array_add(myargs, xclient_username);
    if (xclient_port) {
	g_ptr_array_add(myargs, "-p");
	g_ptr_array_add(myargs, xclient_port);
    }
    if (ssh_keys && strlen(ssh_keys) > 1) {
	g_ptr_array_add(myargs, "-i");
	g_ptr_array_add(myargs, xssh_keys);
    }
    g_ptr_array_add(myargs, rc->hostname);
    g_ptr_array_add(myargs, xamandad_path);
    g_ptr_array_add(myargs, "-auth=ssh");
    g_ptr_array_add(myargs, NULL);

    cmd = g_strjoinv(" ", (gchar **)myargs->pdata);
    g_debug("exec: %s", cmd);
    g_free(cmd);

    switch (rc->pid = fork()) {
    case -1:
	g_free(rc->errmsg);
	rc->errmsg = g_strdup_printf(_("fork: %s"), strerror(errno));
	aclose(rpipe[0]);
	aclose(rpipe[1]);
	aclose(wpipe[0]);
	aclose(wpipe[1]);
	return (-1);
    case 0:
	dup2(wpipe[0], 0);
	dup2(rpipe[1], 1);
	break;
    default:
	rc->read = rpipe[0];
	aclose(rpipe[1]);
	rc->write = wpipe[1];
	aclose(wpipe[0]);
	rc->child_watch = new_child_watch_source(rc->pid);
	g_source_set_callback(rc->child_watch,
            (GSourceFunc)ssh_child_watch_callback, rc, NULL);
	g_source_attach(rc->child_watch, NULL);
	g_source_unref(rc->child_watch);

	return (0);
    }

    /* drop root privs for good */
    set_root_privs(-1);

    safe_fd(-1, 0);

    execvp(SSH, (gchar **)myargs->pdata);

    error("error: couldn't exec %s: %s", SSH, strerror(errno));

    /* should never go here, shut up compiler warning */
    return(-1);
}
Ejemplo n.º 9
0
void
traverse_dirs(
    char *	parent_dir,
    char *	include)
{
    DIR *d;
    struct dirent *f;
    struct stat finfo;
    char *dirname, *newname = NULL;
    char *newbase = NULL;
    dev_t parent_dev = (dev_t)0;
    int i;
    size_t l;
    size_t parent_len;
    int has_exclude;
    char *aparent;

    if(parent_dir == NULL || include == NULL)
	return;

    has_exclude = !is_empty_sl(exclude_sl) && (use_gtar_excl || use_star_excl);
    aparent = g_strjoin(NULL, parent_dir, "/", include, NULL);

    /* We (may) need root privs for the *stat() calls here. */
    set_root_privs(1);
    if(stat(parent_dir, &finfo) != -1)
	parent_dev = finfo.st_dev;

    parent_len = strlen(parent_dir);

    push_name(aparent);

    for(; (dirname = pop_name()) != NULL; free(dirname)) {
	if(has_exclude && calc_check_exclude(dirname+parent_len+1)) {
	    continue;
	}
	if((d = opendir(dirname)) == NULL) {
	    perror(dirname);
	    continue;
	}

	l = strlen(dirname);
	if(l > 0 && dirname[l - 1] != '/') {
	    g_free(newbase);
	    newbase = g_strconcat(dirname, "/", NULL);
	} else {
	    g_free(newbase);
	    newbase = g_strdup(dirname);
	}

	while((f = readdir(d)) != NULL) {
	    int is_symlink = 0;
	    int is_dir;
	    int is_file;
	    if(is_dot_or_dotdot(f->d_name)) {
		continue;
	    }

	    g_free(newname);
	    newname = g_strconcat(newbase, f->d_name, NULL);
	    if(lstat(newname, &finfo) == -1) {
		g_fprintf(stderr, "%s/%s: %s\n",
			dirname, f->d_name, strerror(errno));
		continue;
	    }

	    if(finfo.st_dev != parent_dev)
		continue;

#ifdef S_IFLNK
	    is_symlink = ((finfo.st_mode & S_IFMT) == S_IFLNK);
#endif
	    is_dir = ((finfo.st_mode & S_IFMT) == S_IFDIR);
	    is_file = ((finfo.st_mode & S_IFMT) == S_IFREG);

	    if (!(is_file || is_dir || is_symlink)) {
		continue;
	    }

	    {
		int is_excluded = -1;
		for(i = 0; i < ndumps; i++) {
		    add_file_name(i, newname);
		    if(is_file && (time_t)finfo.st_ctime >= dumpdate[i]) {

			if(has_exclude) {
			    if(is_excluded == -1)
				is_excluded =
				       calc_check_exclude(newname+parent_len+1);
			    if(is_excluded == 1) {
				i = ndumps;
				continue;
			    }
			}
			add_file(i, &finfo);
		    }
		}
		if(is_dir) {
		    if(has_exclude && calc_check_exclude(newname+parent_len+1))
			continue;
		    push_name(newname);
		}
	    }
	}

#ifdef CLOSEDIR_VOID
	closedir(d);
#else
	if(closedir(d) == -1)
	    perror(dirname);
#endif
    }

    /* drop root privs -- we're done with the permission-sensitive calls */
    set_root_privs(0);

    amfree(newbase);
    amfree(newname);
    amfree(aparent);
}
Ejemplo n.º 10
0
int
main(
    int		argc,
    char **	argv)
{
#ifdef TEST
/* standalone test to ckeck wether the calculated file size is ok */
    struct stat finfo;
    int i;
    off_t dump_total = (off_t)0;
    off_t gtar_total = (off_t)0;
    char *d;
    int l, w;

    /*
     * Configure program for internationalization:
     *   1) Only set the message locale for now.
     *   2) Set textdomain for all amanda related programs to "amanda"
     *      We don't want to be forced to support dozens of message catalogs.
     */  
    setlocale(LC_MESSAGES, "C");
    textdomain("amanda"); 

    safe_fd(-1, 0);

    set_pname("calcsize");

    dbopen(NULL);
    config_init(CONFIG_INIT_CLIENT, NULL);

    /* Don't die when child closes pipe */
    signal(SIGPIPE, SIG_IGN);

    if (argc < 2) {
	g_fprintf(stderr,_("Usage: %s file[s]\n"),argv[0]);
	return 1;
    }
    for(i=1; i<argc; i++) {
	if(lstat(argv[i], &finfo) == -1) {
	    g_fprintf(stderr, "%s: %s\n", argv[i], strerror(errno));
	    continue;
	}
	g_printf("%s: st_size=%lu", argv[i],(unsigned long)finfo.st_size);
	g_printf(": blocks=%llu\n", ST_BLOCKS(finfo));
	dump_total += (ST_BLOCKS(finfo) + (off_t)1) / (off_t)2 + (off_t)1;
	gtar_total += ROUND(4,(ST_BLOCKS(finfo) + (off_t)1));
    }
    g_printf("           gtar           dump\n");
    g_printf("total      %-9lu         %-9lu\n",gtar_total,dump_total);
    return 0;
#else
    int i;
    char *dirname=NULL;
    char *amname=NULL, *qamname=NULL;
    char *filename=NULL, *qfilename = NULL;

    if (argc > 1 && argv[1] && g_str_equal(argv[1], "--version")) {
	printf("calcsize-%s\n", VERSION);
	return (0);
    }

    safe_fd(-1, 0);
    safe_cd();

    set_pname("calcsize");

    dbopen(DBG_SUBDIR_CLIENT);
    config_init(CONFIG_INIT_CLIENT, NULL);
    dbprintf(_("version %s\n"), VERSION);

    /* drop root privileges; we'll regain them for the required operations */
#ifdef WANT_SETUID_CLIENT
    check_running_as(RUNNING_AS_CLIENT_LOGIN | RUNNING_AS_UID_ONLY);
    if (!set_root_privs(0)) {
	error(_("calcsize must be run setuid root"));
    }
#else
    check_running_as(RUNNING_AS_CLIENT_LOGIN);
#endif

    argc--, argv++;	/* skip program name */

    /* need at least program, amname, and directory name */

    if(argc < 4) {
	error(_("Usage: %s config [DUMP|STAR|GNUTAR] name dir [-X exclude-file] [-I include-file] [level date]*"),
	      get_pname());
        /*NOTREACHED*/
    }

    dbprintf(_("config: %s\n"), *argv);
    if (!g_str_equal(*argv, "NOCONFIG")) {
	dbrename(*argv, DBG_SUBDIR_CLIENT);
    }
    argc--;
    argv++;

    /* parse backup program name */

    if(g_str_equal(*argv, "DUMP")) {
#if !defined(DUMP) && !defined(XFSDUMP)
	error("dump not available on this system");
	/*NOTREACHED*/
#else
	add_file_name = add_file_name_dump;
	add_file = add_file_dump;
	final_size = final_size_dump;
#endif
    }
    else if(g_str_equal(*argv, "GNUTAR")) {
#ifndef GNUTAR
	error("gnutar not available on this system");
	/*NOTREACHED*/
#else
	add_file_name = add_file_name_gnutar;
	add_file = add_file_gnutar;
	final_size = final_size_gnutar;
	use_gtar_excl++;
#endif
    }
    else {
	add_file_name = add_file_name_unknown;
	add_file = add_file_unknown;
	final_size = final_size_unknown;
    }
    argc--, argv++;

    /* the amanda name can be different from the directory name */

    if (argc > 0) {
	amname = *argv;
	qamname = quote_string(amname);
	argc--, argv++;
    } else {
	error("missing <name>");
	/*NOTREACHED*/
    }

    /* the toplevel directory name to search from */
    if (argc > 0) {
	dirname = *argv;
	argc--, argv++;
    } else {
	error("missing <dir>");
	/*NOTREACHED*/
    }

    if ((argc > 1) && g_str_equal(*argv, "-X")) {
	argv++;

	if (!(use_gtar_excl || use_star_excl)) {
	  error("exclusion specification not supported");
	  /*NOTREACHED*/
	}
	
	filename = g_strdup(*argv);
	qfilename = quote_string(filename);
	if (access(filename, R_OK) != 0) {
	    g_fprintf(stderr,"Cannot open exclude file %s\n", qfilename);
	    use_gtar_excl = use_star_excl = 0;
	} else {
	    exclude_sl = calc_load_file(filename);
	    if (!exclude_sl) {
		g_fprintf(stderr,"Cannot open exclude file %s: %s\n", qfilename,
			strerror(errno));
		use_gtar_excl = use_star_excl = 0;
	    }
	}
	amfree(qfilename);
	amfree(filename);
	argc -= 2;
	argv++;
    } else {
	use_gtar_excl = use_star_excl = 0;
    }

    if ((argc > 1) && g_str_equal(*argv, "-I")) {
	argv++;
	
	filename = g_strdup(*argv);
	qfilename = quote_string(filename);
	if (access(filename, R_OK) != 0) {
	    g_fprintf(stderr,"Cannot open include file %s\n", qfilename);
	    use_gtar_excl = use_star_excl = 0;
	} else {
	    include_sl = calc_load_file(filename);
	    if (!include_sl) {
		g_fprintf(stderr,"Cannot open include file %s: %s\n", qfilename,
			strerror(errno));
		use_gtar_excl = use_star_excl = 0;
	    }
	}
	amfree(qfilename);
	amfree(filename);
	argc -= 2;
	argv++;
    }

    /* the dump levels to calculate sizes for */

    ndumps = 0;
    while(argc >= 2) {
	if(ndumps < MAXDUMPS) {
	    dumplevel[ndumps] = atoi(argv[0]);
	    dumpdate [ndumps] = (time_t) atol(argv[1]);
	    ndumps++;
	    argc -= 2, argv += 2;
	}
    }

    if(argc) {
	error("leftover arg \"%s\", expected <level> and <date>", *argv);
	/*NOTREACHED*/
    }

    if(is_empty_sl(include_sl)) {
	traverse_dirs(dirname,".");
    }
    else {
	sle_t *an_include = include_sl->first;
	while(an_include != NULL) {
/*
	    char *adirname = stralloc2(dirname, an_include->name+1);
	    traverse_dirs(adirname);
	    amfree(adirname);
*/
	    traverse_dirs(dirname, an_include->name);
	    an_include = an_include->next;
	}
    }
    for(i = 0; i < ndumps; i++) {

	amflock(1, "size");

	dbprintf("calcsize: %s %d SIZE %lld\n",
	       qamname, dumplevel[i],
	       (long long)final_size(i, dirname));
	g_fprintf(stderr, "%s %d SIZE %lld\n",
	       qamname, dumplevel[i],
	       (long long)final_size(i, dirname));
	fflush(stderr);

	amfunlock(1, "size");
    }
    amfree(qamname);

    return 0;
#endif
}
Ejemplo n.º 11
0
int
main(
    int		argc,
    char **	argv)
{
    int c;
    char *command;
    application_argument_t argument;
    int i;

#ifdef GNUTAR
    gnutar_path = GNUTAR;
#else
    gnutar_path = NULL;
#endif
    gnutar_directory = NULL;
    gnutar_onefilesystem = 1;
    gnutar_atimepreserve = 1;
    gnutar_checkdevice = 1;
    gnutar_sparse = 1;
    gnutar_no_unquote = 0;
    exit_handling = NULL;

    /* initialize */

    /*
     * Configure program for internationalization:
     *   1) Only set the message locale for now.
     *   2) Set textdomain for all amanda related programs to "amanda"
     *      We don't want to be forced to support dozens of message catalogs.
     */
    setlocale(LC_MESSAGES, "C");
    textdomain("amanda");

    if (argc < 2) {
        printf("ERROR no command given to amgtar\n");
        error(_("No command given to amgtar"));
    }

    /* drop root privileges */
    if (!set_root_privs(0)) {
	if (strcmp(argv[1], "selfcheck") == 0) {
	    printf("ERROR amgtar must be run setuid root\n");
	}
	error(_("amgtar must be run setuid root"));
    }

    safe_fd(3, 2);

    set_pname("amgtar");

    /* Don't die when child closes pipe */
    signal(SIGPIPE, SIG_IGN);

#if defined(USE_DBMALLOC)
    malloc_size_1 = malloc_inuse(&malloc_hist_1);
#endif

    add_amanda_log_handler(amanda_log_stderr);
    add_amanda_log_handler(amanda_log_syslog);
    dbopen(DBG_SUBDIR_CLIENT);
    startclock();
    dbprintf(_("version %s\n"), version());

    config_init(CONFIG_INIT_CLIENT, NULL);

    //check_running_as(RUNNING_AS_DUMPUSER_PREFERRED);
    //root for amrecover
    //RUNNING_AS_CLIENT_LOGIN from selfcheck, sendsize, sendbackup

    /* parse argument */
    command = argv[1];

    argument.config     = NULL;
    argument.host       = NULL;
    argument.message    = 0;
    argument.collection = 0;
    argument.calcsize   = 0;
    argument.tar_blocksize = NULL;
    argument.level      = NULL;
    init_dle(&argument.dle);

    while (1) {
	int option_index = 0;
    	c = getopt_long (argc, argv, "", long_options, &option_index);
	if (c == -1) {
	    break;
	}
	switch (c) {
	case 1: argument.config = stralloc(optarg);
		break;
	case 2: argument.host = stralloc(optarg);
		break;
	case 3: argument.dle.disk = stralloc(optarg);
		break;
	case 4: argument.dle.device = stralloc(optarg);
		break;
	case 5: argument.level = g_slist_append(argument.level,
					        GINT_TO_POINTER(atoi(optarg)));
		break;
	case 6: argument.dle.create_index = 1;
		break;
	case 7: argument.message = 1;
		break;
	case 8: argument.collection = 1;
		break;
	case 9: argument.dle.record = 1;
		break;
	case 10: gnutar_path = stralloc(optarg);
		 break;
	case 11: gnutar_listdir = stralloc(optarg);
		 break;
	case 12: if (optarg && strcasecmp(optarg, "NO") == 0)
		     gnutar_onefilesystem = 0;
		 else if (optarg && strcasecmp(optarg, "YES") == 0)
		     gnutar_onefilesystem = 1;
		 else if (strcasecmp(command, "selfcheck") == 0)
		     printf(_("ERROR [%s: bad ONE-FILE-SYSTEM property value (%s)]\n"), get_pname(), optarg);
		 break;
	case 13: if (optarg && strcasecmp(optarg, "NO") == 0)
		     gnutar_sparse = 0;
		 else if (optarg && strcasecmp(optarg, "YES") == 0)
		     gnutar_sparse = 1;
		 else if (strcasecmp(command, "selfcheck") == 0)
		     printf(_("ERROR [%s: bad SPARSE property value (%s)]\n"), get_pname(), optarg);
		 break;
	case 14: if (optarg && strcasecmp(optarg, "NO") == 0)
		     gnutar_atimepreserve = 0;
		 else if (optarg && strcasecmp(optarg, "YES") == 0)
		     gnutar_atimepreserve = 1;
		 else if (strcasecmp(command, "selfcheck") == 0)
		     printf(_("ERROR [%s: bad ATIME-PRESERVE property value (%s)]\n"), get_pname(), optarg);
		 break;
	case 15: if (optarg && strcasecmp(optarg, "NO") == 0)
		     gnutar_checkdevice = 0;
		 else if (optarg && strcasecmp(optarg, "YES") == 0)
		     gnutar_checkdevice = 1;
		 else if (strcasecmp(command, "selfcheck") == 0)
		     printf(_("ERROR [%s: bad CHECK-DEVICE property value (%s)]\n"), get_pname(), optarg);
		 break;
	case 16: if (optarg)
		     argument.dle.include_file =
			 append_sl(argument.dle.include_file, optarg);
		 break;
	case 17: if (optarg)
		     argument.dle.include_list =
			 append_sl(argument.dle.include_list, optarg);
		 break;
	case 18: argument.dle.include_optional = 1;
		 break;
	case 19: if (optarg)
		     argument.dle.exclude_file =
			 append_sl(argument.dle.exclude_file, optarg);
		 break;
	case 20: if (optarg)
		     argument.dle.exclude_list =
			 append_sl(argument.dle.exclude_list, optarg);
		 break;
	case 21: argument.dle.exclude_optional = 1;
		 break;
	case 22: gnutar_directory = stralloc(optarg);
		 break;
	case 23: if (optarg)
		     normal_message = 
			 g_slist_append(normal_message, optarg);
		 break;
	case 24: if (optarg)
		     ignore_message = 
			 g_slist_append(ignore_message, optarg);
		 break;
	case 25: if (optarg)
		     strange_message = 
			 g_slist_append(strange_message, optarg);
		 break;
	case 26: if (optarg)
		     exit_handling = stralloc(optarg);
		 break;
	case 27: argument.calcsize = 1;
		 break;
	case 28: argument.tar_blocksize = stralloc(optarg);
		 break;
	case 29: if (optarg && strcasecmp(optarg, "NO") == 0)
		     gnutar_no_unquote = 0;
		 else if (optarg && strcasecmp(optarg, "YES") == 0)
		     gnutar_no_unquote = 1;
		 else if (strcasecmp(command, "selfcheck") == 0)
		     printf(_("ERROR [%s: bad No_UNQUOTE property value (%s)]\n"), get_pname(), optarg);
		 break;
	case ':':
	case '?':
		break;
	}
    }

    argument.argc = argc - optind;
    argument.argv = argv + optind;

    if (argument.config) {
	config_init(CONFIG_INIT_CLIENT | CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_OVERLAY,
		    argument.config);
	dbrename(get_config_name(), DBG_SUBDIR_CLIENT);
    }

    if (config_errors(NULL) >= CFGERR_ERRORS) {
	g_critical(_("errors processing config file"));
    }

    re_table = build_re_table(init_re_table, normal_message, ignore_message,
			      strange_message);

    for(i=0;i<256;i++)
	exit_value[i] = 1; /* BAD  */
    exit_value[0] = 0;     /* GOOD */
    exit_value[1] = 0;     /* GOOD */
    if (exit_handling) {
	char *s = exit_handling;
	while (s) {
	    char *r = strchr(s, '=');
	    if (r) {
		int j = atoi(s);
		if (j >= 0 && j < 256) {
		    r++;
		    if (strncasecmp(r, "GOOD", 4) == 0) {
			exit_value[j] = 0;
		    }
		}
	    }
	    s = strchr(s+1, ' ');
	}
    }

    gnutar_listdir = getconf_str(CNF_GNUTAR_LIST_DIR);
    if (strlen(gnutar_listdir) == 0)
	gnutar_listdir = NULL;

    if (gnutar_path) {
	dbprintf("GNUTAR-PATH %s\n", gnutar_path);
    } else {
	dbprintf("GNUTAR-PATH is not set\n");
    }
    if (gnutar_listdir) {
	    dbprintf("GNUTAR-LISTDIR %s\n", gnutar_listdir);
    } else {
	dbprintf("GNUTAR-LISTDIR is not set\n");
    }
    if (gnutar_directory) {
	dbprintf("DIRECTORY %s\n", gnutar_directory);
    }
    dbprintf("ONE-FILE-SYSTEM %s\n", gnutar_onefilesystem? "yes":"no");
    dbprintf("SPARSE %s\n", gnutar_sparse? "yes":"no");
    dbprintf("NO-UNQUOTE %s\n", gnutar_no_unquote? "yes":"no");
    dbprintf("ATIME-PRESERVE %s\n", gnutar_atimepreserve? "yes":"no");
    dbprintf("CHECK-DEVICE %s\n", gnutar_checkdevice? "yes":"no");
    {
	amregex_t *rp;
	for (rp = re_table; rp->regex != NULL; rp++) {
	    switch (rp->typ) {
		case DMP_NORMAL : dbprintf("NORMAL %s\n", rp->regex); break;
		case DMP_IGNORE : dbprintf("IGNORE %s\n", rp->regex); break;
		case DMP_STRANGE: dbprintf("STRANGE %s\n", rp->regex); break;
		case DMP_SIZE   : dbprintf("SIZE %s\n", rp->regex); break;
		case DMP_ERROR  : dbprintf("ERROR %s\n", rp->regex); break;
	    }
	}
    }

    if (strcmp(command, "support") == 0) {
	amgtar_support(&argument);
    } else if (strcmp(command, "selfcheck") == 0) {
	amgtar_selfcheck(&argument);
    } else if (strcmp(command, "estimate") == 0) {
	amgtar_estimate(&argument);
    } else if (strcmp(command, "backup") == 0) {
	amgtar_backup(&argument);
    } else if (strcmp(command, "restore") == 0) {
	amgtar_restore(&argument);
    } else if (strcmp(command, "validate") == 0) {
	amgtar_validate(&argument);
    } else {
	dbprintf("Unknown command `%s'.\n", command);
	fprintf(stderr, "Unknown command `%s'.\n", command);
	exit (1);
    }
    return 0;
}
Ejemplo n.º 12
0
int
main(
    int		argc,
    char **	argv)
{
    config_overrides_t *cfg_ovr;
    char *hostname;
    char *auth;
    char *service;
    char *config = NULL;
    int opt;
    extern int optind;
    extern char *optarg;
    FILE *input_file;
    int use_connect = 0;
    int got_input_file = 0;
    int i;
    unsigned char gfd[32768];

    glib_init();

    /*
     * Configure program for internationalization:
     *   1) Only set the message locale for now.
     *   2) Set textdomain for all amanda related programs to "amanda"
     *      We don't want to be forced to support dozens of message catalogs.
     */
    setlocale(LC_MESSAGES, "C");
    textdomain("amanda");

//    safe_fd(-1, 0);
    safe_cd();

    set_pname("amservice");
    /* drop root privileges */
    if (!set_root_privs(0)) {
	error(_("amservice must be run setuid root"));
    }

    /* Don't die when child closes pipe */
    signal(SIGPIPE, SIG_IGN);

    dbopen(DBG_SUBDIR_SERVER);

    add_amanda_log_handler(amanda_log_stderr);

    our_features = am_init_feature_set();
    our_feature_string = am_feature_to_string(our_features);
    /* process arguments */

    for (i=0; i<argc; i++) {
	g_debug("argv[%d] = %s", i, argv[i]);
    }

    for (i = 0;i < 32768; i++) {
	gfd[i] = 0;
    }

    cfg_ovr = new_config_overrides(argc/2);
    input_file = stdin;
    while((opt = getopt_long(argc, argv, "o:f:s", long_options, NULL)) != EOF) {
	switch(opt) {
	case 1:		printf("amservice-%s\n", VERSION);
			return(0);
			break;
	case 2:		g_free(our_feature_string);
			g_free(our_features);
			our_feature_string = g_strdup(optarg);
			our_features = am_string_to_feature(our_feature_string);
			break;
	case 3: {	gchar *copy_optarg = g_strdup(optarg);
			gchar *coma = strchr(copy_optarg, ',');
			gchar *stream_in;
			if (nb_lstream == DATA_FD_COUNT) {
			    g_critical("Too many --stream, maximum is %d",
				       DATA_FD_COUNT);
			    exit(1);
			} else if (coma) {
			    *coma++ = '\0';
			    stream_in = coma;
			    coma = strchr(coma, ',');
			    if (coma) {
				*coma++ = '\0';
				lstreams[nb_lstream].name = g_strdup(copy_optarg);
				lstreams[nb_lstream].fd_in = atoi(stream_in);
				lstreams[nb_lstream].fd_out = atoi(coma);
				gfd[lstreams[nb_lstream].fd_in] = 1;
				gfd[lstreams[nb_lstream].fd_out] = 1;
				nb_lstream++;
			    }
			}
			if (!coma) {
			    g_critical("Invalid --stream option (%s)", optarg);
			    exit(1);
			}
			g_free(copy_optarg);
			break;
		  }
	case 4:		g_free(config);
			config = g_strdup(optarg);
			break;
	case 'o':	add_config_override_opt(cfg_ovr, optarg);
			break;
	case 'f':	if (got_input_file == 1) {
			    g_critical("Invalid two -f argument");
			    exit(1);
			}
			got_input_file = 1;
			if (*optarg == '/') {
			    input_file = fopen(optarg, "r");
			} else {
			    char *name = g_strjoin(NULL, get_original_cwd(), "/",
						   optarg, NULL);
			    input_file = fopen(name, "r");
			    amfree(name);
			}
			if (!input_file) {
			    g_critical("Cannot open input file '%s': %s",
				optarg, strerror(errno));
			    exit(1);
			}
			break;
	case 's':	use_connect = 1;
			break;
	}
    }

    if (use_connect && !got_input_file) {
	g_critical("The -s option require -f");
	exit(1);
    }

    /* close all unused fd */
    for (i = 3;i < 32768; i++) {
	if (gfd[i] == 0 && i != dbfd() &&
	    (!got_input_file ||  i != fileno(input_file))) {
	    close(i);
	}
    }
    argc -= optind, argv += optind;
    if(argc < 3) usage();

    /* set a default config */
    set_config_overrides(cfg_ovr);
    config_init(CONFIG_INIT_CLIENT|CONFIG_INIT_GLOBAL, NULL);
    if (config) {
	config_init(CONFIG_INIT_CLIENT | CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_OVERLAY, config);
    }
    dbrename(get_config_name(), DBG_SUBDIR_SERVER);

    if (config_errors(NULL) >= CFGERR_WARNINGS) {
	config_print_errors();
	if (config_errors(NULL) >= CFGERR_ERRORS) {
	    g_critical(_("errors processing config file"));
	}
    }

    conf_ctimeout = (time_t)getconf_int(CNF_CTIMEOUT);

    hostname = argv[0];
    auth = argv[1];
    if (g_str_equal(auth,"NULL")) {
	auth = getconf_str(CNF_AUTH);
    }
    service = argv[2];

    /* start client side checks */

    copy_stream = use_connect && got_input_file;
    client_protocol(hostname, auth, service, config, input_file);

    amfree(our_feature_string);
    am_release_feature_set(our_features);
    our_features = NULL;
    if (got_input_file)
	fclose(input_file);

    dbclose();
    return(remote_errors != 0);
}
Ejemplo n.º 13
0
/*
 * Forks a ssh to the host listed in rc->hostname
 * Returns negative on error, with an errmsg in rc->errmsg.
 */
static int
runssh(
    struct tcp_conn *	rc,
    const char *	amandad_path,
    const char *	client_username,
    const char *	ssh_keys)
{
    int rpipe[2], wpipe[2];
    char *xamandad_path = (char *)amandad_path;
    char *xclient_username = (char *)client_username;
    char *xssh_keys = (char *)ssh_keys;

    memset(rpipe, -1, SIZEOF(rpipe));
    memset(wpipe, -1, SIZEOF(wpipe));
    if (pipe(rpipe) < 0 || pipe(wpipe) < 0) {
	rc->errmsg = newvstrallocf(rc->errmsg, _("pipe: %s"), strerror(errno));
	return (-1);
    }

    switch (rc->pid = fork()) {
    case -1:
	rc->errmsg = newvstrallocf(rc->errmsg, _("fork: %s"), strerror(errno));
	aclose(rpipe[0]);
	aclose(rpipe[1]);
	aclose(wpipe[0]);
	aclose(wpipe[1]);
	return (-1);
    case 0:
	dup2(wpipe[0], 0);
	dup2(rpipe[1], 1);
	break;
    default:
	rc->read = rpipe[0];
	aclose(rpipe[1]);
	rc->write = wpipe[1];
	aclose(wpipe[0]);
	return (0);
    }

    /* drop root privs for good */
    set_root_privs(-1);

    safe_fd(-1, 0);

    if(!xamandad_path || strlen(xamandad_path) <= 1) 
	xamandad_path = vstralloc(amlibexecdir, "/", "amandad", NULL);
    if(!xclient_username || strlen(xclient_username) <= 1)
	xclient_username = CLIENT_LOGIN;
    if(!ssh_keys || strlen(ssh_keys) <= 1) {
	execlp(SSH, SSH, SSH_OPTIONS, "-l", xclient_username,
	       rc->hostname, xamandad_path, "-auth=ssh", "amdump", "amindexd",
	       "amidxtaped", (char *)NULL);
    }
    else {
	execlp(SSH, SSH, SSH_OPTIONS, "-l", xclient_username,
	       "-i", xssh_keys, rc->hostname, xamandad_path, "-auth=ssh",
	       "amdump", "amindexd", "amidxtaped", (char *)NULL);
    }
    error("error: couldn't exec %s: %s", SSH, strerror(errno));

    /* should never go here, shut up compiler warning */
    return(-1);
}
Ejemplo n.º 14
0
int
main(
    int		argc,
    char **	argv)
{
    int c;
    char *command;
    application_argument_t argument;

#ifdef STAR
    star_path = STAR;
#else
    star_path = NULL;
#endif
    star_tardumps = "/etc/tardumps";
    star_dle_tardumps = 0;
    star_onefilesystem = 1;
    star_sparse = 1;
    star_directory = NULL;

    /* initialize */

    /*
     * Configure program for internationalization:
     *   1) Only set the message locale for now.
     *   2) Set textdomain for all amanda related programs to "amanda"
     *      We don't want to be forced to support dozens of message catalogs.
     */
    setlocale(LC_MESSAGES, "C");
    textdomain("amanda");

    if (argc < 2) {
	printf("ERROR no command given to amstar\n");
	error(_("No command given to amstar"));
    }

    /* drop root privileges */
    if (!set_root_privs(0)) {
	if (strcmp(argv[1], "selfcheck") == 0) {
	    printf("ERROR amstar must be run setuid root\n");
	}
	error(_("amstar must be run setuid root"));
    }

    safe_fd(3, 2);

    set_pname("amstar");

    /* Don't die when child closes pipe */
    signal(SIGPIPE, SIG_IGN);

#if defined(USE_DBMALLOC)
    malloc_size_1 = malloc_inuse(&malloc_hist_1);
#endif

    add_amanda_log_handler(amanda_log_stderr);
    add_amanda_log_handler(amanda_log_syslog);
    dbopen(DBG_SUBDIR_CLIENT);
    startclock();
    dbprintf(_("version %s\n"), VERSION);

    config_init(CONFIG_INIT_CLIENT, NULL);

    //check_running_as(RUNNING_AS_DUMPUSER_PREFERRED);
    //root for amrecover
    //RUNNING_AS_CLIENT_LOGIN from selfcheck, sendsize, sendbackup

    /* parse argument */
    command = argv[1];

    argument.config     = NULL;
    argument.host       = NULL;
    argument.message    = 0;
    argument.collection = 0;
    argument.calcsize   = 0;
    argument.level      = NULL;
    argument.command_options = NULL;
    init_dle(&argument.dle);

    opterr = 0;
    while (1) {
	int option_index = 0;
    	c = getopt_long (argc, argv, "", long_options, &option_index);
	if (c == -1)
	    break;

	switch (c) {
	case 1: argument.config = stralloc(optarg);
		break;
	case 2: argument.host = stralloc(optarg);
		break;
	case 3: argument.dle.disk = stralloc(optarg);
		break;
	case 4: argument.dle.device = stralloc(optarg);
		break;
	case 5: argument.level = g_slist_append(argument.level,
						GINT_TO_POINTER(atoi(optarg)));
		break;
	case 6: argument.dle.create_index = 1;
		break;
	case 7: argument.message = 1;
		break;
	case 8: argument.collection = 1;
		break;
	case 9: argument.dle.record = 1;
		break;
	case 10: star_path = stralloc(optarg);
		 break;
	case 11: star_tardumps = stralloc(optarg);
		 break;
	case 12: if (optarg && strcasecmp(optarg, "NO") == 0)
		     star_dle_tardumps = 0;
		 else if (optarg && strcasecmp(optarg, "YES") == 0)
		     star_dle_tardumps = 1;
		 else if (strcasecmp(command, "selfcheck") == 0)
		     printf(_("ERROR [%s: bad STAR-DLE-TARDUMP property value (%s)]\n"), get_pname(), optarg);
		 break;
	case 13: if (optarg && strcasecmp(optarg, "YES") != 0) {
		     /* This option is required to be YES */
		     /* star_onefilesystem = 0; */
		 }
		 break;
	case 14: if (optarg && strcasecmp(optarg, "NO") == 0)
		     star_sparse = 0;
		 else if (optarg && strcasecmp(optarg, "YES") == 0)
		     star_sparse = 1;
		 else if (strcasecmp(command, "selfcheck") == 0)
		     printf(_("ERROR [%s: bad SPARSE property value (%s)]\n"), get_pname(), optarg);
		 break;
	case 15: argument.calcsize = 1;
		 break;
        case 16: if (optarg)
                     normal_message =
                         g_slist_append(normal_message, optarg);
                 break;
        case 17: if (optarg)
                     ignore_message =
                         g_slist_append(ignore_message, optarg);
                 break;
        case 18: if (optarg)
                     strange_message =
                         g_slist_append(strange_message, optarg);
                 break;
	case 19: if (optarg)
		     argument.dle.include_list =
			 append_sl(argument.dle.include_list, optarg);
		 break;
	case 20: if (optarg)
		     argument.dle.exclude_list =
			 append_sl(argument.dle.exclude_list, optarg);
		 break;
	case 21: if (optarg)
		     star_directory = stralloc(optarg);
		 break;
	case 22: argument.command_options =
			g_slist_append(argument.command_options,
				       stralloc(optarg));
	case 23: if (optarg)
		     argument.dle.exclude_file =
			 append_sl(argument.dle.exclude_file, optarg);
		 break;
	case ':':
	case '?':
		break;
	}
    }

    if (!argument.dle.disk && argument.dle.device)
	argument.dle.disk = stralloc(argument.dle.device);
    if (!argument.dle.device && argument.dle.disk)
	argument.dle.device = stralloc(argument.dle.disk);

    argument.argc = argc - optind;
    argument.argv = argv + optind;

    if (argument.config) {
	/* overlay this configuration on the existing (nameless) configuration */
	config_init(CONFIG_INIT_CLIENT | CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_OVERLAY,
		    argument.config);
	dbrename(get_config_name(), DBG_SUBDIR_CLIENT);

    }

    if (config_errors(NULL) >= CFGERR_ERRORS) {
	g_critical(_("errors processing config file"));
    }

    re_table = build_re_table(init_re_table, normal_message, ignore_message,
			      strange_message);

    if (strcmp(command, "support") == 0) {
	amstar_support(&argument);
    } else if (strcmp(command, "selfcheck") == 0) {
	amstar_selfcheck(&argument);
    } else if (strcmp(command, "estimate") == 0) {
	amstar_estimate(&argument);
    } else if (strcmp(command, "backup") == 0) {
	amstar_backup(&argument);
    } else if (strcmp(command, "restore") == 0) {
	amstar_restore(&argument);
    } else if (strcmp(command, "validate") == 0) {
	amstar_validate(&argument);
    } else {
	fprintf(stderr, "Unknown command `%s'.\n", command);
	exit (1);
    }
    return 0;
}
Ejemplo n.º 15
0
pid_t
pipespawnv_passwd(
    char *	prog,
    int		pipedef,
    int		need_root,
    int *	stdinfd,
    int *	stdoutfd,
    int *	stderrfd,
    char **	my_argv)
{
    pid_t pid;
    int i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2];
    char number[NUM_STR_SIZE];
    char **arg;
    char *e;
    char **env;
    char *cmdline;
    char **newenv;
    char *passwdvar = NULL;
    int  *passwdfd = NULL;
    GPtrArray *array = g_ptr_array_new();
    gchar **strings;

    /*
     * Log the command line and count the args.
     */
    if ((pipedef & PASSWD_PIPE) != 0) {
	passwdvar = *my_argv++;
	passwdfd  = (int *)*my_argv++;
    }
    memset(inpipe, -1, sizeof(inpipe));
    memset(outpipe, -1, sizeof(outpipe));
    memset(errpipe, -1, sizeof(errpipe));
    memset(passwdpipe, -1, sizeof(passwdpipe));

    g_ptr_array_add(array, g_strdup(prog));

    for(arg = my_argv; *arg != NULL; arg++) {
        if (*arg == skip_argument)
            continue;
        g_ptr_array_add(array, quote_string(*arg));
    }

    g_ptr_array_add(array, NULL);

    strings = (gchar **)g_ptr_array_free(array, FALSE);
    cmdline = g_strjoinv(" ", strings);
    g_strfreev(strings);

    dbprintf(_("Spawning \"%s\" in pipeline\n"), cmdline);

    /*
     * Create the pipes
     */
    if ((pipedef & STDIN_PIPE) != 0) {
	if(pipe(inpipe) == -1) {
	    error(_("error [open pipe to %s: %s]"), prog, strerror(errno));
	    /*NOTREACHED*/
	}
    }
    if ((pipedef & STDOUT_PIPE) != 0) {
	if(pipe(outpipe) == -1) {
	    error(_("error [open pipe to %s: %s]"), prog, strerror(errno));
	    /*NOTREACHED*/
	}
    }
    if ((pipedef & STDERR_PIPE) != 0) {
	if(pipe(errpipe) == -1) {
	    error(_("error [open pipe to %s: %s]"), prog, strerror(errno));
	    /*NOTREACHED*/
	}
    }
    if ((pipedef & PASSWD_PIPE) != 0) {
	if(pipe(passwdpipe) == -1) {
	    error(_("error [open pipe to %s: %s]"), prog, strerror(errno));
	    /*NOTREACHED*/
	}
    }

    /*
     * Fork and set up the return or run the program.
     */
    switch(pid = fork()) {
    case -1:
	e = strerror(errno);
	error(_("error [fork %s: %s]"), prog, e);
	/*NOTREACHED*/

    default:	/* parent process */
	if ((pipedef & STDIN_PIPE) != 0) {
	    aclose(inpipe[0]);		/* close input side of pipe */
	    *stdinfd = inpipe[1];
	}
	if ((pipedef & STDOUT_PIPE) != 0) {
	    aclose(outpipe[1]);		/* close output side of pipe */
	    *stdoutfd = outpipe[0];
	}
	if ((pipedef & STDERR_PIPE) != 0) {
	    aclose(errpipe[1]);		/* close output side of pipe */
	    *stderrfd = errpipe[0];
	}
	if ((pipedef & PASSWD_PIPE) != 0) {
	    aclose(passwdpipe[0]);	/* close input side of pipe */
	    *passwdfd = passwdpipe[1];
	}
	break;
    case 0:		/* child process */
	debug_dup_stderr_to_debug();
	if ((pipedef & STDIN_PIPE) != 0) {
	    aclose(inpipe[1]);		/* close output side of pipe */
	} else {
	    inpipe[0] = *stdinfd;
	}
	if ((pipedef & STDOUT_PIPE) != 0) {
	    aclose(outpipe[0]);		/* close input side of pipe */
	} else {
	    outpipe[1] = *stdoutfd;
	}
	if ((pipedef & STDERR_PIPE) != 0) {
	    aclose(errpipe[0]);		/* close input side of pipe */
	} else {
	    errpipe[1] = *stderrfd;
	}
        if ((pipedef & PASSWD_PIPE) != 0) { 
            aclose(passwdpipe[1]);      /* close output side of pipe */
        }

	/*
	 * Shift the pipes to the standard file descriptors as requested.
	 */
	if(dup2(inpipe[0], 0) == -1) {
	    g_fprintf(stderr, "error [spawn %s: dup2 in: %s]", prog, strerror(errno));
	    exit(1);
	    /*NOTREACHED*/
	}
	if(dup2(outpipe[1], 1) == -1) {
	    g_fprintf(stderr, "error [spawn %s: dup2 out: %s]", prog, strerror(errno));
	    exit(1);
	    /*NOTREACHED*/
	}
	if(dup2(errpipe[1], 2) == -1) {
	    g_fprintf(stderr, "error [spawn %s: dup2 err: %s]", prog, strerror(errno));
	    exit(1);
	    /*NOTREACHED*/
	}

	/*
	 * Get the "safe" environment.  If we are sending a password to
	 * the child via a pipe, add the environment variable for that.
	 */
	env = safe_env();
	if ((pipedef & PASSWD_PIPE) != 0) {
	    for (i = 0; env[i] != NULL; i++)
		(void)i; /* make lint happy and do nothing */	
	    newenv = (char **)g_malloc((i + 1 + 1) * sizeof(*newenv));
	    g_snprintf(number, sizeof(number), "%d", passwdpipe[0]);
	    newenv[0] = g_strjoin(NULL, passwdvar, "=", number, NULL);
	    for(i = 0; env[i] != NULL; i++)
	    	newenv[i + 1] = env[i];
	    newenv[i + 1] = NULL;
	    amfree(env);
	    env = newenv;
	    safe_fd(passwdpipe[0], 1);
	} else {
	    safe_fd(-1, 0);
	}

	if (need_root) {
	    become_root();
	} else {
	    /* if our real userid is zero, the child shouldn't inherit
	     * that, so drop privs permanently */
	    if (getuid() == 0 && !set_root_privs(-1)) {
		error(_("could not drop root privileges"));
	    }
	}

	execve(prog, my_argv, env);
	e = strerror(errno);
	error(_("error [exec %s: %s]"), prog, e);
	/*NOTREACHED*/
    }
    amfree(cmdline);
    return pid;
}
Ejemplo n.º 16
0
/*
 * Negotiate a krb5 gss context from the server end.
 */
static int
gss_server(
    struct tcp_conn *rc)
{
    OM_uint32 maj_stat, min_stat, ret_flags;
    gss_buffer_desc send_tok, recv_tok, AA;
    gss_OID doid;
    gss_name_t gss_name;
    gss_cred_id_t gss_creds;
    char *p, *realm, *msg;
    int rval = -1;
    int rvalue;
    char errbuf[256];
    char *errmsg = NULL;

    auth_debug(1, "gss_server\n");

    assert(rc != NULL);

    /*
     * We need to be root while in gss_acquire_cred() to read the host key
     * out of the default keytab.  We also need to be root in
     * gss_accept_context() thanks to the replay cache code.
     */
    if (!set_root_privs(0)) {
	g_snprintf(errbuf, SIZEOF(errbuf),
	    _("can't take root privileges to read krb5 host key: %s"), strerror(errno));
	goto out;
    }

    rc->gss_context = GSS_C_NO_CONTEXT;
    send_tok.value = vstralloc("host/", myhostname, NULL);
    send_tok.length = strlen(send_tok.value) + 1;
    for (p = send_tok.value; *p != '\0'; p++) {
	if (isupper((int)*p))
	    *p = tolower(*p);
    }
    maj_stat = gss_import_name(&min_stat, &send_tok, GSS_C_NULL_OID,
	&gss_name);
    if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
	set_root_privs(0);
	g_snprintf(errbuf, SIZEOF(errbuf),
	    _("can't import name %s: %s"), (char *)send_tok.value,
	    gss_error(maj_stat, min_stat));
	amfree(send_tok.value);
	goto out;
    }
    amfree(send_tok.value);

    maj_stat = gss_display_name(&min_stat, gss_name, &AA, &doid);
    dbprintf(_("gss_name %s\n"), (char *)AA.value);
    maj_stat = gss_acquire_cred(&min_stat, gss_name, 0,
	GSS_C_NULL_OID_SET, GSS_C_ACCEPT, &gss_creds, NULL, NULL);
    if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
	g_snprintf(errbuf, SIZEOF(errbuf),
	    _("can't acquire creds for host key host/%s: %s"), myhostname,
	    gss_error(maj_stat, min_stat));
	gss_release_name(&min_stat, &gss_name);
	set_root_privs(0);
	goto out;
    }
    gss_release_name(&min_stat, &gss_name);

    for (recv_tok.length = 0;;) {
	recv_tok.value = NULL;
        rvalue = tcpm_recv_token(rc, rc->read, &rc->handle, &rc->errmsg,
				 /* (void *) is to avoid type-punning warning */
				 (char **)(void *)&recv_tok.value,
				 (ssize_t *)&recv_tok.length, 60);
	if (rvalue <= 0) {
	    if (rvalue < 0) {
		g_snprintf(errbuf, SIZEOF(errbuf),
		    _("recv error in gss loop: %s"), rc->errmsg);
		amfree(rc->errmsg);
	    } else
		g_snprintf(errbuf, SIZEOF(errbuf), _("EOF in gss loop"));
	    goto out;
	}

	maj_stat = gss_accept_sec_context(&min_stat, &rc->gss_context,
	    gss_creds, &recv_tok, GSS_C_NO_CHANNEL_BINDINGS,
	    &gss_name, &doid, &send_tok, &ret_flags, NULL, NULL);

	if (maj_stat != (OM_uint32)GSS_S_COMPLETE &&
	    maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED) {
	    g_snprintf(errbuf, SIZEOF(errbuf),
		_("error accepting context: %s"), gss_error(maj_stat, min_stat));
	    amfree(recv_tok.value);
	    goto out;
	}
	amfree(recv_tok.value);

	if (send_tok.length != 0 && tcpm_send_token(rc, rc->write, 0, &errmsg, send_tok.value, send_tok.length) < 0) {
	    strncpy(errbuf, rc->errmsg, SIZEOF(errbuf) - 1);
	    errbuf[SIZEOF(errbuf) - 1] = '\0';
	    amfree(rc->errmsg);
	    gss_release_buffer(&min_stat, &send_tok);
	    goto out;
	}
	gss_release_buffer(&min_stat, &send_tok);


	/*
	 * If we need to get more from the client, then register for
	 * more packets.
	 */
	if (maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED)
	    break;
    }

    maj_stat = gss_display_name(&min_stat, gss_name, &send_tok, &doid);
    if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
	g_snprintf(errbuf, SIZEOF(errbuf),
	    _("can't display gss name: %s"), gss_error(maj_stat, min_stat));
	gss_release_name(&min_stat, &gss_name);
	goto out;
    }
    gss_release_name(&min_stat, &gss_name);

    /* get rid of the realm */
    if ((p = strchr(send_tok.value, '@')) == NULL) {
	g_snprintf(errbuf, SIZEOF(errbuf),
	    _("malformed gss name: %s"), (char *)send_tok.value);
	amfree(send_tok.value);
	goto out;
    }
    *p = '\0';
    realm = ++p;

    /* 
     * If the principal doesn't match, complain
     */
    if ((msg = krb5_checkuser(rc->hostname, send_tok.value, realm)) != NULL) {
	g_snprintf(errbuf, SIZEOF(errbuf),
	    _("access not allowed from %s: %s"), (char *)send_tok.value, msg);
	amfree(send_tok.value);
	goto out;
    }
    amfree(send_tok.value);

    rval = 0;
out:
    set_root_privs(0);
    if (rval != 0) {
	rc->errmsg = stralloc(errbuf);
    } else {
	rc->auth = 1;
    }
    auth_debug(1, _("gss_server returning %d\n"), rval);
    return (rval);
}
Ejemplo n.º 17
0
static void
bsd_connect(
    const char *	hostname,
    char *		(*conf_fn)(char *, void *),
    void		(*fn)(void *, security_handle_t *, security_status_t),
    void *		arg,
    void *		datap)
{
    struct sec_handle *bh;
    in_port_t port = 0;
    struct timeval sequence_time;
    int sequence;
    char *handle;
    int result;
    struct addrinfo *res, *res_addr;
    char *canonname;
    int result_bind;
    char *service;

    assert(hostname != NULL);

    (void)conf_fn;	/* Quiet unused parameter warning */
    (void)datap;        /* Quiet unused parameter warning */

    bh = g_new0(struct sec_handle, 1);
    bh->proto_handle=NULL;
    security_handleinit(&bh->sech, &bsd_security_driver);

    result = resolve_hostname(hostname, SOCK_DGRAM, &res, &canonname);
    if(result != 0) {
	dbprintf(_("resolve_hostname(%s): %s\n"), hostname, gai_strerror(result));
	security_seterror(&bh->sech, _("resolve_hostname(%s): %s\n"), hostname,
			  gai_strerror(result));
	(*fn)(arg, &bh->sech, S_ERROR);
	return;
    }
    if (canonname == NULL) {
	dbprintf(_("resolve_hostname(%s) did not return a canonical name\n"), hostname);
	security_seterror(&bh->sech,
	        _("resolve_hostname(%s) did not return a canonical name\n"), hostname);
	(*fn)(arg, &bh->sech, S_ERROR);
	if (res) freeaddrinfo(res);
	return;
    }
    if (res == NULL) {
	dbprintf(_("resolve_hostname(%s): no results\n"), hostname);
	security_seterror(&bh->sech,
	        _("resolve_hostname(%s): no results\n"), hostname);
	(*fn)(arg, &bh->sech, S_ERROR);
	amfree(canonname);
	return;
    }

    for (res_addr = res; res_addr != NULL; res_addr = res_addr->ai_next) {
#ifdef WORKING_IPV6
	/* IPv6 socket already bound */
	if (res_addr->ai_addr->sa_family == AF_INET6 && not_init6 == 0) {
	    break;
	}
	/*
	 * Only init the IPv6 socket once
	 */
	if (res_addr->ai_addr->sa_family == AF_INET6 && not_init6 == 1) {
	    uid_t euid;
	    dgram_zero(&netfd6.dgram);

	    euid = geteuid();
	    set_root_privs(1);
	    result_bind = dgram_bind(&netfd6.dgram,
				     res_addr->ai_addr->sa_family, &port);
	    set_root_privs(0);
	    if (result_bind != 0) {
		continue;
	    }
	    netfd6.handle = NULL;
	    netfd6.pkt.body = NULL;
	    netfd6.recv_security_ok = &bsd_recv_security_ok;
	    netfd6.prefix_packet = &bsd_prefix_packet;
	    /*
	     * We must have a reserved port.  Bomb if we didn't get one.
	     */
	    if (port >= IPPORT_RESERVED) {
		security_seterror(&bh->sech,
		    _("unable to bind to a reserved port (got port %u)"),
		    (unsigned int)port);
		(*fn)(arg, &bh->sech, S_ERROR);
		freeaddrinfo(res);
		amfree(canonname);
		return;
	    }
	    not_init6 = 0;
	    bh->udp = &netfd6;
	    break;
	}
#endif

	/* IPv4 socket already bound */
	if (res_addr->ai_addr->sa_family == AF_INET && not_init4 == 0) {
	    break;
	}

	/*
	 * Only init the IPv4 socket once
	 */
	if (res_addr->ai_addr->sa_family == AF_INET && not_init4 == 1) {
	    uid_t euid;
	    dgram_zero(&netfd4.dgram);

	    euid = geteuid();
	    set_root_privs(1);
	    result_bind = dgram_bind(&netfd4.dgram,
				     res_addr->ai_addr->sa_family, &port);
	    set_root_privs(0);
	    if (result_bind != 0) {
		continue;
	    }
	    netfd4.handle = NULL;
	    netfd4.pkt.body = NULL;
	    netfd4.recv_security_ok = &bsd_recv_security_ok;
	    netfd4.prefix_packet = &bsd_prefix_packet;
	    /*
	     * We must have a reserved port.  Bomb if we didn't get one.
	     */
	    if (port >= IPPORT_RESERVED) {
		security_seterror(&bh->sech,
		    "unable to bind to a reserved port (got port %u)",
		    (unsigned int)port);
		(*fn)(arg, &bh->sech, S_ERROR);
		freeaddrinfo(res);
		amfree(canonname);
		return;
	    }
	    not_init4 = 0;
	    bh->udp = &netfd4;
	    break;
	}
    }

    if (res_addr == NULL) {
	dbprintf(_("Can't bind a socket to connect to %s\n"), hostname);
	security_seterror(&bh->sech,
	        _("Can't bind a socket to connect to %s\n"), hostname);
	(*fn)(arg, &bh->sech, S_ERROR);
	amfree(canonname);
	freeaddrinfo(res);
	return;
    }

#ifdef WORKING_IPV6
    if (res_addr->ai_addr->sa_family == AF_INET6)
	bh->udp = &netfd6;
    else
#endif
	bh->udp = &netfd4;

    auth_debug(1, _("Resolved hostname=%s\n"), canonname);

    if (conf_fn) {
        service = conf_fn("client_port", datap);
        if (!service || strlen(service) <= 1)
            service = "amanda";
    } else {
        service = "amanda";
    }
    port = find_port_for_service(service, "udp");
    if (port == 0) {
        security_seterror(&bh->sech, _("%s/udp unknown protocol"), service);
	(*fn)(arg, &bh->sech, S_ERROR);
        amfree(canonname);
	freeaddrinfo(res);
	return;
    }

    amanda_gettimeofday(&sequence_time);
    sequence = (int)sequence_time.tv_sec ^ (int)sequence_time.tv_usec;
    handle=g_malloc(15);
    g_snprintf(handle, 14, "000-%08x",  (unsigned)newhandle++);
    if (udp_inithandle(bh->udp, bh, canonname,
	(sockaddr_union *)res_addr->ai_addr, port, handle, sequence) < 0) {
	(*fn)(arg, &bh->sech, S_ERROR);
	amfree(bh->hostname);
	amfree(bh);
    }
    else {
	(*fn)(arg, &bh->sech, S_OK);
    }
    amfree(handle);
    amfree(canonname);

    freeaddrinfo(res);
}
Ejemplo n.º 18
0
static void
amgtar_selfcheck(
    application_argument_t *argument)
{
    if (argument->dle.disk) {
	char *qdisk = quote_string(argument->dle.disk);
	fprintf(stdout, "OK disk %s\n", qdisk);
	amfree(qdisk);
    }

    printf("OK amgtar version %s\n", VERSION);
    amgtar_build_exinclude(&argument->dle, 1, NULL, NULL, NULL, NULL);

    printf("OK amgtar\n");
    if (gnutar_path) {
	if (check_file(gnutar_path, X_OK)) {
	    char *gtar_version;
	    GPtrArray *argv_ptr = g_ptr_array_new();

	    g_ptr_array_add(argv_ptr, gnutar_path);
	    g_ptr_array_add(argv_ptr, "--version");
	    g_ptr_array_add(argv_ptr, NULL);

	    gtar_version = get_first_line(argv_ptr);
	    if (gtar_version) {
		char *gv;
		for (gv = gtar_version; *gv && !g_ascii_isdigit(*gv); gv++);
		printf("OK amgtar gtar-version %s\n", gv);
	    } else {
		printf(_("ERROR [Can't get %s version]\n"), gnutar_path);
	    }

	    g_ptr_array_free(argv_ptr, TRUE);
	    amfree(gtar_version);
	}
    } else {
	printf(_("ERROR [GNUTAR program not available]\n"));
    }

    if (gnutar_listdir && strlen(gnutar_listdir) == 0)
	gnutar_listdir = NULL;
    if (gnutar_listdir) {
	check_dir(gnutar_listdir, R_OK|W_OK);
    } else {
	printf(_("ERROR [No GNUTAR-LISTDIR]\n"));
    }

    set_root_privs(1);
    if (gnutar_directory) {
	check_dir(gnutar_directory, R_OK);
    } else if (argument->dle.device) {
	check_dir(argument->dle.device, R_OK);
    }
    if (argument->calcsize) {
	char *calcsize = g_strjoin(NULL, amlibexecdir, "/", "calcsize", NULL);
	check_file(calcsize, X_OK);
	check_suid(calcsize);
	amfree(calcsize);
    }
    set_root_privs(0);
}