NTSTATUS/WERROR changes

Andrew Tridgell tridge at samba.org
Tue Sep 4 04:17:05 GMT 2001


I've just finished a large set of changes in how Samba handles
errors. Please read this if you are working on Samba code. The changes
are only in the head branch (ie. Samba 3.x)

The changes are an attempt to catch some very common coding errors in
Samba. The most common error that will be caught is mixing BOOL with a
uint32 nt_status value. We had quite a few places where we did:

  if (!foo = malloc(n)) return False;

in a function that returns a uint32 NT status value. The problem is
that False is zero, so we were in fact returning the NT success
value. Not good.

The fix is to make BOOL, int and uint32 incompative with a new type
called NTSTATUS. The compiler will then catch these types of bugs,
along with a wide range of similar bugs. 

Unfortunately C does not have a standard way of making integral types
incompatible, so I used a common trick in gcc and some other compilers
that allows you to create constant structures. On systems that support
this the type NTSTATUS is a structure containing a single uint32
element. Because you can't mix structures and integral types in C this
generates a error on any attempt to mix the types.

To support this I added some macros like this:

#if defined(HAVE_IMMEDIATE_STRUCTURES)
typedef struct {uint32 v;} NTSTATUS;
#define NT_STATUS(x) ((NTSTATUS) { x })
#define NT_STATUS_V(x) ((x).v)
#else
typedef uint32 NTSTATUS;
#define NT_STATUS(x) (x)
#define NT_STATUS_V(x) (x)
#endif

and this for the completely different win32 error space that I have
called WERROR

#if defined(HAVE_IMMEDIATE_STRUCTURES)
typedef struct {uint32 v;} WERROR;
#define W_ERROR(x) ((WERROR) { x })
#define W_ERROR_V(x) ((x).v)
#else
typedef uint32 WERROR;
#define W_ERROR(x) (x)
#define W_ERROR_V(x) (x)
#endif

which means we catch places where we attempt to mix win32 and NT error
codes (we were doing that in quite a few places).

Finally, the following 3 macros are used to check for the special
success value for these types:

#define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0)
#define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000)
#define W_ERROR_IS_OK(x) (W_ERROR_V(x) == 0)


What I'd like to see is Samba gradually moving away from using BOOL
and instead use NTSTATUS internally. We have a lot of problems with
now with returning the right error code in the right place and I think
that by converting to NTSTATUS we will fix a lot of these. It should
now be easier to make this transition without screwing up.

I have also added error mapping functions that convert betwen the 3
different types of error codes we need to deal with (unix errno,
ntstatus, win32 errors and dos errors). These aren't perfect yet, but
they are a good start.

We might convert some more types to structures like this soon once we
see how this goes. An obvious candidate is BOOL, but that has some
potential problems.

Cheers, Tridge




More information about the samba-technical mailing list