Beispiel #1
0
static int
_parse_gids (char     *s,
             uidgid_t *u)
{
    char *pos = NULL;
    gid_t gid;

    w_assert (s);
    w_assert (u);

    if (u->ngid >= DMON_GID_COUNT) {
        w_printerr ("more than $L groups given, ignoring additional ones\n",
                    DMON_GID_COUNT);
        return 0;
    }

    pos = strchr (s, ':');
    if (pos != NULL)
        *pos = '\0';

    if (name_to_gid (s, &gid)) {
        if (pos != NULL) *pos = ':';
        return 1;
    }

    if (pos != NULL)
        *pos = ':';

    u->gids[u->ngid++] = gid;

    return (pos == NULL) ? 0 : _parse_gids (pos + 1, u);
}
Beispiel #2
0
static int map_gid(int id, char *name)
{
	gid_t gid;
	if (name_to_gid(name, &gid) && gid != 0)
		return gid;
	return id;
}
Beispiel #3
0
int main(int argc, char *argv[])
{
	int i;
	gid_t user_gid;
	uid_t user_uid;


	int is_only_group = 0;
	int is_only_group_all = 0;
	int is_name = 0;
	int is_only_user = 0;
	int is_real = 0;

	//bug!: myid -Gn - err
	char *opts="rgGnu";
	int opt, opt_c = 0;
	while((opt=getopt(argc,argv,opts))!=-1){
		switch(opt){
			case 'a':
				break;
			case 'g':
				is_only_group = 1;
				break;
			case 'G':
				is_only_group_all = 1;
				break;
			case 'n':
				is_name = 1;
				break;
			case 'r':
				is_real = 1;
				break;
			case 'u':
				is_only_user = 1;
				break;
		}
		opt_c++;
	}
	//without username
	if(argc == 1 || (opt_c + 1) == argc){
		if( is_real){
			user_gid = getgid();
			user_uid = getuid();
		}
		else{
			user_gid = getegid();
			user_uid = geteuid();

		}
	}
	//with username in command line
	else{
		user_gid = name_to_uid(argv[1+opt_c]);
		user_uid = name_to_gid(argv[1+opt_c]); 
	}
	// -g flag.
	if( is_only_group){
		if( is_name)
			printf("%s\n",gid_to_name(user_gid));
		else
			printf("%d\n",user_gid);
		return 0;
	}
	// -G flag.
	if( is_only_group_all){
		int list_size = 0;
		gid_t * user_groups = get_groups(gid_to_name(user_gid),&list_size);
		for( i=0;i<list_size;i++)
			if( is_name)
				printf("%s ",gid_to_name(user_groups[i]));
			else
				printf("%d ",user_groups[i]);
		printf("\n");
		return 0;
	}
	// -u flag.
	if( is_only_user){
		if( is_name)
			printf("%s\n",uid_to_name(user_uid));
		else
			printf("%d\n",user_uid);
		return 0;
	}
	//wrong flags
	if( is_name && is_real){
		fprintf(stderr,"id: cannot print only names or real IDs in default format\n");
		return EARG;
	}
	//common case:
	printf("uid=%d(%s) ",user_uid,uid_to_name(user_uid));
	printf("gid=%d(%s) ",user_gid,gid_to_name(user_gid));

	int list_size = 0;
	gid_t * user_groups = get_groups(gid_to_name(user_gid),&list_size);
	printf("groups=");
	printf("%s(%d)",gid_to_name(user_gid),user_gid);
	for( i=0;i<list_size;i++)
		printf("%d(%s) ",	user_groups[i],
					gid_to_name(user_groups[i]));
	printf("\n");
	return 0;
}
Beispiel #4
0
/*
 *	init_irix() - initialize the IRIX format argument list.
 */
static	int
init_irix(int argc, char **argv)
{
	int	c;
	char	*optstring = "a:D:g:j:p:u:M:n:cdefhJlmorst";

	/*  Process options. */
	while ((c = getopt(argc, argv, optstring)) != EOF) {
		switch (c) {

	 	/*  Process the report selection options. */
		case 'c':		/* command report */
			c_opt++;
			break;
		case 'f':		/* command flow report */
			f_opt++;
			break;
		case 'o':		/* other command report */
			o_opt++;
			break;
		case 's':		/* summary report */
			s_opt++;
			break;

	 	/*  Process the record selection options. */
		case 'a':		/* select by array session ID */
			a_opt++;
			sscanf(optarg, "%llx", &s_ash);
			break;

		case 'g':		/* select by group ID */
			g_opt++;
			if (optarg[0] >= '0' && optarg[0] <= '9') {
				sscanf(optarg, "%d", &s_gid);

			} else {	/* ASCII */
				if ((s_gid = name_to_gid(optarg)) == -1) {
					acct_err(ACCT_ABORT,
					       _("An unknown Group name '%s' was given on the -g parameter."),
						optarg);
				}
			}
			break;

		case 'j':		/* select by job ID */
			j_opt++;
			sscanf(optarg, "%llx", &s_jid);
			break;

		case 'M':			/* select by positioning */
			M_opt++;
			if ((M_optargc = getoptlst(optarg, &M_optargv))
					== -1) {
				acct_err(ACCT_ABORT,
				       _("An error was returned from routine '%s' for the (-%s) option '%s'."),
					"getoptlst()",
					"M", optarg);
			}
			break;

		case 'n':		/* select by command names */
			n_opt++;
			if ((n_optargc = getoptlst(optarg, &n_optargv))
					== -1) {
				acct_err(ACCT_ABORT,
				       _("An error was returned from routine '%s' for the (-%s) option '%s'."),
					"getoptlst()",
					"n", optarg);
			}
			names = getnames(n_optargc, n_optargv);
			free(n_optargv);
			break;

		case 'p':		/* select by project ID */
			p_opt++;
			if (optarg[0] >= '0' && optarg[0] <= '9') {
				sscanf(optarg, "%lld", &s_prid);

			} else {	/* ASCII */
				if ((s_prid = name_to_prid(optarg)) == -1) {
					acct_err(ACCT_ABORT,
					       _("An unknown Project name '%s' was given on the -p parameter."),
						optarg);
				}
			}
			break;

		case 'u':		/* select by user ID */
			u_opt++;
			if (optarg[0] >= '0' && optarg[0] <= '9') {
				sscanf(optarg, "%d", &s_uid); /* numeric */

			} else {	/* ASCII */
				if ((s_uid = name_to_uid(optarg)) == -1) {
					acct_err(ACCT_ABORT,
					       _("An unknown User name '%s' was given on the -u parameter."),
						optarg);
				}
			}
			break;

	 	/*  Process the report modification options. */
		case 'd':		/* daemon report */
			d_opt++;
			break;
		case 'e':		/* extended summary report */
			e_opt++;
			break;
		case 'h':		/* hiwater report */
			h_opt++;
			break;
		case 'J':
			J_opt++;	/* select all special pacct */
			break;
		case 'l':		/* long report (-{B c f} only) */
			l_opt++;
			break;

	 	/*  Process the remaining options. */
		case 'D':		/* debug option */
			D_opt++;
			db_flag = atoi(optarg);
			if ((db_flag < 1) || (db_flag > 4)) {
				acct_err(ACCT_FATAL,
				       _("The (-%s) option's argument, '%s', is invalid."),
					"D", optarg);
				Nerror("Option -D valid values are 1 to 4\n");
				usage();
			}
			Ndebug("Debugging option set to level %d\n", db_flag);
			break;
		case 'm':		/* mark position */
			m_opt++;
			break;
		case 'r':		/* raw mode */
			r_opt++;
			break;
		case 't':		/* terminate job accounting */
			t_opt++;
			break;

		default:
			usage();
		}
	}

	/*  Verify the selected options - must be used with report options. */
	if (!c_opt && !f_opt && !o_opt && !s_opt){
		if (a_opt) {
		    acct_err(ACCT_ABORT,
		      _("The (-%s) option must be used with the (-%s) option."),
			 "a", "{c f o s}");
		}
		if (g_opt) {
                    acct_err(ACCT_ABORT,
                      _("The (-%s) option must be used with the (-%s) option."),
			 "g", "{c f o s}");
                }
		if (j_opt) {
                    acct_err(ACCT_ABORT,
                      _("The (-%s) option must be used with the (-%s) option."),
			 "j", "{c f o s}");
                }
		if (n_opt) {
                    acct_err(ACCT_ABORT,
                      _("The (-%s) option must be used with the (-%s) option."),
			 "n", "{c f o s}");
                }
		if (p_opt) {
                    acct_err(ACCT_ABORT,
                      _("The (-%s) option must be used with the (-%s) option."),
			 "p", "{c f o s}");
                }
		if (u_opt) {
                    acct_err(ACCT_ABORT,
                      _("The (-%s) option must be used with the (-%s) option."),
			 "u", "{c f o s}");
                }
		if (d_opt) {
                    acct_err(ACCT_ABORT,
                      _("The (-%s) option must be used with the (-%s) option."),
			 "d", "{c f o s}");
                }
		if (r_opt) {
                    acct_err(ACCT_ABORT,
                      _("The (-%s) option must be used with the (-%s) option."),
			 "r", "{c f o s}");
                }

	/*  and -m is NOT used with the report options. */
	} else if (m_opt) {
	    acct_err(ACCT_ABORT,
		_("The (-%s) option cannot be selected when issuing a report."),
			"m");
	}

	/*  Insure -m is NOT with t. */
	if (t_opt && m_opt) {
		acct_err(ACCT_ABORT,
		   _("The (-%s) and the (-%s) options are mutually exclusive."),
			"m", "t");
	}

	/*  Insure -o is NOT with c. */
	if (o_opt && c_opt) {
		acct_err(ACCT_ABORT,
		   _("The (-%s) and the (-%s) options are mutually exclusive."),
			"o", "c");
	}

	/*  Insure -e is with {s}. */
	if (e_opt && !(s_opt) ) {
		acct_err(ACCT_ABORT,
		      _("The (-%s) option must be used with the (-%s) option."),
			"e", "s");
	}

	/*  Insure -h is with l and c. */
	if (h_opt && !(c_opt && l_opt)) {
		acct_err(ACCT_ABORT,
		      _("The (-%s) option must be used with the (-%s) option."),
			"h", "c and l");
	}

	/*  Insure -l is with -{ c f} */
	if (l_opt && !(c_opt || f_opt)) {
		acct_err(ACCT_ABORT,
		      _("The (-%s) option must be used with the (-%s) option."),
			"l", "{c f}");
	}

	/*  Insure -M is with -{c}. */
	if (M_opt && !c_opt) {
		acct_err(ACCT_ABORT,
		      _("The (-%s) option must be used with the (-%s) option."),
			"M", "c");
	}

	return(0);
}
static int rsync_module(int fd, int i)
{
	int argc=0;
	char *argv[MAX_ARGS];
	char **argp;
	char line[MAXPATHLEN];
	uid_t uid = (uid_t)-2;
	gid_t gid = (gid_t)-2;
	char *p;
	char *addr = client_addr(fd);
	char *host = client_name(fd);
	char *name = lp_name(i);
	int use_chroot = lp_use_chroot(i);
	int start_glob=0;
	int ret;
	char *request=NULL;
	extern int am_sender;
	extern int remote_version;
	extern int am_root;

	if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
		rprintf(FERROR,"rsync denied on module %s from %s (%s)\n",
			name, client_name(fd), client_addr(fd));
		io_printf(fd,"@ERROR: access denied to %s from %s (%s)\n",
			  name, client_name(fd), client_addr(fd));
		return -1;
	}

	if (!claim_connection(lp_lock_file(i), lp_max_connections(i))) {
		if (errno) {
			rprintf(FERROR,"failed to open lock file %s : %s\n",
				lp_lock_file(i), strerror(errno));
			io_printf(fd,"@ERROR: failed to open lock file %s : %s\n",
				  lp_lock_file(i), strerror(errno));
		} else {
			rprintf(FERROR,"max connections (%d) reached\n",
				lp_max_connections(i));
			io_printf(fd,"@ERROR: max connections (%d) reached - try again later\n", lp_max_connections(i));
		}
		return -1;
	}

	
	auth_user = auth_server(fd, i, addr, "@RSYNCD: AUTHREQD ");

	if (!auth_user) {
		rprintf(FERROR,"auth failed on module %s from %s (%s)\n",
			name, client_name(fd), client_addr(fd));
		io_printf(fd,"@ERROR: auth failed on module %s\n",name);
		return -1;		
	}

	module_id = i;

	if (lp_read_only(i))
		read_only = 1;

	am_root = (getuid() == 0);

	if (am_root) {
		p = lp_uid(i);
		if (!name_to_uid(p, &uid)) {
			if (!isdigit(*p)) {
				rprintf(FERROR,"Invalid uid %s\n", p);
				io_printf(fd,"@ERROR: invalid uid\n");
				return -1;
			} 
			uid = atoi(p);
		}

		p = lp_gid(i);
		if (!name_to_gid(p, &gid)) {
			if (!isdigit(*p)) {
				rprintf(FERROR,"Invalid gid %s\n", p);
				io_printf(fd,"@ERROR: invalid gid\n");
				return -1;
			} 
			gid = atoi(p);
		}
	}

	p = lp_include_from(i);
	add_exclude_file(p, 1, 1);

	p = lp_include(i);
	add_include_line(p);

	p = lp_exclude_from(i);
	add_exclude_file(p, 1, 0);

	p = lp_exclude(i);
	add_exclude_line(p);

	log_open();

	if (use_chroot) {
		if (chroot(lp_path(i))) {
			rprintf(FERROR,"chroot %s failed\n", lp_path(i));
			io_printf(fd,"@ERROR: chroot failed\n");
			return -1;
		}

		if (!push_dir("/", 0)) {
			rprintf(FERROR,"chdir %s failed\n", lp_path(i));
			io_printf(fd,"@ERROR: chdir failed\n");
			return -1;
		}

	} else {
		if (!push_dir(lp_path(i), 0)) {
			rprintf(FERROR,"chdir %s failed\n", lp_path(i));
			io_printf(fd,"@ERROR: chdir failed\n");
			return -1;
		}
	}

	if (am_root) {
		if (setgid(gid)) {
			rprintf(FERROR,"setgid %d failed\n", gid);
			io_printf(fd,"@ERROR: setgid failed\n");
			return -1;
		}

		if (setuid(uid)) {
			rprintf(FERROR,"setuid %d failed\n", uid);
			io_printf(fd,"@ERROR: setuid failed\n");
			return -1;
		}

		am_root = (getuid() == 0);
	}

	io_printf(fd,"@RSYNCD: OK\n");

	argv[argc++] = "rsyncd";

	while (1) {
		if (!read_line(fd, line, sizeof(line)-1)) {
			return -1;
		}

		if (!*line) break;

		p = line;

		argv[argc] = strdup(p);
		if (!argv[argc]) {
			return -1;
		}

		if (start_glob) {
			if (start_glob == 1) {
				request = strdup(p);
				start_glob++;
			}
			glob_expand(name, argv, &argc, MAX_ARGS, !use_chroot);
		} else {
			argc++;
		}

		if (strcmp(line,".") == 0) {
			start_glob = 1;
		}

		if (argc == MAX_ARGS) {
			return -1;
		}
	}

	if (!use_chroot) {
		/*
		 * Note that this is applied to all parameters, whether or not
		 *    they are filenames, but no other legal parameters contain
		 *    the forms that need to be sanitized so it doesn't hurt;
		 *    it is not known at this point which parameters are files
		 *    and which aren't.
		 */
		for (i = 1; i < argc; i++) {
			sanitize_path(argv[i]);
		}
	}

	ret = parse_arguments(argc, argv, 0);

	if (request) {
		if (*auth_user) {
			rprintf(FINFO,"rsync %s %s from %s@%s (%s)\n",
				am_sender?"on":"to",
				request, auth_user, host, addr);
		} else {
			rprintf(FINFO,"rsync %s %s from %s (%s)\n",
				am_sender?"on":"to",
				request, host, addr);
		}
		free(request);
	}

#if !TRIDGE
	/* don't allow the logs to be flooded too fast */
	if (verbose > 1) verbose = 1;
#endif

	argc -= optind;
	argp = argv + optind;
	optind = 0;

	if (remote_version > 17 && am_sender)
		io_start_multiplex_out(fd);

	if (!ret) {
		option_error();
	}

	if (lp_timeout(i)) {
		extern int io_timeout;
		io_timeout = lp_timeout(i);
	}

	start_server(fd, fd, argc, argp);

	return 0;
}
Beispiel #6
0
/*****************************************************************************
 *
 * NAME
 *      check_file      - Make sure the specified file exists as specified.
 *
 * SYNOPSIS
 *      check_file_retval = check_file( file, own, grp, mode );
 *
 *      file            r       The name of the file to be verified, changed
 *                              or created.
 *      own             r       The file's owner.
 *      grp             r       The file's group.
 *      mode            r       The file's mode.
 *
 * DESCRIPTION
 *      This routine determines whether <file> exists -and- is a regular file.
 *      If the file doesn't exist, this routine will create it.
 *
 *      In either case, the file's owner will be set to <own>, group will be
 *      set to <grp>, mode will be set to <mode>, and MAC label will be set
 *      to dbadmin (for Trusted IRIX only).
 *
 *      NOTES:  If the owner cannot be changed to <own> because the executing
 *              user does NOT have permission, the error is ignored and this
 *              routine will return a successful indication.
 *
 *              Only the -low order- 9 bits of <mode> are expected to be used.
 *
 *              All file descriptors opened by the processing contained in
 *              this routine are closed -before- control is returned.
 *
 *              If an error occurs and the file was NOT created, this routine
 *              attempts to put the file back to the way it existed upon entry
 *              to this routine.
 *
 *              If an error occurs and the file was created by this routine,
 *              it is removed -before- control is returned to the caller.
 *
 * RETURNS
 *      0       - If the file exists as requested.
 *      1       - If <own> is NOT a valid user name.
 *      2       - If <grp> is NOT a valid group name.
 *      3       - If <mode> has more than the -low order- 9 bits set.
 *      4       - If the file could NOT be creat()'d.
 *      5       - If the stat() system call failed.
 *      6       - If the file's mode could NOT be set as requested.
 *      7       - If the file's group could NOT be set as requested.
 *      8       - If the file's owner could NOT be set as requested.
 *      9       - If <file> exists -and- is NOT a regular file.
 *     10       - If we cannot get the mac_t structure for dbadmin.
 *     11       - If the file's MAC label could NOT be set as requested.
 *
 *****************************************************************************/
check_file_retval
check_file( char *file, char *own, char *grp, mode_t mode )
{
        uid_t   uid;
        gid_t   gid;

#ifdef HAVE_MAC_H
	mac_t   mac_label;
#endif	/* HAVE_MAC_H */
        int     we_created_it = 0;
        check_file_retval  rc = CHK_SUCCESS;
        int     fd;

        struct stat	stbuf;

        if ( ( mode & ~0777 ) != 0 )
                return( CHK_BAD_MODE );

        uid = name_to_uid( own );
        if ( uid < 0 )
                return( CHK_BAD_OWNER );

        gid = name_to_gid( grp );
        if ( gid < 0 )
                return( CHK_BAD_GROUP );

        if ( stat( file, &stbuf ) < 0 )
        {
                if ( ( fd = creat( file, mode ) ) < 0 )
                        return( CHK_NOT_CREATED );

                (void) close( fd );
                we_created_it = 1;

                if ( stat( file, &stbuf ) < 0 )
                        rc = CHK_STAT_FAILED;
        }

        if ( rc == CHK_SUCCESS && ! ( stbuf.st_mode & S_IFREG ) )
                rc = CHK_FILE_NOT_REGULAR;

        if ( rc == CHK_SUCCESS && stbuf.st_gid != gid )
        {
                if ( chown( file, stbuf.st_uid, gid ) < 0 )
                        rc = CHK_CANNOT_SET_GROUP;
        }

        if ( rc == CHK_SUCCESS && ( stbuf.st_mode & 0777 ) != mode )
        {
                if ( chmod( file, mode ) < 0 )
                        rc = CHK_CANNOT_SET_MODE;
        }
        if ( rc == CHK_SUCCESS && stbuf.st_uid != uid )
        {
                if ( chown( file, uid, gid ) < 0 )
                {
                        if ( errno != EPERM )
                                rc = CHK_CANNOT_SET_OWNER;
                }
        }

#ifdef HAVE_MAC_H
	if ( rc == CHK_SUCCESS && sysconf(_SC_MAC) )
	{
		/*
		 *	Set the MAC label of the accounting file to dbadmin.
		 */
		if (( mac_label = mac_from_text( "dbadmin" ) ) == NULL)
			rc = CHK_CANNOT_GET_MAC;
		else if ( mac_set_file( file, mac_label ) < 0 )
			rc = CHK_CANNOT_SET_MAC;
		mac_free( mac_label );
	}
#endif	/* HAVE_MAC_H */
	
        if ( rc != CHK_SUCCESS )
        {
                if ( we_created_it == 1 )
                        (void) unlink( file );
                else
                {
                        (void) chown( file, stbuf.st_uid, stbuf.st_gid );
                        (void) chmod( file, ( stbuf.st_mode & 0777 ) );
                }
        }

        return( rc );
}
Beispiel #7
0
int audit_rule_fieldpair(struct audit_rule *rule, const char *pair, int flags)
{
	const char *f = pair;
	char       *v;
	int        op;
	int        field;
	int        vlen;
    
	if (f == NULL)
		return -1;

	/* look for 2-char operators first
	   then look for 1-char operators afterwards
	   when found, null out the bytes under the operators to split
	   and set value pointer just past operator bytes
	*/
	if ( (v = strstr(pair, "!=")) ) {
		*v++ = '\0';
		*v++ = '\0';
		op = AUDIT_NEGATE; // legacy
		// op = AUDIT_NOT_EQUAL;
	} else if ( (v = strstr(pair, ">")) ) {
		return -10;
	} else if ( (v = strstr(pair, "<")) ) {
		return -10;
	} else if ( (v = strstr(pair, "&")) ) {
		return -10;
	} else if ( (v = strstr(pair, "=")) ) {
		*v++ = '\0';
		op = 0; // legacy 
		// op = AUDIT_EQUAL;
	}

	if (v == NULL)
		return -1;
	
	if (*f == 0)
		return -22;

	if (*v == 0)
		return -20;

	audit_msg(LOG_DEBUG,"pair=%s\n", f);
	if ((field = audit_name_to_field(f)) < 0) 
		return -2;

	/* Exclude filter can be used only with MSGTYPE field */
	if (flags == AUDIT_FILTER_EXCLUDE && field != AUDIT_MSGTYPE)
		return -12; 

	audit_msg(LOG_DEBUG,"f%d%s%s\n", field, audit_operator_to_symbol(op),v);
	rule->fields[rule->field_count] = field | op;
	switch (field)
	{
		case AUDIT_UID:
		case AUDIT_EUID:
		case AUDIT_SUID:
		case AUDIT_FSUID:
		case AUDIT_LOGINUID:
			// Do positive & negative separate for 32 bit systems
			vlen = strlen(v);
			if (isdigit((char)*(v))) 
				rule->values[rule->field_count] = 
					strtoul(v, NULL, 0);
			else if (vlen >= 2 && *(v)=='-' &&
						(isdigit((char)*(v+1))))
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			else {
				if (name_to_uid(v, 
					&rule->values[rule->field_count])) {
					audit_msg(LOG_ERR, "Unknown user: %s",
						v);
					return -2;
				}
			}
			break;
		case AUDIT_GID:
		case AUDIT_EGID:
		case AUDIT_SGID:
		case AUDIT_FSGID:
			if (isdigit((char)*(v))) 
				rule->values[rule->field_count] = 
					strtol(v, NULL, 0);
			else {
				if (name_to_gid(v, 
					&rule->values[rule->field_count])) {
					audit_msg(LOG_ERR, "Unknown group: %s",
						v);
					return -2;
				}
			}
			break;
		case AUDIT_EXIT:
			if (flags != AUDIT_FILTER_EXIT)
				return -7;
			vlen = strlen(v);
			if (isdigit((char)*(v)))
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			else if (vlen >= 2 && *(v)=='-' &&
					(isdigit((char)*(v+1))))
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			else {
				rule->values[rule->field_count] =
						audit_name_to_errno(v);
				if (rule->values[rule->field_count] == 0) 
					return -15;
			}
			break;
		case AUDIT_MSGTYPE:
			if (flags != AUDIT_FILTER_EXCLUDE)
				return -9;

			if (isdigit((char)*(v)))
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			else
				if (audit_name_to_msg_type(v) > 0)
					rule->values[rule->field_count] =
						audit_name_to_msg_type(v);
				else
					return -8;
			break;
		case AUDIT_ARCH:
			if (audit_syscalladded) 
				return -3;
			if (!(op == AUDIT_NEGATE || op == 0))
				return -13;
			if (isdigit((char)*(v))) {
				int machine;

				errno = 0;
				audit_elf = strtoul(v, NULL, 0);
				if (errno) 
					return -5;

				// Make sure we have a valid mapping
				machine = audit_elf_to_machine(audit_elf);
				if (machine < 0)
					return -5;
			}
			else {
				// what do we want? i686, x86_64, ia64
				// or b64, b32
				int machine;
				unsigned int bits=0, elf;
				const char *arch=v;
				if (strcasecmp("b64", arch) == 0) {
					bits = __AUDIT_ARCH_64BIT;
					machine = audit_detect_machine();
				} else if (strcasecmp("b32", arch) == 0) {
					bits = ~__AUDIT_ARCH_64BIT;
					machine = audit_detect_machine();
				} 
				else 
					machine = audit_name_to_machine(arch);

				if (machine < 0) 
					return -4;

				/* Here's where we fixup the machine.
				 * for example, they give x86_64 & want 32 bits.
				 * we translate that to i686. */
				if (bits == ~__AUDIT_ARCH_64BIT &&
					machine == MACH_86_64)
						machine = MACH_X86;
				else if (bits == ~__AUDIT_ARCH_64BIT &&
					machine == MACH_PPC64)
						machine = MACH_PPC;
				else if (bits == ~__AUDIT_ARCH_64BIT &&
					machine == MACH_S390X)
						machine = MACH_S390;

				/* Check for errors - return -6 
				 * We don't allow 32 bit machines to specify 
				 * 64 bit. */
				switch (machine)
				{
					case MACH_X86:
						if (bits == __AUDIT_ARCH_64BIT)
							return -6;
						break;
					case MACH_IA64:
						if (bits == ~__AUDIT_ARCH_64BIT)
							return -6;
						break;
					case MACH_PPC:
						if (bits == __AUDIT_ARCH_64BIT)
							return -6;
						break;
					case MACH_S390:
						if (bits == __AUDIT_ARCH_64BIT)
							return -6;
						break;
					case MACH_86_64: /* fallthrough */
					case MACH_PPC64: /* fallthrough */
					case MACH_S390X: /* fallthrough */
						break;
					default:
						return -6;
				}

				/* OK, we have the machine type, now convert
				   to elf. */
				elf = audit_machine_to_elf(machine);
				if (elf == 0)
					return -5;

				audit_elf = elf;
			}
			rule->values[rule->field_count] = audit_elf;
			audit_archadded = 1;
			break;
		case AUDIT_FILETYPE:
			if (flags != AUDIT_FILTER_EXIT && flags != AUDIT_FILTER_ENTRY)
				return -17;
			rule->values[rule->field_count] =
				audit_name_to_ftype(v);
			if (rule->values[rule->field_count] < 0) {
				return -16;
			}
			break;
		/* These are strings */
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
		case AUDIT_WATCH:
		case AUDIT_PERM:
		case AUDIT_DIR:
		case AUDIT_FILTERKEY:
			return -10;
                case AUDIT_ARG0...AUDIT_ARG3:
			vlen = strlen(v);
			if (isdigit((char)*(v)))
				rule->values[rule->field_count] =
					strtoul(v, NULL, 0);
			else if (vlen >= 2 && *(v)=='-' &&
						(isdigit((char)*(v+1))))
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			else
				return -21;
			break;
                case AUDIT_DEVMAJOR...AUDIT_INODE:
                case AUDIT_SUCCESS:
			if (flags != AUDIT_FILTER_EXIT)
				return -7;
			/* fallthrough */
		default:
			if (field == AUDIT_INODE) {
				if (!(op == AUDIT_NEGATE || op == 0))
					return -13;
			}
			if (field == AUDIT_PPID && (flags != AUDIT_FILTER_EXIT
				&& flags != AUDIT_FILTER_ENTRY))
				return -17;
			
			if (flags == AUDIT_FILTER_EXCLUDE)
				return -18;
			
			if (!isdigit((char)*(v)))
				return -21;

			if (field == AUDIT_INODE) 
				rule->values[rule->field_count] =
						strtoul(v, NULL, 0);
			else
				rule->values[rule->field_count] =
						strtol(v, NULL, 0);
			break;
	}
	++rule->field_count;
	return 0;
}
Beispiel #8
0
/**
 * @brief Lookup a name using PAM
 *
 * @param[in]  name       C string of name
 * @param[in]  len        Length of name
 * @param[out] id         ID found
 * @param[in]  anon       ID to use in case of nobody
 * @param[in]  group      Whether this a group lookup
 * @param[out] gss_gid    Found GID
 * @param[out] gss_uid    Found UID
 * @apram[out] gotgss_gid Found a GID.
 * @param[in]  at         Location of the @
 *
 * @return true on success, false not making the grade
 */
static bool pwentname2id(char *name, size_t len, uint32_t *id,
			 const uint32_t anon, bool group, gid_t *gid,
			 bool *got_gid, char *at)
{
	if (at != NULL) {
		if (strcmp(at + 1, owner_domain.addr) != 0) {
			/* We won't map what isn't even in the right domain */
			return false;
		}
		*at = '\0';
	}
	if (group) {
		int err;

		err = name_to_gid(name, id);
		if (err == 0)
			return true;
		else if (err != ENOENT) {
			LogWarn(COMPONENT_IDMAPPER,
				"getgrnam_r %s failed, error: %d", name, err);
			return false;
		}
#ifndef USE_NFSIDMAP
		else {
			char *end = NULL;
			gid_t gid;

			gid = strtol(name, &end, 10);
			if (end && *end != '\0')
				return 0;

			*id = gid;
			return true;
		}
#endif
	} else {
		struct passwd p;
		struct passwd *pres;
		int size = sysconf(_SC_GETPW_R_SIZE_MAX);
		char *buf;

		if (size == -1)
			size = PWENT_BEST_GUESS_LEN;

		buf = alloca(size);

		if (getpwnam_r(name, &p, buf, size, &pres) != 0) {
			LogInfo(COMPONENT_IDMAPPER, "getpwnam_r %s failed",
				name);
			return false;
		} else if (pres != NULL) {
			*id = pres->pw_uid;
			*gid = pres->pw_gid;
			*got_gid = true;
			return true;
		}
#ifndef USE_NFSIDMAP
		else {
			char *end = NULL;
			uid_t uid;

			uid = strtol(name, &end, 10);
			if (end && *end != '\0')
				return 0;

			*id = uid;
			*got_gid = false;
			return true;
		}
#endif
	}
	return false;
}