Convert a SID to an ascii string.
*****************************************************************/
-char *sid_to_string(fstring sidstr_out, const DOM_SID *sid)
+char *sid_to_fstring(fstring sidstr_out, const DOM_SID *sid)
{
- char subauth[16];
- int i;
- uint32 ia;
-
- if (!sid) {
- fstrcpy(sidstr_out, "(NULL SID)");
- return sidstr_out;
- }
-
- /*
- * BIG NOTE: this function only does SIDS where the identauth is not >= 2^32
- * in a range of 2^48.
- */
- ia = (sid->id_auth[5]) +
- (sid->id_auth[4] << 8 ) +
- (sid->id_auth[3] << 16) +
- (sid->id_auth[2] << 24);
-
- slprintf(sidstr_out, sizeof(fstring) - 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, "-%lu", (unsigned long)sid->sub_auths[i]);
- fstrcat(sidstr_out, subauth);
- }
-
+ char *str = sid_string_talloc(talloc_tos(), sid);
+ fstrcpy(sidstr_out, str);
+ TALLOC_FREE(str);
return sidstr_out;
}
/*****************************************************************
- Useful function for debug lines.
-*****************************************************************/
+ Essentially a renamed dom_sid_string from librpc/ndr with a
+ panic if it didn't work
-const char *sid_string_static(const DOM_SID *sid)
-{
- static fstring sid_str;
- sid_to_string(sid_str, sid);
- return sid_str;
-}
+ This introduces a dependency on librpc/ndr/sid.o which can easily
+ be turned around if necessary
+*****************************************************************/
char *sid_string_talloc(TALLOC_CTX *mem_ctx, const DOM_SID *sid)
{
- fstring sid_str;
- char *result;
- sid_to_string(sid_str, sid);
- result = talloc_strdup(mem_ctx, sid_str);
+ char *result = dom_sid_string(mem_ctx, sid);
SMB_ASSERT(result != NULL);
return result;
}
+/*****************************************************************
+ Useful function for debug lines.
+*****************************************************************/
+
char *sid_string_dbg(const DOM_SID *sid)
{
return sid_string_talloc(debug_ctx(), sid);
}
+/*****************************************************************
+ Use with care!
+*****************************************************************/
+
char *sid_string_tos(const DOM_SID *sid)
{
return sid_string_talloc(talloc_tos(), sid);
{
size_t i;
- if (len < sid_size(sid))
+ if (len < ndr_size_dom_sid(sid, NULL, 0))
return False;
SCVAL(outbuf,0,sid->sid_rev_num);
sid->sid_rev_num = CVAL(inbuf, 0);
sid->num_auths = CVAL(inbuf, 1);
+ if (sid->num_auths > MAXSUBAUTHS) {
+ return false;
+ }
memcpy(sid->id_auth, inbuf+2, 6);
if (len < 8 + sid->num_auths*4)
return False;
return sid_compare_auth(sid1, sid2);
}
+int sid_compare_sort(const void *p1, const void *p2)
+{
+ const struct dom_sid *sid1 = (const struct dom_sid *)p1;
+ const struct dom_sid *sid2 = (const struct dom_sid *)p2;
+ int i, res;
+
+ if (sid1->sid_rev_num != sid2->sid_rev_num) {
+ return sid1->sid_rev_num - sid2->sid_rev_num;
+ }
+
+ for (i = 0; i < 6; i++) {
+ if (sid1->id_auth[i] != sid2->id_auth[i]) {
+ return sid1->id_auth[i] - sid2->id_auth[i];
+ }
+ }
+
+ if (sid1->num_auths != sid2->num_auths) {
+ return sid1->num_auths - sid2->num_auths;
+ }
+
+ for (i = 0; i<sid1->num_auths; i++) {
+ if (sid1->sub_auths[i] != sid2->sub_auths[i]) {
+ return sid1->sub_auths[i] - sid2->sub_auths[i];
+ }
+ }
+
+ return 0;
+}
+
/*****************************************************************
See if 2 SIDs are in the same domain
this just compares the leading sub-auths
return sid_compare(sid1, sid2) == 0;
}
-/*****************************************************************
- Calculates size of a sid.
-*****************************************************************/
-
-size_t sid_size(const DOM_SID *sid)
-{
- if (sid == NULL)
- return 0;
-
- return sid->num_auths * sizeof(uint32) + 8;
-}
-
/*****************************************************************
Returns true if SID is internal (and non-mappable).
*****************************************************************/
char *sid_binstring(const DOM_SID *sid)
{
char *buf, *s;
- int len = sid_size(sid);
+ int len = ndr_size_dom_sid(sid, NULL, 0);
buf = (char *)SMB_MALLOC(len);
if (!buf)
return NULL;
char *sid_binstring_hex(const DOM_SID *sid)
{
char *buf, *s;
- int len = sid_size(sid);
+ int len = ndr_size_dom_sid(sid, NULL, 0);
buf = (char *)SMB_MALLOC(len);
if (!buf)
return NULL;
Add SID to an array SIDs
********************************************************************/
-bool add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
- DOM_SID **sids, size_t *num)
+NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+ DOM_SID **sids, size_t *num)
{
*sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID,
(*num)+1);
if (*sids == NULL) {
*num = 0;
- return False;
+ return NT_STATUS_NO_MEMORY;
}
sid_copy(&((*sids)[*num]), sid);
*num += 1;
- return True;
+ return NT_STATUS_OK;
}
Add SID to an array SIDs ensuring that it is not already there
********************************************************************/
-bool add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
- DOM_SID **sids, size_t *num_sids)
+NTSTATUS 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 True;
+ return NT_STATUS_OK;
}
return add_sid_to_array(mem_ctx, sid, sids, num_sids);
return sid_equal(sid, &null_sid);
}
+bool is_sid_in_token(const NT_USER_TOKEN *token, const DOM_SID *sid)
+{
+ int i;
+
+ for (i=0; i<token->num_sids; i++) {
+ if (sid_compare(sid, &token->user_sids[i]) == 0)
+ return true;
+ }
+ return false;
+}
+
NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx,
- const NET_USER_INFO_3 *info3,
+ const struct netr_SamInfo3 *info3,
DOM_SID **user_sids,
size_t *num_user_sids,
- bool include_user_group_rid)
+ bool include_user_group_rid,
+ bool skip_ressource_groups)
{
+ NTSTATUS status;
DOM_SID sid;
DOM_SID *sid_array = NULL;
size_t num_sids = 0;
int i;
if (include_user_group_rid) {
-
- if (!sid_compose(&sid, &(info3->dom_sid.sid),
- info3->user_rid)
- || !add_sid_to_array(mem_ctx, &sid,
- &sid_array, &num_sids)) {
- DEBUG(3,("could not add user SID from rid 0x%x\n",
- info3->user_rid));
+ if (!sid_compose(&sid, info3->base.domain_sid, info3->base.rid)) {
+ DEBUG(3, ("could not compose user SID from rid 0x%x\n",
+ info3->base.rid));
return NT_STATUS_INVALID_PARAMETER;
}
-
- if (!sid_compose(&sid, &(info3->dom_sid.sid),
- info3->group_rid)
- || !add_sid_to_array(mem_ctx, &sid,
- &sid_array, &num_sids)) {
- DEBUG(3,("could not append additional group rid 0x%x\n",
- info3->group_rid));
-
- return NT_STATUS_INVALID_PARAMETER;
+ status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("could not append user SID from rid 0x%x\n",
+ info3->base.rid));
+ return status;
}
}
- for (i = 0; i < info3->num_groups2; i++) {
- if (!sid_compose(&sid, &(info3->dom_sid.sid),
- info3->gids[i].g_rid)
- || !add_sid_to_array(mem_ctx, &sid,
- &sid_array, &num_sids)) {
- DEBUG(3,("could not append additional group rid 0x%x\n",
- info3->gids[i].g_rid));
+ if (!sid_compose(&sid, info3->base.domain_sid, info3->base.primary_gid)) {
+ DEBUG(3, ("could not compose group SID from rid 0x%x\n",
+ info3->base.primary_gid));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("could not append group SID from rid 0x%x\n",
+ info3->base.rid));
+ return status;
+ }
+
+ for (i = 0; i < info3->base.groups.count; i++) {
+ /* Don't add the primary group sid twice. */
+ if (info3->base.primary_gid == info3->base.groups.rids[i].rid) {
+ continue;
+ }
+ if (!sid_compose(&sid, info3->base.domain_sid,
+ info3->base.groups.rids[i].rid)) {
+ DEBUG(3, ("could not compose SID from additional group "
+ "rid 0x%x\n", info3->base.groups.rids[i].rid));
return NT_STATUS_INVALID_PARAMETER;
}
+ status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("could not append SID from additional group "
+ "rid 0x%x\n", info3->base.groups.rids[i].rid));
+ return status;
+ }
}
/* Copy 'other' sids. We need to do sid filtering here to
http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
*/
- for (i = 0; i < info3->num_other_sids; i++) {
- if (!add_sid_to_array(mem_ctx, &info3->other_sids[i].sid,
- &sid_array, &num_sids)) {
+ for (i = 0; i < info3->sidcount; i++) {
+
+ if (skip_ressource_groups &&
+ (info3->sids[i].attributes & SE_GROUP_RESOURCE)) {
+ continue;
+ }
+
+ status = add_sid_to_array(mem_ctx, info3->sids[i].sid,
+ &sid_array, &num_sids);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("could not add SID to array: %s\n",
- sid_string_dbg(&info3->other_sids[i].sid)));
- return NT_STATUS_NO_MEMORY;
+ sid_string_dbg(info3->sids[i].sid)));
+ return status;
}
}