access_table() challenge status

Cole, Timothy D. timothy_d_cole at md.northgrum.com
Tue Jan 18 18:31:02 GMT 2000



> -----Original Message-----
> From:	Andrew Tridgell [SMTP:tridge at linuxcare.com]
> Sent:	Tuesday, January 18, 2000 7:01
> To:	Multiple recipients of list SAMBA-TECHNICAL
> Subject:	access_table() challenge status
> 
> Thanks for all the contributions!
> 
> The submission from Paul Mackerras is the leader so far. Mattys
> submission would be the best (by a long way!) if it handled the
> DENY_FCB case. Mattys certainly gives the most insight into how this
> stuff works.
> 
> Here is Mattys in case anyone missed it. It is very simple
> conceptually (only two ugly conditionals) but doesn't even attempt
> DENY_FCB.
> 
	Okay, I took the FCB code from my attempt after optimizing it a bit
more (I'm glad I factored it out when I first wrote it :P), and merged it
with Matty's.  The clarity of the code has suffered somewhat, but I think
the FCB stuff is going to be evil no matter how you handle it.  In any case,
here's the result:

	static int deny_mask(int deny) {
		switch (deny) {
		  case DENY_READ: return 1;
		  case DENY_WRITE: return 2;
		  case DENY_ALL: return 3;
		  default: return 0;
		}
	}

	static int mode_mask(int mode) {
		switch (mode) {
		  case DOS_OPEN_RDONLY:	return 1;
		  case DOS_OPEN_WRONLY: return 2;
		  case DOS_OPEN_RDWR: return 3;
		  default: return 0;
		}
	}

	static BOOL is_compatible(int old_deny, int old_mode, int new_deny,
	                        int new_mode, BOOL same_process, BOOL isexe)
	{
		if ( old_deny == DENY_DOS ) {
	        	return isexe || ( ( old_mode == DOS_OPEN_RDONLY )
			               && ( new_mode == DOS_OPEN_RDONLY ) )
			             || ( same_process && ( old_deny ==
DENY_DOS )
			               && ( new_deny == DENY_DOS ) );
		} else {
			return !( mode_mask(new_mode) & deny_mask(old_deny)
);
		}
	}

	static BOOL is_allowed(int new_deny, int new_mode, int old_deny,
	                        int old_mode, BOOL same_process, BOOL isexe)
	{
	        if ((old_deny == DENY_DOS) && (old_mode == DOS_OPEN_RDONLY)
	                && (new_mode != DOS_OPEN_RDONLY) && same_process &&
!isexe)
	                return 0;

	        return is_compatible(old_deny, old_mode, new_deny, new_mode,
	                                                same_process, isexe)
	                && is_compatible(new_deny, new_mode, old_deny,
old_mode,
	                                                same_process,
isexe);
	}


	static int access_table2(int new_deny,int old_deny,int old_mode,
				 BOOL same_pid, BOOL isexe)
	{
		BOOL r, w;

		if (isexe) {
			if ( old_deny == DENY_FCB ) switch (new_deny) {
			  case DENY_FCB:
			  case DENY_DOS:
				return same_pid ? AALL : AFAIL;
			  default:
				return AFAIL;
			} else if ( new_deny == DENY_FCB ) {
				return AFAIL;
			}
		} else {
			if ( old_deny == DENY_FCB ) switch (new_deny) {
			  case DENY_FCB:
			  case DENY_DOS:
			  case DENY_WRITE:
				if (same_pid) return ( new_deny ==
DENY_WRITE )
				                   ? AFAIL : AALL;
				return ( old_mode == DOS_OPEN_RDONLY ) ?
AREAD : AFAIL;
			  case DENY_NONE:
				if ( !same_pid && ( old_mode ==
DOS_OPEN_RDONLY ) ) {
					return AREAD;
				}
			  default:
				return AFAIL;
			} else if ( new_deny == DENY_FCB ) switch (old_deny)
{
			  case DENY_DOS:
				if (same_pid) {
					return ( old_mode != DOS_OPEN_RDONLY
)
					     ? AALL : AFAIL;
				}
				if ( deny_mask(new_deny) &
mode_mask(old_mode) ) {
					return AFAIL;
				}
			  case DENY_WRITE:
			  case DENY_NONE:
				return ( old_mode == DOS_OPEN_RDONLY ) ?
AREAD : AFAIL;
			  default:
				return AFAIL;
			}
		}

		r = is_allowed(new_deny, DOS_OPEN_RDONLY, old_deny,
old_mode, same_pid,
			       isexe);
		w = is_allowed(new_deny, DOS_OPEN_WRONLY, old_deny,
old_mode, same_pid,
			       isexe);
		
		if (r && w) return AALL;
		if (r) return AREAD;
		if (w) return AWRITE;
		return AFAIL;
	}


More information about the samba-technical mailing list