added jeremy's new c++-like code for parsing of security descriptors.
[samba.git] / source3 / lib / util_sid.c
index cce360f4c1998303914771a1175c3b8f45303fe7..77997df1e68da60b829cf7a7251aeedbf1a4beb4 100644 (file)
@@ -29,7 +29,7 @@ extern int DEBUGLEVEL;
  Convert a SID to an ascii string.
 *****************************************************************/
 
-char *sid_to_string(pstring sidstr_out, DOM_SID *sid)
+char *sid_to_string(pstring sidstr_out, const DOM_SID *sid)
 {
   char subauth[16];
   int i;
@@ -39,11 +39,11 @@ char *sid_to_string(pstring sidstr_out, DOM_SID *sid)
               (sid->id_auth[3] << 16) +
               (sid->id_auth[2] << 24);
 
-  slprintf(sidstr_out, sizeof(pstring) - 1, "S-%d-%d", sid->sid_rev_num, ia);
+  slprintf(sidstr_out, sizeof(pstring) - 1, "S-%u-%lu", (unsigned int)sid->sid_rev_num, (unsigned long)ia);
 
   for (i = 0; i < sid->num_auths; i++)
   {
-    slprintf(subauth, sizeof(subauth)-1, "-%u", sid->sub_auths[i]);
+    slprintf(subauth, sizeof(subauth)-1, "-%lu", (unsigned long)sid->sub_auths[i]);
     pstrcat(sidstr_out, subauth);
   }
 
@@ -55,62 +55,63 @@ char *sid_to_string(pstring sidstr_out, DOM_SID *sid)
  Convert a string to a SID. Returns True on success, False on fail.
 *****************************************************************/  
    
-BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
+BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
 {
-  pstring tok;
-  char *p = sidstr;
-  /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
-  uint32 ia;
+       const char *p = sidstr;
+       /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
+       uint32 ia;
 
-  memset((char *)sidout, '\0', sizeof(DOM_SID));
+       memset((char *)sidout, '\0', sizeof(DOM_SID));
 
-  if (StrnCaseCmp( sidstr, "S-", 2)) {
-    DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
-    return False;
-  }
+       if (StrnCaseCmp( sidstr, "S-", 2))
+       {
+               DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
+               return False;
+       }
 
-  p += 2;
-  if (!next_token(&p, tok, "-", sizeof(tok))) {
-    DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
-    return False;
-  }
+       if ((p = strchr(p, '-')) == NULL)
+       {
+               DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
+               return False;
+       }
 
-  /* Get the revision number. */
-  sidout->sid_rev_num = atoi(tok);
+       p++;
 
-  if (!next_token(&p, tok, "-", sizeof(tok))) {
-    DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
-    return False;
-  }
+       /* Get the revision number. */
+       sidout->sid_rev_num = (uint8)strtoul(p,NULL,10);
 
-  /* identauth in decimal should be <  2^32 */
-  ia = atoi(tok);
+       if ((p = strchr(p, '-')) == NULL)
+       {
+               DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
+               return False;
+       }
 
-  /* NOTE - the ia value is in big-endian format. */
-  sidout->id_auth[0] = 0;
-  sidout->id_auth[1] = 0;
-  sidout->id_auth[2] = (ia & 0xff000000) >> 24;
-  sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
-  sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
-  sidout->id_auth[5] = (ia & 0x000000ff);
+       p++;
 
-  sidout->num_auths = 0;
+       /* identauth in decimal should be <  2^32 */
+       ia = (uint32)strtoul(p,NULL,10);
 
-  while(next_token(&p, tok, "-", sizeof(tok)) && 
-       sidout->num_auths < MAXSUBAUTHS)
-  {
-    /* 
-     * NOTE - the subauths are in native machine-endian format. They
-     * are converted to little-endian when linearized onto the wire.
-     */
-       uint32 rid = (uint32)strtoul(tok, NULL, 10);
-       DEBUG(50,("string_to_sid: tok: %s rid 0x%x\n", tok, rid));
-       sid_append_rid(sidout, rid);
-  }
+       /* NOTE - the ia value is in big-endian format. */
+       sidout->id_auth[0] = 0;
+       sidout->id_auth[1] = 0;
+       sidout->id_auth[2] = (ia & 0xff000000) >> 24;
+       sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
+       sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
+       sidout->id_auth[5] = (ia & 0x000000ff);
 
-  DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));
+       sidout->num_auths = 0;
 
-  return True;
+       while (((p = strchr(p, '-')) != NULL) && sidout->num_auths < MAXSUBAUTHS)
+       {
+               p++;
+               /*
+                * NOTE - the subauths are in native machine-endian format. They
+                * are converted to little-endian when linearized onto the wire.
+                */
+               sid_append_rid(sidout, (uint32)strtoul(p, NULL, 10));
+       }
+
+       return True;
 }
 
 /*****************************************************************
@@ -134,7 +135,10 @@ BOOL sid_split_rid(DOM_SID *sid, uint32 *rid)
        if (sid->num_auths > 0)
        {
                sid->num_auths--;
-               (*rid) = sid->sub_auths[sid->num_auths];
+               if (rid != NULL)
+               {
+                       (*rid) = sid->sub_auths[sid->num_auths];
+               }
                return True;
        }
        return False;
@@ -143,7 +147,7 @@ BOOL sid_split_rid(DOM_SID *sid, uint32 *rid)
 /*****************************************************************
  copies a sid
 *****************************************************************/  
-void sid_copy(DOM_SID *sid1, DOM_SID *sid2)
+void sid_copy(DOM_SID *sid1, const DOM_SID *sid2)
 {
        int i;
 
@@ -160,10 +164,35 @@ void sid_copy(DOM_SID *sid1, DOM_SID *sid2)
        sid1->num_auths   = sid2->num_auths;
        sid1->sid_rev_num = sid2->sid_rev_num;
 }
+
+/*****************************************************************
+ compare two sids up to the auths of the first sid
+*****************************************************************/  
+BOOL sid_front_equal(const DOM_SID *sid1, const DOM_SID *sid2)
+{
+       int i;
+
+       /* compare most likely different rids, first: i.e start at end */
+       for (i = sid1->num_auths-1; i >= 0; --i)
+       {
+               if (sid1->sub_auths[i] != sid2->sub_auths[i]) return False;
+       }
+
+       if (sid1->num_auths   >  sid2->num_auths  ) return False;
+       if (sid1->sid_rev_num != sid2->sid_rev_num) return False;
+
+       for (i = 0; i < 6; i++)
+       {
+               if (sid1->id_auth[i] != sid2->id_auth[i]) return False;
+       }
+
+       return True;
+}
+
 /*****************************************************************
  compare two sids
 *****************************************************************/  
-BOOL sid_equal(DOM_SID *sid1, DOM_SID *sid2)
+BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
 {
        int i;
 
@@ -188,7 +217,7 @@ BOOL sid_equal(DOM_SID *sid1, DOM_SID *sid2)
 /*****************************************************************
  calculates size of a sid
 *****************************************************************/  
-int sid_size(DOM_SID *sid)
+int sid_size(const DOM_SID *sid)
 {
        if (sid == NULL)
        {
@@ -196,3 +225,23 @@ int sid_size(DOM_SID *sid)
        }
        return sid->num_auths * sizeof(uint32) + 8;
 }
+
+
+/*****************************************************************
+ Duplicates a sid - mallocs the target.
+*****************************************************************/
+
+DOM_SID *sid_dup(DOM_SID *src)
+{
+  DOM_SID *dst;
+
+  if(!src)
+    return NULL;
+
+  if((dst = malloc(sizeof(DOM_SID))) != NULL) {
+       memset(dst, '\0', sizeof(DOM_SID));
+       sid_copy( dst, src);
+  }
+
+  return dst;
+}