Changeset 745 for trunk/server/libcli/security/dom_sid.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/libcli/security/dom_sid.c
r583 r745 29 29 *****************************************************************/ 30 30 31 staticint dom_sid_compare_auth(const struct dom_sid *sid1,32 31 int dom_sid_compare_auth(const struct dom_sid *sid1, 32 const struct dom_sid *sid2) 33 33 { 34 34 int i; … … 86 86 } 87 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 88 /***************************************************************** 89 Add a rid to the end of a sid 90 *****************************************************************/ 91 92 bool sid_append_rid(struct dom_sid *sid, uint32_t rid) 93 { 94 if (sid->num_auths < ARRAY_SIZE(sid->sub_auths)) { 95 sid->sub_auths[sid->num_auths++] = rid; 96 return true; 97 } 98 return false; 99 } 100 101 /* 102 See if 2 SIDs are in the same domain 103 this just compares the leading sub-auths 104 */ 105 int dom_sid_compare_domain(const struct dom_sid *sid1, 106 const struct dom_sid *sid2) 107 { 108 int n, i; 109 110 n = MIN(sid1->num_auths, sid2->num_auths); 111 112 for (i = n-1; i >= 0; --i) 113 if (sid1->sub_auths[i] != sid2->sub_auths[i]) 114 return sid1->sub_auths[i] - sid2->sub_auths[i]; 115 116 return dom_sid_compare_auth(sid1, sid2); 117 } 118 119 /***************************************************************** 120 Convert a string to a SID. Returns True on success, False on fail. 121 Return the first character not parsed in endp. 122 *****************************************************************/ 123 124 bool dom_sid_parse_endp(const char *sidstr,struct dom_sid *sidout, 125 const char **endp) 126 { 127 const char *p; 128 char *q; 129 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */ 130 uint32_t conv; 131 132 ZERO_STRUCTP(sidout); 133 134 if ((sidstr[0] != 'S' && sidstr[0] != 's') || sidstr[1] != '-') { 135 goto format_error; 136 } 137 138 /* Get the revision number. */ 139 p = sidstr + 2; 140 141 if (!isdigit(*p)) { 142 goto format_error; 143 } 144 145 conv = (uint32_t) strtoul(p, &q, 10); 146 if (!q || (*q != '-')) { 147 goto format_error; 148 } 149 sidout->sid_rev_num = (uint8_t) conv; 150 q++; 151 152 if (!isdigit(*q)) { 153 goto format_error; 154 } 155 156 /* get identauth */ 157 conv = (uint32_t) strtoul(q, &q, 10); 158 if (!q) { 159 goto format_error; 160 } 161 162 /* identauth in decimal should be < 2^32 */ 163 /* NOTE - the conv value is in big-endian format. */ 164 sidout->id_auth[0] = 0; 165 sidout->id_auth[1] = 0; 166 sidout->id_auth[2] = (conv & 0xff000000) >> 24; 167 sidout->id_auth[3] = (conv & 0x00ff0000) >> 16; 168 sidout->id_auth[4] = (conv & 0x0000ff00) >> 8; 169 sidout->id_auth[5] = (conv & 0x000000ff); 170 171 sidout->num_auths = 0; 172 if (*q != '-') { 173 /* Just id_auth, no subauths */ 174 return true; 175 } 176 177 q++; 178 179 while (true) { 180 char *end; 181 182 if (!isdigit(*q)) { 183 goto format_error; 184 } 185 186 conv = strtoul(q, &end, 10); 187 if (end == q) { 188 goto format_error; 189 } 190 191 if (!sid_append_rid(sidout, conv)) { 192 DEBUG(3, ("Too many sid auths in %s\n", sidstr)); 193 return false; 194 } 195 196 q = end; 197 if (*q != '-') { 198 break; 199 } 200 q += 1; 201 } 202 if (endp != NULL) { 203 *endp = q; 204 } 205 return true; 206 207 format_error: 208 DEBUG(3, ("string_to_sid: SID %s is not in a valid format\n", sidstr)); 209 return false; 210 } 211 212 bool string_to_sid(struct dom_sid *sidout, const char *sidstr) 213 { 214 return dom_sid_parse(sidstr, sidout); 215 } 91 216 92 217 bool dom_sid_parse(const char *sidstr, struct dom_sid *ret) 93 218 { 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 if (num_sub_auths > MAXSUBAUTHS) { 121 return false; 122 } 123 124 ret->sid_rev_num = rev; 125 ret->id_auth[0] = 0; 126 ret->id_auth[1] = 0; 127 ret->id_auth[2] = ia >> 24; 128 ret->id_auth[3] = ia >> 16; 129 ret->id_auth[4] = ia >> 8; 130 ret->id_auth[5] = ia; 131 ret->num_auths = num_sub_auths; 132 133 for (i=0;i<num_sub_auths;i++) { 134 if (sidstr[0] != '-') { 135 return false; 136 } 137 sidstr++; 138 ret->sub_auths[i] = strtoul(sidstr, &p, 10); 139 if (p == sidstr) { 140 return false; 141 } 142 sidstr = p; 143 } 144 145 return true; 219 return dom_sid_parse_endp(sidstr, ret, NULL); 146 220 } 147 221 … … 222 296 struct dom_sid *sid; 223 297 224 sid = talloc(mem_ctx, struct dom_sid);298 sid = dom_sid_dup(mem_ctx, domain_sid); 225 299 if (!sid) return NULL; 226 300 227 *sid = *domain_sid;228 229 sid->sub_auths[sid->num_auths] = rid;230 sid->num_auths++;301 if (!sid_append_rid(sid, rid)) { 302 talloc_free(sid); 303 return NULL; 304 } 231 305 232 306 return sid; … … 284 358 285 359 /* 286 convert a dom_sid to a string 287 */ 288 char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) 289 { 290 int i, ofs, maxlen; 360 Convert a dom_sid to a string, printing into a buffer. Return the 361 string length. If it overflows, return the string length that would 362 result (buflen needs to be +1 for the terminating 0). 363 */ 364 int dom_sid_string_buf(const struct dom_sid *sid, char *buf, int buflen) 365 { 366 int i, ofs; 291 367 uint32_t ia; 292 char *ret;293 368 294 369 if (!sid) { 295 return talloc_strdup(mem_ctx, "(NULL SID)"); 296 } 297 298 maxlen = sid->num_auths * 11 + 25; 299 ret = talloc_array(mem_ctx, char, maxlen); 300 if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)"); 370 strlcpy(buf, "(NULL SID)", buflen); 371 return 10; /* strlen("(NULL SID)") */ 372 } 301 373 302 374 ia = (sid->id_auth[5]) + … … 305 377 (sid->id_auth[2] << 24); 306 378 307 ofs = snprintf( ret, maxlen, "S-%u-%lu",379 ofs = snprintf(buf, buflen, "S-%u-%lu", 308 380 (unsigned int)sid->sid_rev_num, (unsigned long)ia); 309 381 310 382 for (i = 0; i < sid->num_auths; i++) { 311 ofs += snprintf( ret + ofs, maxlen - ofs, "-%lu",383 ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%lu", 312 384 (unsigned long)sid->sub_auths[i]); 313 385 } 314 315 return ret; 316 } 386 return ofs; 387 } 388 389 /* 390 convert a dom_sid to a string 391 */ 392 char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) 393 { 394 char buf[DOM_SID_STR_BUFLEN]; 395 char *result; 396 int len; 397 398 len = dom_sid_string_buf(sid, buf, sizeof(buf)); 399 400 if (len+1 > sizeof(buf)) { 401 return talloc_strdup(mem_ctx, "(SID ERR)"); 402 } 403 404 /* 405 * Avoid calling strlen (via talloc_strdup), we already have 406 * the length 407 */ 408 result = (char *)talloc_memdup(mem_ctx, buf, len+1); 409 410 /* 411 * beautify the talloc_report output 412 */ 413 talloc_set_name_const(result, result); 414 return result; 415 }
Note:
See TracChangeset
for help on using the changeset viewer.