1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

libcli/security Merge source3/ string_to_sid() to common code

The source3 code repsects the limit of a maximum of 15 subauths,
while the source4 code does not, creating a security issue as
we parse string-form SIDs from clients.

Andrew Bartlett
This commit is contained in:
Andrew Bartlett 2010-09-04 14:09:17 +10:00 committed by Jeremy Allison
parent 72a8ea4d15
commit 51ecf79654
2 changed files with 106 additions and 157 deletions

View File

@ -85,60 +85,115 @@ bool dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2)
return dom_sid_compare(sid1, sid2) == 0;
}
/* Yes, I did think about multibyte issues here, and for all I can see there's
* none of those for parsing a SID. */
#undef strncasecmp
/*****************************************************************
Add a rid to the end of a sid
*****************************************************************/
bool sid_append_rid(struct dom_sid *sid, uint32_t rid)
{
if (sid->num_auths < ARRAY_SIZE(sid->sub_auths)) {
sid->sub_auths[sid->num_auths++] = rid;
return true;
}
return false;
}
/*****************************************************************
Convert a string to a SID. Returns True on success, False on fail.
*****************************************************************/
bool string_to_sid(struct dom_sid *sidout, const char *sidstr)
{
const char *p;
char *q;
/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
uint32_t conv;
if ((sidstr[0] != 'S' && sidstr[0] != 's') || sidstr[1] != '-') {
goto format_error;
}
ZERO_STRUCTP(sidout);
/* Get the revision number. */
p = sidstr + 2;
if (!isdigit(*p)) {
goto format_error;
}
conv = (uint32_t) strtoul(p, &q, 10);
if (!q || (*q != '-')) {
goto format_error;
}
sidout->sid_rev_num = (uint8_t) conv;
q++;
if (!isdigit(*q)) {
goto format_error;
}
/* get identauth */
conv = (uint32_t) strtoul(q, &q, 10);
if (!q) {
goto format_error;
} else if (*q == '\0') {
/* Just id_auth, no subauths */
} else if (*q != '-') {
goto format_error;
}
/* identauth in decimal should be < 2^32 */
/* NOTE - the conv value is in big-endian format. */
sidout->id_auth[0] = 0;
sidout->id_auth[1] = 0;
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);
sidout->num_auths = 0;
if (*q == '\0') {
return true;
}
q++;
while (true) {
char *end;
if (!isdigit(*q)) {
goto format_error;
}
conv = strtoul(q, &end, 10);
if (end == q) {
goto format_error;
}
if (!sid_append_rid(sidout, conv)) {
DEBUG(3, ("Too many sid auths in %s\n", sidstr));
return false;
}
q = end;
if (*q == '\0') {
break;
}
if (*q != '-') {
goto format_error;
}
q += 1;
}
return true;
format_error:
DEBUG(3, ("string_to_sid: SID %s is not in a valid format\n", sidstr));
return false;
}
bool dom_sid_parse(const char *sidstr, struct dom_sid *ret)
{
unsigned int rev, ia, num_sub_auths, i;
char *p;
if (strncasecmp(sidstr, "S-", 2)) {
return false;
}
sidstr += 2;
rev = strtol(sidstr, &p, 10);
if (*p != '-') {
return false;
}
sidstr = p+1;
ia = strtol(sidstr, &p, 10);
if (p == sidstr) {
return false;
}
sidstr = p;
num_sub_auths = 0;
for (i=0;sidstr[i];i++) {
if (sidstr[i] == '-') num_sub_auths++;
}
ret->sid_rev_num = rev;
ret->id_auth[0] = 0;
ret->id_auth[1] = 0;
ret->id_auth[2] = ia >> 24;
ret->id_auth[3] = ia >> 16;
ret->id_auth[4] = ia >> 8;
ret->id_auth[5] = ia;
ret->num_auths = num_sub_auths;
for (i=0;i<num_sub_auths;i++) {
if (sidstr[0] != '-') {
return false;
}
sidstr++;
ret->sub_auths[i] = strtoul(sidstr, &p, 10);
if (p == sidstr) {
return false;
}
sidstr = p;
}
return true;
return string_to_sid(ret, sidstr);
}
/*

View File

@ -194,112 +194,6 @@ char *sid_string_tos(const struct dom_sid *sid)
return sid_string_talloc(talloc_tos(), sid);
}
/*****************************************************************
Convert a string to a SID. Returns True on success, False on fail.
*****************************************************************/
bool string_to_sid(struct dom_sid *sidout, const char *sidstr)
{
const char *p;
char *q;
/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
uint32_t conv;
if ((sidstr[0] != 'S' && sidstr[0] != 's') || sidstr[1] != '-') {
goto format_error;
}
ZERO_STRUCTP(sidout);
/* Get the revision number. */
p = sidstr + 2;
if (!isdigit(*p)) {
goto format_error;
}
conv = (uint32_t) strtoul(p, &q, 10);
if (!q || (*q != '-')) {
goto format_error;
}
sidout->sid_rev_num = (uint8_t) conv;
q++;
if (!isdigit(*q)) {
goto format_error;
}
/* get identauth */
conv = (uint32_t) strtoul(q, &q, 10);
if (!q) {
goto format_error;
} else if (*q == '\0') {
/* Just id_auth, no subauths */
} else if (*q != '-') {
goto format_error;
}
/* identauth in decimal should be < 2^32 */
/* NOTE - the conv value is in big-endian format. */
sidout->id_auth[0] = 0;
sidout->id_auth[1] = 0;
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);
sidout->num_auths = 0;
if (*q == '\0') {
return true;
}
q++;
while (true) {
char *end;
if (!isdigit(*q)) {
goto format_error;
}
conv = strtoul(q, &end, 10);
if (end == q) {
goto format_error;
}
if (!sid_append_rid(sidout, conv)) {
DEBUG(3, ("Too many sid auths in %s\n", sidstr));
return false;
}
q = end;
if (*q == '\0') {
break;
}
if (*q != '-') {
goto format_error;
}
q += 1;
}
return true;
format_error:
DEBUG(3, ("string_to_sid: SID %s is not in a valid format\n", sidstr));
return false;
}
/*****************************************************************
Add a rid to the end of a sid
*****************************************************************/
bool sid_append_rid(struct dom_sid *sid, uint32_t rid)
{
if (sid->num_auths < ARRAY_SIZE(sid->sub_auths)) {
sid->sub_auths[sid->num_auths++] = rid;
return true;
}
return false;
}
bool sid_compose(struct dom_sid *dst, const struct dom_sid *domain_sid, uint32 rid)
{
sid_copy(dst, domain_sid);