r23779: Change from v2 or later to v3 or later.
[amitay/samba.git] / source3 / lib / util_sid.c
index f3f6c938ee55452b61eb8a6ebb8edae411fe1620..1473190abd5e77df2508350e4a4f32e6a6ce5a56 100644 (file)
@@ -6,10 +6,11 @@
    Copyright (C) Jeremy Allison                1999
    Copyright (C) Stefan (metze) Metzmacher     2002
    Copyright (C) Simo Sorce                    2002
+   Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
       
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -73,12 +74,22 @@ const DOM_SID global_sid_Builtin_Backup_Operators = /* Builtin backup operators
 { 1, 2, {0,0,0,0,0,5}, {32,551,0,0,0,0,0,0,0,0,0,0,0,0,0}};
 const DOM_SID global_sid_Builtin_Replicator =          /* Builtin replicator */
 { 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_PreWin2kAccess =      /* Builtin pre win2k access */
+{ 1, 2, {0,0,0,0,0,5}, {32,554,0,0,0,0,0,0,0,0,0,0,0,0,0}};
 
+const DOM_SID global_sid_Unix_Users =                  /* Unmapped Unix users */
+{ 1, 1, {0,0,0,0,0,22}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Unix_Groups =                 /* Unmapped Unix groups */
+{ 1, 1, {0,0,0,0,0,22}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+/* Unused, left here for documentary purposes */
+#if 0
 #define SECURITY_NULL_SID_AUTHORITY    0
 #define SECURITY_WORLD_SID_AUTHORITY   1
 #define SECURITY_LOCAL_SID_AUTHORITY   2
 #define SECURITY_CREATOR_SID_AUTHORITY 3
 #define SECURITY_NT_AUTHORITY          5
+#endif
 
 /*
  * An NT compatible anonymous token.
@@ -99,7 +110,7 @@ NT_USER_TOKEN system_token = { 1, system_sid_array, SE_ALL_PRIVS };
 ****************************************************************************/
 
 static const struct {
-       enum SID_NAME_USE sid_type;
+       enum lsa_SidType sid_type;
        const char *string;
 } sid_name_type[] = {
        {SID_NAME_USER, "User"},
@@ -112,7 +123,7 @@ static const struct {
        {SID_NAME_UNKNOWN, "UNKNOWN"},
        {SID_NAME_COMPUTER, "Computer"},
 
-       {(enum SID_NAME_USE)0, NULL}
+       {(enum lsa_SidType)0, NULL}
 };
 
 const char *sid_type_lookup(uint32 sid_type) 
@@ -152,59 +163,6 @@ const char *get_global_sam_name(void)
        return global_myname();
 }
 
-/**************************************************************************
- Splits a name of format \DOMAIN\name or name into its two components.
- Sets the DOMAIN name to global_myname() if it has not been specified.
-***************************************************************************/
-
-void split_domain_name(const char *fullname, char *domain, char *name)
-{
-       pstring full_name;
-       const char *sep;
-       char *p;
-
-       sep = lp_winbind_separator();
-
-       *domain = *name = '\0';
-
-       if (fullname[0] == sep[0] || fullname[0] == '\\')
-               fullname++;
-
-       pstrcpy(full_name, fullname);
-       p = strchr_m(full_name+1, '\\');
-       if (!p) p = strchr_m(full_name+1, sep[0]);
-
-       if (p != NULL) {
-               *p = 0;
-               fstrcpy(domain, full_name);
-               fstrcpy(name, p+1);
-       } else {
-               fstrcpy(domain, get_global_sam_name());
-               fstrcpy(name, full_name);
-       }
-
-       DEBUG(10,("split_domain_name:name '%s' split into domain :'%s' and user :'%s'\n",
-                       fullname, domain, name));
-}
-
-/****************************************************************************
- Test if a SID is wellknown and resolvable.
-****************************************************************************/
-
-BOOL resolvable_wellknown_sid(DOM_SID *sid)
-{
-       uint32 ia = (sid->id_auth[5]) +
-                       (sid->id_auth[4] << 8 ) +
-                       (sid->id_auth[3] << 16) +
-                       (sid->id_auth[2] << 24);
-
-       if (sid->sid_rev_num != SEC_DESC_REVISION || sid->num_auths < 1)
-               return False;
-
-       return (ia == SECURITY_WORLD_SID_AUTHORITY ||
-               ia == SECURITY_CREATOR_SID_AUTHORITY);
-}
-
 /*****************************************************************
  Convert a SID to an ascii string.
 *****************************************************************/
@@ -256,63 +214,55 @@ const char *sid_string_static(const DOM_SID *sid)
    
 BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
 {
-       pstring tok;
-       char *q;
        const char *p;
+       char *q;
        /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
-       uint32 ia;
+       uint32 conv;
   
-       if (StrnCaseCmp( sidstr, "S-", 2)) {
-               DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
+       if ((sidstr[0] != 'S' && sidstr[0] != 's') || sidstr[1] != '-') {
+               DEBUG(3,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
                return False;
        }
 
-       memset((char *)sidout, '\0', sizeof(DOM_SID));
+       ZERO_STRUCTP(sidout);
 
-       p = q = SMB_STRDUP(sidstr + 2);
-       if (p == NULL) {
-               DEBUG(0, ("string_to_sid: out of memory!\n"));
-               return False;
-       }
-
-       if (!next_token(&p, tok, "-", sizeof(tok))) {
-               DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
-               SAFE_FREE(q);
+       /* Get the revision number. */
+       p = sidstr + 2;
+       conv = (uint32) strtoul(p, &q, 10);
+       if (!q || (*q != '-')) {
+               DEBUG(3,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
                return False;
        }
+       sidout->sid_rev_num = (uint8) conv;
+       q++;
 
-       /* Get the revision number. */
-       sidout->sid_rev_num = (uint8)strtoul(tok, NULL, 10);
-
-       if (!next_token(&p, tok, "-", sizeof(tok))) {
+       /* get identauth */
+       conv = (uint32) strtoul(q, &q, 10);
+       if (!q || (*q != '-')) {
                DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
-               SAFE_FREE(q);
                return False;
        }
-
        /* identauth in decimal should be <  2^32 */
-       ia = (uint32)strtoul(tok, NULL, 10);
-
-       /* NOTE - the ia value is in big-endian format. */
+       /* NOTE - the conv 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);
+       sidout->id_auth[2] = (conv & 0xff000000) >> 24;
+       sidout->id_auth[3] = (conv & 0x00ff0000) >> 16;
+       sidout->id_auth[4] = (conv & 0x0000ff00) >> 8;
+       sidout->id_auth[5] = (conv & 0x000000ff);
 
+       q++;
        sidout->num_auths = 0;
 
-       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.
-                */
-               sid_append_rid(sidout, (uint32)strtoul(tok, NULL, 10));
+       for(conv = (uint32) strtoul(q, &q, 10);
+           q && (*q =='-' || *q =='\0') && (sidout->num_auths < MAXSUBAUTHS);
+           conv = (uint32) strtoul(q, &q, 10)) {
+               sid_append_rid(sidout, conv);
+               if (*q == '\0')
+                       break;
+               q++;
        }
-
-       SAFE_FREE(q);
+               
        return True;
 }
 
@@ -539,30 +489,6 @@ BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
        return sid_compare(sid1, sid2) == 0;
 }
 
-/*****************************************************************
- Check if the SID is the builtin SID (S-1-5-32).
-*****************************************************************/  
-
-BOOL sid_check_is_builtin(const DOM_SID *sid)
-{
-       return sid_equal(sid, &global_sid_Builtin);
-}
-
-/*****************************************************************
- Check if the SID is one of the builtin SIDs (S-1-5-32-a).
-*****************************************************************/  
-
-BOOL sid_check_is_in_builtin(const DOM_SID *sid)
-{
-       DOM_SID dom_sid;
-       uint32 rid;
-
-       sid_copy(&dom_sid, sid);
-       sid_split_rid(&dom_sid, &rid);
-       
-       return sid_equal(&dom_sid, &global_sid_Builtin);
-}
-
 /*****************************************************************
  Calculates size of a sid.
 *****************************************************************/  
@@ -605,7 +531,25 @@ char *sid_binstring(const DOM_SID *sid)
 {
        char *buf, *s;
        int len = sid_size(sid);
-       buf = SMB_MALLOC(len);
+       buf = (char *)SMB_MALLOC(len);
+       if (!buf)
+               return NULL;
+       sid_linearize(buf, len, sid);
+       s = binary_string_rfc2254(buf, len);
+       free(buf);
+       return s;
+}
+
+/*****************************************************************
+ Return the binary string representation of a DOM_SID.
+ Caller must free.
+*****************************************************************/
+
+char *sid_binstring_hex(const DOM_SID *sid)
+{
+       char *buf, *s;
+       int len = sid_size(sid);
+       buf = (char *)SMB_MALLOC(len);
        if (!buf)
                return NULL;
        sid_linearize(buf, len, sid);
@@ -636,22 +580,20 @@ DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src)
  Add SID to an array SIDs
 ********************************************************************/
 
-void add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid, 
+BOOL add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid, 
                      DOM_SID **sids, size_t *num)
 {
-       if (mem_ctx != NULL)
-               *sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID,
+       *sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID,
                                             (*num)+1);
-       else
-               *sids = SMB_REALLOC_ARRAY(*sids, DOM_SID, (*num)+1);
-
-       if (*sids == NULL)
-               return;
+       if (*sids == NULL) {
+               *num = 0;
+               return False;
+       }
 
        sid_copy(&((*sids)[*num]), sid);
        *num += 1;
 
-       return;
+       return True;
 }
 
 
@@ -659,17 +601,17 @@ void add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
  Add SID to an array SIDs ensuring that it is not already there
 ********************************************************************/
 
-void add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+BOOL add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
                             DOM_SID **sids, size_t *num_sids)
 {
        size_t i;
 
        for (i=0; i<(*num_sids); i++) {
                if (sid_compare(sid, &(*sids)[i]) == 0)
-                       return;
+                       return True;
        }
 
-       add_sid_to_array(mem_ctx, sid, sids, num_sids);
+       return add_sid_to_array(mem_ctx, sid, sids, num_sids);
 }
 
 /********************************************************************
@@ -700,3 +642,31 @@ void del_sid_from_array(const DOM_SID *sid, DOM_SID **sids, size_t *num)
        
        return;
 }
+
+BOOL add_rid_to_array_unique(TALLOC_CTX *mem_ctx,
+                                   uint32 rid, uint32 **pp_rids, size_t *p_num)
+{
+       size_t i;
+
+       for (i=0; i<*p_num; i++) {
+               if ((*pp_rids)[i] == rid)
+                       return True;
+       }
+       
+       *pp_rids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_rids, uint32, *p_num+1);
+
+       if (*pp_rids == NULL) {
+               *p_num = 0;
+               return False;
+       }
+
+       (*pp_rids)[*p_num] = rid;
+       *p_num += 1;
+       return True;
+}
+
+BOOL is_null_sid(const DOM_SID *sid)
+{
+       static const DOM_SID null_sid = {0};
+       return sid_equal(sid, &null_sid);
+}