root/libcli/security/dom_sid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dom_sid_compare_auth
  2. dom_sid_compare
  3. dom_sid_equal
  4. dom_sid_parse
  5. dom_sid_parse_talloc
  6. dom_sid_parse_length
  7. dom_sid_dup
  8. dom_sid_add_rid
  9. dom_sid_split_rid
  10. dom_sid_in_domain
  11. dom_sid_string

   1 /*
   2    Unix SMB/CIFS implementation.
   3    Samba utility functions
   4 
   5    Copyright (C) Stefan (metze) Metzmacher      2002-2004
   6    Copyright (C) Andrew Tridgell                1992-2004
   7    Copyright (C) Jeremy Allison                 1999
   8 
   9    This program is free software; you can redistribute it and/or modify
  10    it under the terms of the GNU General Public License as published by
  11    the Free Software Foundation; either version 3 of the License, or
  12    (at your option) any later version.
  13 
  14    This program is distributed in the hope that it will be useful,
  15    but WITHOUT ANY WARRANTY; without even the implied warranty of
  16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17    GNU General Public License for more details.
  18 
  19    You should have received a copy of the GNU General Public License
  20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  21 */
  22 
  23 #include "includes.h"
  24 #include "librpc/gen_ndr/security.h"
  25 #include "dom_sid.h"
  26 
  27 /*****************************************************************
  28  Compare the auth portion of two sids.
  29 *****************************************************************/
  30 
  31 static int dom_sid_compare_auth(const struct dom_sid *sid1,
     /* [<][>][^][v][top][bottom][index][help] */
  32                                 const struct dom_sid *sid2)
  33 {
  34         int i;
  35 
  36         if (sid1 == sid2)
  37                 return 0;
  38         if (!sid1)
  39                 return -1;
  40         if (!sid2)
  41                 return 1;
  42 
  43         if (sid1->sid_rev_num != sid2->sid_rev_num)
  44                 return sid1->sid_rev_num - sid2->sid_rev_num;
  45 
  46         for (i = 0; i < 6; i++)
  47                 if (sid1->id_auth[i] != sid2->id_auth[i])
  48                         return sid1->id_auth[i] - sid2->id_auth[i];
  49 
  50         return 0;
  51 }
  52 
  53 /*****************************************************************
  54  Compare two sids.
  55 *****************************************************************/
  56 
  57 int dom_sid_compare(const struct dom_sid *sid1, const struct dom_sid *sid2)
     /* [<][>][^][v][top][bottom][index][help] */
  58 {
  59         int i;
  60 
  61         if (sid1 == sid2)
  62                 return 0;
  63         if (!sid1)
  64                 return -1;
  65         if (!sid2)
  66                 return 1;
  67 
  68         /* Compare most likely different rids, first: i.e start at end */
  69         if (sid1->num_auths != sid2->num_auths)
  70                 return sid1->num_auths - sid2->num_auths;
  71 
  72         for (i = sid1->num_auths-1; i >= 0; --i)
  73                 if (sid1->sub_auths[i] != sid2->sub_auths[i])
  74                         return sid1->sub_auths[i] - sid2->sub_auths[i];
  75 
  76         return dom_sid_compare_auth(sid1, sid2);
  77 }
  78 
  79 /*****************************************************************
  80  Compare two sids.
  81 *****************************************************************/
  82 
  83 bool dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2)
     /* [<][>][^][v][top][bottom][index][help] */
  84 {
  85         return dom_sid_compare(sid1, sid2) == 0;
  86 }
  87 
  88 /* Yes, I did think about multibyte issues here, and for all I can see there's
  89  * none of those for parsing a SID. */
  90 #undef strncasecmp
  91 
  92 bool dom_sid_parse(const char *sidstr, struct dom_sid *ret)
     /* [<][>][^][v][top][bottom][index][help] */
  93 {
  94         uint_t rev, ia, num_sub_auths, i;
  95         char *p;
  96 
  97         if (strncasecmp(sidstr, "S-", 2)) {
  98                 return false;
  99         }
 100 
 101         sidstr += 2;
 102 
 103         rev = strtol(sidstr, &p, 10);
 104         if (*p != '-') {
 105                 return false;
 106         }
 107         sidstr = p+1;
 108 
 109         ia = strtol(sidstr, &p, 10);
 110         if (p == sidstr) {
 111                 return false;
 112         }
 113         sidstr = p;
 114 
 115         num_sub_auths = 0;
 116         for (i=0;sidstr[i];i++) {
 117                 if (sidstr[i] == '-') num_sub_auths++;
 118         }
 119 
 120         ret->sid_rev_num = rev;
 121         ret->id_auth[0] = 0;
 122         ret->id_auth[1] = 0;
 123         ret->id_auth[2] = ia >> 24;
 124         ret->id_auth[3] = ia >> 16;
 125         ret->id_auth[4] = ia >> 8;
 126         ret->id_auth[5] = ia;
 127         ret->num_auths = num_sub_auths;
 128 
 129         for (i=0;i<num_sub_auths;i++) {
 130                 if (sidstr[0] != '-') {
 131                         return false;
 132                 }
 133                 sidstr++;
 134                 ret->sub_auths[i] = strtoul(sidstr, &p, 10);
 135                 if (p == sidstr) {
 136                         return false;
 137                 }
 138                 sidstr = p;
 139         }
 140 
 141         return true;
 142 }
 143 
 144 /*
 145   convert a string to a dom_sid, returning a talloc'd dom_sid
 146 */
 147 struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
     /* [<][>][^][v][top][bottom][index][help] */
 148 {
 149         struct dom_sid *ret;
 150         ret = talloc(mem_ctx, struct dom_sid);
 151         if (!ret) {
 152                 return NULL;
 153         }
 154         if (!dom_sid_parse(sidstr, ret)) {
 155                 talloc_free(ret);
 156                 return NULL;
 157         }
 158 
 159         return ret;
 160 }
 161 
 162 /*
 163   convert a string to a dom_sid, returning a talloc'd dom_sid
 164 */
 165 struct dom_sid *dom_sid_parse_length(TALLOC_CTX *mem_ctx, const DATA_BLOB *sid)
     /* [<][>][^][v][top][bottom][index][help] */
 166 {
 167         struct dom_sid *ret;
 168         char *p = talloc_strndup(mem_ctx, (char *)sid->data, sid->length);
 169         if (!p) {
 170                 return NULL;
 171         }
 172         ret = dom_sid_parse_talloc(mem_ctx, p);
 173         talloc_free(p);
 174         return ret;
 175 }
 176 
 177 /*
 178   copy a dom_sid structure
 179 */
 180 struct dom_sid *dom_sid_dup(TALLOC_CTX *mem_ctx, const struct dom_sid *dom_sid)
     /* [<][>][^][v][top][bottom][index][help] */
 181 {
 182         struct dom_sid *ret;
 183         int i;
 184 
 185         if (!dom_sid) {
 186                 return NULL;
 187         }
 188 
 189         ret = talloc(mem_ctx, struct dom_sid);
 190         if (!ret) {
 191                 return NULL;
 192         }
 193 
 194         ret->sid_rev_num = dom_sid->sid_rev_num;
 195         ret->id_auth[0] = dom_sid->id_auth[0];
 196         ret->id_auth[1] = dom_sid->id_auth[1];
 197         ret->id_auth[2] = dom_sid->id_auth[2];
 198         ret->id_auth[3] = dom_sid->id_auth[3];
 199         ret->id_auth[4] = dom_sid->id_auth[4];
 200         ret->id_auth[5] = dom_sid->id_auth[5];
 201         ret->num_auths = dom_sid->num_auths;
 202 
 203         for (i=0;i<dom_sid->num_auths;i++) {
 204                 ret->sub_auths[i] = dom_sid->sub_auths[i];
 205         }
 206 
 207         return ret;
 208 }
 209 
 210 /*
 211   add a rid to a domain dom_sid to make a full dom_sid. This function
 212   returns a new sid in the supplied memory context
 213 */
 214 struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 215                                 const struct dom_sid *domain_sid,
 216                                 uint32_t rid)
 217 {
 218         struct dom_sid *sid;
 219 
 220         sid = talloc(mem_ctx, struct dom_sid);
 221         if (!sid) return NULL;
 222 
 223         *sid = *domain_sid;
 224 
 225         sid->sub_auths[sid->num_auths] = rid;
 226         sid->num_auths++;
 227 
 228         return sid;
 229 }
 230 
 231 /*
 232   Split up a SID into its domain and RID part
 233 */
 234 NTSTATUS dom_sid_split_rid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
     /* [<][>][^][v][top][bottom][index][help] */
 235                            struct dom_sid **domain, uint32_t *rid)
 236 {
 237         if (sid->num_auths == 0) {
 238                 return NT_STATUS_INVALID_PARAMETER;
 239         }
 240 
 241         if (domain) {
 242                 if (!(*domain = dom_sid_dup(mem_ctx, sid))) {
 243                         return NT_STATUS_NO_MEMORY;
 244                 }
 245 
 246                 (*domain)->num_auths -= 1;
 247         }
 248 
 249         if (rid) {
 250                 *rid = sid->sub_auths[sid->num_auths - 1];
 251         }
 252 
 253         return NT_STATUS_OK;
 254 }
 255 
 256 /*
 257   return true if the 2nd sid is in the domain given by the first sid
 258 */
 259 bool dom_sid_in_domain(const struct dom_sid *domain_sid,
     /* [<][>][^][v][top][bottom][index][help] */
 260                        const struct dom_sid *sid)
 261 {
 262         int i;
 263 
 264         if (!domain_sid || !sid) {
 265                 return false;
 266         }
 267 
 268         if (domain_sid->num_auths > sid->num_auths) {
 269                 return false;
 270         }
 271 
 272         for (i = domain_sid->num_auths-1; i >= 0; --i) {
 273                 if (domain_sid->sub_auths[i] != sid->sub_auths[i]) {
 274                         return false;
 275                 }
 276         }
 277 
 278         return dom_sid_compare_auth(domain_sid, sid) == 0;
 279 }
 280 
 281 /*
 282   convert a dom_sid to a string
 283 */
 284 char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
     /* [<][>][^][v][top][bottom][index][help] */
 285 {
 286         int i, ofs, maxlen;
 287         uint32_t ia;
 288         char *ret;
 289 
 290         if (!sid) {
 291                 return talloc_strdup(mem_ctx, "(NULL SID)");
 292         }
 293 
 294         maxlen = sid->num_auths * 11 + 25;
 295         ret = talloc_array(mem_ctx, char, maxlen);
 296         if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)");
 297 
 298         ia = (sid->id_auth[5]) +
 299                 (sid->id_auth[4] << 8 ) +
 300                 (sid->id_auth[3] << 16) +
 301                 (sid->id_auth[2] << 24);
 302 
 303         ofs = snprintf(ret, maxlen, "S-%u-%lu",
 304                        (unsigned int)sid->sid_rev_num, (unsigned long)ia);
 305 
 306         for (i = 0; i < sid->num_auths; i++) {
 307                 ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu",
 308                                 (unsigned long)sid->sub_auths[i]);
 309         }
 310 
 311         return ret;
 312 }

/* [<][>][^][v][top][bottom][index][help] */