Index: include/lib.h
===================================================================
--- include/lib.h	(revision 67)
+++ include/lib.h	(working copy)
@@ -1,6 +1,7 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <sys/types.h>
 #include <stdio.h>
 #include <setjmp.h>
@@ -101,6 +102,7 @@
 char *j_strdup(const char *str); /* provides NULL safe strdup wrapper */
 char *j_strcat(char *dest, char *txt); /* strcpy() clone */
 int j_strcmp(const char *a, const char *b); /* provides NULL safe strcmp wrapper */
+int j_strcasecmp(const char *a, const char *b); /* provides NULL safe strcasecmp wrapper */
 int j_strncmp(const char *a, const char *b, int i); /* provides NULL safe strncmp wrapper */
 int j_strncasecmp(const char *a, const char *b, int i); /* provides NULL safe strncasecmp wrapper */
 int j_strlen(const char *a); /* provides NULL safe strlen wrapper */
@@ -299,10 +301,10 @@
 
 
 typedef struct {
-  unsigned long H[5];
-  unsigned long W[80];
+  uint32_t H[5];
+  uint32_t W[80];
   int lenW;
-  unsigned long sizeHi,sizeLo;
+  uint32_t sizeHi,sizeLo;
 } j_SHA_CTX;
 
 
Index: include/conference.h
===================================================================
--- include/conference.h	(revision 67)
+++ include/conference.h	(working copy)
@@ -258,6 +258,7 @@
 							/* Adds extended presence info to a presence packet */
 void add_status_code(xmlnode presence, char *status); /* add a muc status code to a presence stanza */
 void add_room_status_codes(xmlnode presence, cnr room); /* add room specific status codes (logging, anonymous, ...) */ 
+int check_affiliation(GHashTable * ght, jid user, char * affiliation_name); /* Check if user as a particular affiliation */
 int is_sadmin(cni master, jid user);			/* Check if user is server admin */
 int is_owner(cnr room, jid user);			/* Check if user is room owner */
 int is_admin(cnr room, jid user);			/* Check if user is room admin */
Index: src/utils.c
===================================================================
--- src/utils.c	(revision 67)
+++ src/utils.c	(working copy)
@@ -136,6 +136,45 @@
   }
 }
 
+/* Generic function to check if an user as a particular affiliation */
+int check_affiliation(GHashTable * ght, jid user, char * affiliation_name)
+{
+  char ujid[3072];
+
+  snprintf(ujid, sizeof(ujid), "%s@%s", user->user, user->server);
+
+  if(g_hash_table_lookup(ght, ujid) != NULL )
+  {
+    log_debug(NAME, "[%s] Is %s? >%s< - Yes (case 1)", FZONE, affiliation_name, jid_full(user));
+    return 1;
+  }
+
+  if(g_hash_table_lookup(ght, user->server) != NULL )
+  {
+    log_debug(NAME, "[%s] Is %s? >%s< - Yes (case 2)", FZONE, affiliation_name, jid_full(user));
+    return 1;
+  }
+
+  snprintf(ujid, sizeof(ujid), "%s@%s/%s", user->user, user->server, user->resource);
+
+  if(g_hash_table_lookup(ght, ujid) != NULL )
+  {
+    log_debug(NAME, "[%s] Is %s? >%s< - Yes (case 3)", FZONE, affiliation_name, jid_full(user));
+    return 1;
+  }
+
+  snprintf(ujid, sizeof(ujid), "%s/%s", user->server, user->resource);
+
+  if(g_hash_table_lookup(ght, ujid) != NULL )
+  {
+    log_debug(NAME, "[%s] Is %s? >%s< - Yes (case 4)", FZONE, affiliation_name, jid_full(user));
+    return 1;
+  }
+
+  log_debug(NAME, "[%s] Is %s? >%s< - No", FZONE, affiliation_name, jid_full(user));
+  return 0;
+}
+
 /* Is the user a Service Admin? */
 int is_sadmin(cni master, jid user)
 {
@@ -159,62 +198,46 @@
 /* Is the user an owner for that room */
 int is_owner(cnr room, jid user)
 {
-  char ujid[2048];
-  char cjid[2048];
-
   if(room == NULL || user == NULL)
   {
     log_warn(NAME, "[%s] ERR: Missing variable in is_owner", FZONE);
     return 0;
   }
 
-  snprintf(ujid, sizeof(ujid), "%s@%s", user->user, user->server);
-  if(room->creator)
-  {
-    snprintf(cjid, sizeof(cjid), "%s@%s", room->creator->user, room->creator->server);
-  }
-  else
-  {
-    snprintf(cjid, sizeof(cjid), "@");
-  }
-
   log_debug(NAME, "[%s] Is Owner? >%s<", FZONE, jid_full(user));
 
   /* Server admin can override */
   if(is_sadmin(room->master, user))
+  {
+    log_debug(NAME, "[%s] Is Owner? >%s< - Yes (service admin)", FZONE, jid_full(user));
     return 2;
-  else if(j_strcmp(cjid, ujid) == 0)
+  }
+
+  if(room->creator && j_strcmp(user->user, room->creator->user) == 0 && j_strcmp(user->server, room->creator->server) == 0)
+  {
+    log_debug(NAME, "[%s] Is Owner? >%s< - Yes (creator)", FZONE, jid_full(user));
     return 1;
-  else if(g_hash_table_lookup(room->owner, ujid) != NULL )
-    return 1;
-  else
-    return 0;
+  }
 
+  return check_affiliation(room->owner, user, "Owner");
 }
 
 /* Is the user in the admin affiliation list for that room */
 int is_admin(cnr room, jid user)
 {
-  char ujid[2048];
-
   if(room == NULL || user == NULL)
   {
     log_warn(NAME, "[%s] ERR: Missing variable in is_admin", FZONE);
     return 0;
   }
 
-  snprintf(ujid, sizeof(ujid), "%s@%s", user->user, user->server);
-  log_debug(NAME, "[%s] Is Admin? >%s<", FZONE, jid_full(user));
-
   if(is_owner(room, user))
+  {
+    log_debug(NAME, "[%s] Is Admin? >%s< - Yes (owner)", FZONE, jid_full(user));
     return 2;
+  }
 
-  if(g_hash_table_lookup(room->admin, ujid) != NULL )
-    return 1;
-  else if(g_hash_table_lookup(room->admin, user->server) != NULL )
-    return 1;
-  else
-    return 0;
+  return check_affiliation(room->admin, user, "Admin");
 }
 
 /* Is the user in the moderator role list for that room */
@@ -271,16 +294,12 @@
 /* Is the user in the member affiliation list for that room */
 int is_member(cnr room, jid user)
 {
-  char ujid[2048];
-
   if(room == NULL || user == NULL)
   {
     log_warn(NAME, "[%s] ERR: Missing variable in is_member", FZONE);
     return 0;
   }
 
-  snprintf(ujid, sizeof(ujid), "%s@%s", user->user, user->server);
-
   /* Owner is automatically a member */
   if(is_owner(room, user))
   {
@@ -295,42 +314,19 @@
     return 1;
   }
 
-  if(g_hash_table_lookup(room->member, ujid) != NULL )
-  {
-    log_debug(NAME, "[%s] Is Member? >%s< - Yes (case 1)", FZONE, jid_full(user));
-    return 1;
-  }
-  else if(g_hash_table_lookup(room->member, user->server) != NULL )
-  {
-    log_debug(NAME, "[%s] Is Member? >%s< - Yes (case 2)", FZONE, jid_full(user));
-    return 1;
-  }
-  else
-  {
-    log_debug(NAME, "[%s] Is Member? >%s< - No", FZONE, jid_full(user));
-    return 0;
-  }
+  return check_affiliation(room->member, user, "Member");
 }
 
 /* Is the user in the outcast affiliation list for that room */
 int is_outcast(cnr room, jid user)
 {
-  char ujid[2048];
-
   if(room == NULL || user == NULL)
   {
     log_warn(NAME, "[%s] ERR: Missing variable in is_outcast", FZONE);
     return 0;
   }
 
-  snprintf(ujid, sizeof(ujid), "%s@%s", user->user, user->server);
-
-  if(g_hash_table_lookup(room->outcast, ujid) != NULL )
-    return 1;
-  else if(g_hash_table_lookup(room->outcast, user->server) != NULL )
-    return 1;
-  else
-    return 0;
+  return check_affiliation(room->outcast, user, "Outcast");
 }
 
 /* Only return 1 if visitor */
Index: src/conference_room.c
===================================================================
--- src/conference_room.c	(revision 67)
+++ src/conference_room.c	(working copy)
@@ -1018,7 +1018,7 @@
 
       if( nick == NULL)
       {
-        log_debug(NAME, "[%s] No receipient, returning error", FZONE);
+        log_debug(NAME, "[%s] No recipient, returning error", FZONE);
 
         jutil_error(jp->x,TERROR_BAD);
         deliver(dpacket_new(jp->x),NULL);
@@ -1031,6 +1031,15 @@
       {
         id = jid_new(xmlnode_pool(item), nick);
 
+        if (id == NULL)
+        {
+          log_debug(NAME, "[%s] Bad recipient, returning error", FZONE);
+          jutil_error(jp->x,TERROR_BAD);
+          deliver(dpacket_new(jp->x),NULL);
+
+          xmlnode_free(item);
+          return;
+        }
         key = j_strdup(jid_full(jid_user(jid_fix(id))));
         g_hash_table_insert(room->member, key, (void*)item);
       }
@@ -1498,7 +1507,7 @@
 
     room->creator = jid_new(room->p, jid_full(jid_user(admin->realid)));
 
-    add_affiliate(room->owner, admin->realid, NULL);
+    add_affiliate(room->owner, jid_user(admin->realid), NULL);
 
     log_debug(NAME, "[%s] Added new admin: %s to room %s", FZONE, jid_full(jid_fix(owner)), jid_full(room->id));
   }
Index: src/roles.c
===================================================================
--- src/roles.c	(revision 67)
+++ src/roles.c	(working copy)
@@ -73,14 +73,37 @@
   xmlnode old;
   xmlnode store;
   xmlnode node;
-  char ujid[2048];
+  char ujid[3072];
 
   if(userid == NULL)
   {
     return -1;
   }
 
-  snprintf(ujid, sizeof(ujid), "%s@%s", userid->user, userid->server);
+
+  if(userid->user == NULL)
+  {
+    if(userid->resource == NULL)
+    {
+      snprintf(ujid, sizeof(ujid), "%s", userid->server);
+    }
+    else
+    {
+      snprintf(ujid, sizeof(ujid), "%s/%s", userid->server, userid->resource);
+    }
+  }
+  else
+  {
+    if(userid->resource == NULL)
+    {
+      snprintf(ujid, sizeof(ujid), "%s@%s", userid->user, userid->server);
+    }
+    else
+    {
+      snprintf(ujid, sizeof(ujid), "%s@%s/%s", userid->user, userid->server, userid->resource);
+
+    }
+  }
   old = g_hash_table_lookup(hash, ujid);
 
   /* User not previously registered. Set up */
@@ -121,18 +144,42 @@
   xmlnode old;
   xmlnode store;
   xmlnode node;
-  char ujid[2048];
+  char ujid[3072];
 
   if(userid == NULL)
   {
     return -1;
   }
 
-  snprintf(ujid, sizeof(ujid), "%s@%s", userid->user, userid->server);
+  if(userid->user == NULL)
+  {
+    if(userid->resource == NULL)
+    {
+      snprintf(ujid, sizeof(ujid), "%s", userid->server);
+    }
+    else
+    {
+      snprintf(ujid, sizeof(ujid), "%s/%s", userid->server, userid->resource);
+    }
+  }
+  else
+  {
+    if(userid->resource == NULL)
+    {
+      snprintf(ujid, sizeof(ujid), "%s@%s", userid->user, userid->server);
+    }
+    else
+    {
+      snprintf(ujid, sizeof(ujid), "%s@%s/%s", userid->user, userid->server, userid->resource);
+
+    }
+  }
   old = g_hash_table_lookup(hash, ujid);
 
   if(old == NULL)
+  {
     return 1;
+  }
 
   store = xmlnode_dup(old);
 
@@ -158,14 +205,36 @@
   xmlnode store;
   xmlnode current;
   char *userjid;
-  char ujid[2048];
+  char ujid[3072];
 
   if(userid == NULL)
   {
     return;
   }
 
-  snprintf(ujid, sizeof(ujid), "%s@%s", userid->user, userid->server);
+  if(userid->user == NULL)
+  {
+    if(userid->resource == NULL)
+    {
+      snprintf(ujid, sizeof(ujid), "%s", userid->server);
+    }
+    else
+    {
+      snprintf(ujid, sizeof(ujid), "%s/%s", userid->server, userid->resource);
+    }
+  }
+  else
+  {
+    if(userid->resource == NULL)
+    {
+      snprintf(ujid, sizeof(ujid), "%s@%s", userid->user, userid->server);
+    }
+    else
+    {
+      snprintf(ujid, sizeof(ujid), "%s@%s/%s", userid->user, userid->server, userid->resource);
+
+    }
+  }
   store = g_hash_table_lookup(hash, ujid);
 
   if(store == NULL)
Index: src/conference.c
===================================================================
--- src/conference.c	(revision 67)
+++ src/conference.c	(working copy)
@@ -538,6 +538,15 @@
       xmlnode_hide_attrib(jp->x, "type");
     }
 
+    // clean the packet from any x muc#user tag
+    for( node = xmlnode_get_firstchild(jp->x); node != NULL; node = xmlnode_get_nextsibling(node)) {
+      if (xmlnode_get_name(node)==NULL || strcmp("x",xmlnode_get_name(node))!=0) continue; // check if the node is a "x" node
+      if(NSCHECK(node, NS_MUC_USER))
+      {
+        xmlnode_hide(node);
+      }
+    }
+
     priority = jutil_priority(jp->x);
   }
 
@@ -578,7 +587,7 @@
     }
 
     /* Don't allow user if locknicks is set and resource != JID user */
-    if ( ((master->locknicks || room->locknicks) && (j_strcmp(jp->to->resource, jp->from->user) != 0)) && !is_sadmin(master, jp->from) ) {
+    if ( ((master->locknicks || room->locknicks) && (j_strcasecmp(jp->to->resource, jp->from->user) != 0)) && !is_sadmin(master, jp->from) ) {
       log_debug(NAME, "[%s] Nicknames locked - Requested nick %s doesn't match required username %s",
           FZONE, jp->to->resource, jp->from->user);
 
Index: src/jabberd/str.c
===================================================================
--- src/jabberd/str.c	(revision 67)
+++ src/jabberd/str.c	(working copy)
@@ -65,11 +65,15 @@
     if(a == NULL || b == NULL)
         return -1;
 
-    while(*a == *b && *a != '\0' && *b != '\0'){ a++; b++; }
+    return strcmp(a, b);
+}
 
-    if(*a == *b) return 0;
+int j_strcasecmp(const char *a, const char *b)
+{
+    if(a == NULL || b == NULL)
+        return -1;
 
-    return -1;
+    return strcasecmp(a, b);
 }
 
 int j_strncmp(const char *a, const char *b, int i)
Index: src/jabberd/sha.c
===================================================================
--- src/jabberd/sha.c	(revision 67)
+++ src/jabberd/sha.c	(working copy)
@@ -50,7 +50,7 @@
    */
   for (i = 0; i < len; i++) {
     ctx->W[ctx->lenW / 4] <<= 8;
-    ctx->W[ctx->lenW / 4] |= (unsigned long)dataIn[i];
+    ctx->W[ctx->lenW / 4] |= (uint32_t)dataIn[i];
     if ((++ctx->lenW) % 64 == 0) {
       shaHashBlock(ctx);
       ctx->lenW = 0;
@@ -109,7 +109,7 @@
 
 static void shaHashBlock(j_SHA_CTX *ctx) {
   int t;
-  unsigned long A,B,C,D,E,TEMP;
+  uint32_t A,B,C,D,E,TEMP;
 
   for (t = 16; t <= 79; t++)
     ctx->W[t] =
