summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2011-03-03 16:59:39 +0100
committerVolker Lendecke <vl@samba.org>2011-03-03 22:08:49 +0100
commit70517477f8deafc8027388d0597bbd53bd407c58 (patch)
tree6b44a7565da0d4937464e4804cc90434c4ef94fe
parentf8a13c7dbc9b0e2246fb52d4a4d5db3b23bd2340 (diff)
downloadsamba-70517477f8deafc8027388d0597bbd53bd407c58.tar.gz
samba-70517477f8deafc8027388d0597bbd53bd407c58.tar.xz
samba-70517477f8deafc8027388d0597bbd53bd407c58.zip
Add dom_sid_string_buf
This prints into a fixed buffer with the same overflow semantics as snprintf has: Return required string length, regardless of whether it fit or not.
-rw-r--r--libcli/security/dom_sid.c49
-rw-r--r--libcli/security/dom_sid.h3
2 files changed, 40 insertions, 12 deletions
diff --git a/libcli/security/dom_sid.c b/libcli/security/dom_sid.c
index 217d7bb8d4f..809f20ce263 100644
--- a/libcli/security/dom_sid.c
+++ b/libcli/security/dom_sid.c
@@ -347,34 +347,59 @@ bool dom_sid_in_domain(const struct dom_sid *domain_sid,
}
/*
- convert a dom_sid to a string
+ Convert a dom_sid to a string, printing into a buffer. Return the
+ string length. If it overflows, return the string length that would
+ result (buflen needs to be +1 for the terminating 0).
*/
-char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
+int dom_sid_string_buf(const struct dom_sid *sid, char *buf, int buflen)
{
- int i, ofs, maxlen;
+ int i, ofs;
uint32_t ia;
- char *ret;
if (!sid) {
- return talloc_strdup(mem_ctx, "(NULL SID)");
+ strlcpy(buf, "(NULL SID)", buflen);
+ return 10; /* strlen("(NULL SID)") */
}
- maxlen = sid->num_auths * 11 + 25;
- ret = talloc_array(mem_ctx, char, maxlen);
- if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)");
-
ia = (sid->id_auth[5]) +
(sid->id_auth[4] << 8 ) +
(sid->id_auth[3] << 16) +
(sid->id_auth[2] << 24);
- ofs = snprintf(ret, maxlen, "S-%u-%lu",
+ ofs = snprintf(buf, buflen, "S-%u-%lu",
(unsigned int)sid->sid_rev_num, (unsigned long)ia);
for (i = 0; i < sid->num_auths; i++) {
- ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu",
+ ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%lu",
(unsigned long)sid->sub_auths[i]);
}
+ return ofs;
+}
- return ret;
+/*
+ convert a dom_sid to a string
+*/
+char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
+{
+ char buf[DOM_SID_STR_BUFLEN];
+ char *result;
+ int len;
+
+ len = dom_sid_string_buf(sid, buf, sizeof(buf));
+
+ if (len+1 > sizeof(buf)) {
+ return talloc_strdup(mem_ctx, "(SID ERR)");
+ }
+
+ /*
+ * Avoid calling strlen (via talloc_strdup), we already have
+ * the length
+ */
+ result = (char *)talloc_memdup(mem_ctx, buf, len+1);
+
+ /*
+ * beautify the talloc_report output
+ */
+ talloc_set_name_const(result, result);
+ return result;
}
diff --git a/libcli/security/dom_sid.h b/libcli/security/dom_sid.h
index c65471bf90f..3493fab8386 100644
--- a/libcli/security/dom_sid.h
+++ b/libcli/security/dom_sid.h
@@ -71,6 +71,9 @@ NTSTATUS dom_sid_split_rid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
struct dom_sid **domain, uint32_t *rid);
bool dom_sid_in_domain(const struct dom_sid *domain_sid,
const struct dom_sid *sid);
+
+#define DOM_SID_STR_BUFLEN (15*11+25)
+int dom_sid_string_buf(const struct dom_sid *sid, char *buf, int buflen);
char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid);