From be9a69ac5d85a4bd09f7b87f5fe9d2282d5b91b9 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Mon, 14 Apr 2014 13:11:23 +0200 Subject: Extract common code from wbc_sid.c --- nsswitch/libwbclient/wbc_sid.c | 169 ----------------------------- nsswitch/libwbclient/wbc_sid_common.c | 196 ++++++++++++++++++++++++++++++++++ nsswitch/libwbclient/wscript | 1 + 3 files changed, 197 insertions(+), 169 deletions(-) create mode 100644 nsswitch/libwbclient/wbc_sid_common.c diff --git a/nsswitch/libwbclient/wbc_sid.c b/nsswitch/libwbclient/wbc_sid.c index 0877ed04aea..a5f67acb07f 100644 --- a/nsswitch/libwbclient/wbc_sid.c +++ b/nsswitch/libwbclient/wbc_sid.c @@ -27,158 +27,6 @@ #include "libwbclient.h" #include "../winbind_client.h" -/* Convert a sid to a string into a buffer. Return the string - * length. If buflen is too small, return the string length that would - * result if it was long enough. */ -int wbcSidToStringBuf(const struct wbcDomainSid *sid, char *buf, int buflen) -{ - uint64_t id_auth; - int i, ofs; - - if (!sid) { - strlcpy(buf, "(NULL SID)", buflen); - return 10; /* strlen("(NULL SID)") */ - } - - id_auth = (uint64_t)sid->id_auth[5] + - ((uint64_t)sid->id_auth[4] << 8) + - ((uint64_t)sid->id_auth[3] << 16) + - ((uint64_t)sid->id_auth[2] << 24) + - ((uint64_t)sid->id_auth[1] << 32) + - ((uint64_t)sid->id_auth[0] << 40); - - ofs = snprintf(buf, buflen, "S-%hhu-", (unsigned char)sid->sid_rev_num); - if (id_auth >= UINT32_MAX) { - ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "0x%llx", - (unsigned long long)id_auth); - } else { - ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "%llu", - (unsigned long long)id_auth); - } - - for (i = 0; i < sid->num_auths; i++) { - ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%u", - (unsigned int)sid->sub_auths[i]); - } - return ofs; -} - -/* Convert a binary SID to a character string */ -wbcErr wbcSidToString(const struct wbcDomainSid *sid, - char **sid_string) -{ - char buf[WBC_SID_STRING_BUFLEN]; - char *result; - int len; - - if (!sid) { - return WBC_ERR_INVALID_SID; - } - - len = wbcSidToStringBuf(sid, buf, sizeof(buf)); - - if (len+1 > sizeof(buf)) { - return WBC_ERR_INVALID_SID; - } - - result = (char *)wbcAllocateMemory(len+1, 1, NULL); - if (result == NULL) { - return WBC_ERR_NO_MEMORY; - } - memcpy(result, buf, len+1); - - *sid_string = result; - return WBC_ERR_SUCCESS; -} - -#define AUTHORITY_MASK (~(0xffffffffffffULL)) - -/* Convert a character string to a binary SID */ -wbcErr wbcStringToSid(const char *str, - struct wbcDomainSid *sid) -{ - const char *p; - char *q; - uint64_t x; - wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; - - if (!sid) { - wbc_status = WBC_ERR_INVALID_PARAM; - BAIL_ON_WBC_ERROR(wbc_status); - } - - /* Sanity check for either "S-" or "s-" */ - - if (!str - || (str[0]!='S' && str[0]!='s') - || (str[1]!='-')) - { - wbc_status = WBC_ERR_INVALID_PARAM; - BAIL_ON_WBC_ERROR(wbc_status); - } - - /* Get the SID revision number */ - - p = str+2; - x = (uint64_t)strtoul(p, &q, 10); - if (x==0 || x > UINT8_MAX || !q || *q!='-') { - wbc_status = WBC_ERR_INVALID_SID; - BAIL_ON_WBC_ERROR(wbc_status); - } - sid->sid_rev_num = (uint8_t)x; - - /* - * Next the Identifier Authority. This is stored big-endian in a - * 6 byte array. If the authority value is >= UINT_MAX, then it should - * be expressed as a hex value, according to MS-DTYP. - */ - p = q+1; - x = strtoull(p, &q, 0); - if (!q || *q!='-' || (x & AUTHORITY_MASK)) { - wbc_status = WBC_ERR_INVALID_SID; - BAIL_ON_WBC_ERROR(wbc_status); - } - sid->id_auth[5] = (x & 0x0000000000ffULL); - sid->id_auth[4] = (x & 0x00000000ff00ULL) >> 8; - sid->id_auth[3] = (x & 0x000000ff0000ULL) >> 16; - sid->id_auth[2] = (x & 0x0000ff000000ULL) >> 24; - sid->id_auth[1] = (x & 0x00ff00000000ULL) >> 32; - sid->id_auth[0] = (x & 0xff0000000000ULL) >> 40; - - /* now read the the subauthorities */ - p = q +1; - sid->num_auths = 0; - while (sid->num_auths < WBC_MAXSUBAUTHS) { - x = strtoull(p, &q, 10); - if (p == q) - break; - if (x > UINT32_MAX) { - wbc_status = WBC_ERR_INVALID_SID; - BAIL_ON_WBC_ERROR(wbc_status); - } - sid->sub_auths[sid->num_auths++] = x; - - if (*q != '-') { - break; - } - p = q + 1; - } - - /* IF we ended early, then the SID could not be converted */ - - if (q && *q!='\0') { - wbc_status = WBC_ERR_INVALID_SID; - BAIL_ON_WBC_ERROR(wbc_status); - } - - wbc_status = WBC_ERR_SUCCESS; - -done: - return wbc_status; - -} - - /* Convert a domain and name to SID */ wbcErr wbcLookupName(const char *domain, const char *name, @@ -982,20 +830,3 @@ wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid, return wbc_status; } - -const char* wbcSidTypeString(enum wbcSidType type) -{ - switch (type) { - case WBC_SID_NAME_USE_NONE: return "SID_NONE"; - case WBC_SID_NAME_USER: return "SID_USER"; - case WBC_SID_NAME_DOM_GRP: return "SID_DOM_GROUP"; - case WBC_SID_NAME_DOMAIN: return "SID_DOMAIN"; - case WBC_SID_NAME_ALIAS: return "SID_ALIAS"; - case WBC_SID_NAME_WKN_GRP: return "SID_WKN_GROUP"; - case WBC_SID_NAME_DELETED: return "SID_DELETED"; - case WBC_SID_NAME_INVALID: return "SID_INVALID"; - case WBC_SID_NAME_UNKNOWN: return "SID_UNKNOWN"; - case WBC_SID_NAME_COMPUTER: return "SID_COMPUTER"; - default: return "Unknown type"; - } -} diff --git a/nsswitch/libwbclient/wbc_sid_common.c b/nsswitch/libwbclient/wbc_sid_common.c new file mode 100644 index 00000000000..81841780b60 --- /dev/null +++ b/nsswitch/libwbclient/wbc_sid_common.c @@ -0,0 +1,196 @@ +/* + Unix SMB/CIFS implementation. + + Winbind client API + + Copyright (C) Gerald (Jerry) Carter 2007 + Copyright (C) Volker Lendecke 2010 + + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +/* Required Headers */ + +#include "replace.h" +#include "libwbclient.h" +#include "../winbind_client.h" + +/* Convert a sid to a string into a buffer. Return the string + * length. If buflen is too small, return the string length that would + * result if it was long enough. */ +int wbcSidToStringBuf(const struct wbcDomainSid *sid, char *buf, int buflen) +{ + uint64_t id_auth; + int i, ofs; + + if (!sid) { + strlcpy(buf, "(NULL SID)", buflen); + return 10; /* strlen("(NULL SID)") */ + } + + id_auth = (uint64_t)sid->id_auth[5] + + ((uint64_t)sid->id_auth[4] << 8) + + ((uint64_t)sid->id_auth[3] << 16) + + ((uint64_t)sid->id_auth[2] << 24) + + ((uint64_t)sid->id_auth[1] << 32) + + ((uint64_t)sid->id_auth[0] << 40); + + ofs = snprintf(buf, buflen, "S-%hhu-", (unsigned char)sid->sid_rev_num); + if (id_auth >= UINT32_MAX) { + ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "0x%llx", + (unsigned long long)id_auth); + } else { + ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "%llu", + (unsigned long long)id_auth); + } + + for (i = 0; i < sid->num_auths; i++) { + ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%u", + (unsigned int)sid->sub_auths[i]); + } + return ofs; +} + +/* Convert a binary SID to a character string */ +wbcErr wbcSidToString(const struct wbcDomainSid *sid, + char **sid_string) +{ + char buf[WBC_SID_STRING_BUFLEN]; + char *result; + int len; + + if (!sid) { + return WBC_ERR_INVALID_SID; + } + + len = wbcSidToStringBuf(sid, buf, sizeof(buf)); + + if (len+1 > sizeof(buf)) { + return WBC_ERR_INVALID_SID; + } + + result = (char *)wbcAllocateMemory(len+1, 1, NULL); + if (result == NULL) { + return WBC_ERR_NO_MEMORY; + } + memcpy(result, buf, len+1); + + *sid_string = result; + return WBC_ERR_SUCCESS; +} + +#define AUTHORITY_MASK (~(0xffffffffffffULL)) + +/* Convert a character string to a binary SID */ +wbcErr wbcStringToSid(const char *str, + struct wbcDomainSid *sid) +{ + const char *p; + char *q; + uint64_t x; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + + if (!sid) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + /* Sanity check for either "S-" or "s-" */ + + if (!str + || (str[0]!='S' && str[0]!='s') + || (str[1]!='-')) + { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + /* Get the SID revision number */ + + p = str+2; + x = (uint64_t)strtoul(p, &q, 10); + if (x==0 || x > UINT8_MAX || !q || *q!='-') { + wbc_status = WBC_ERR_INVALID_SID; + BAIL_ON_WBC_ERROR(wbc_status); + } + sid->sid_rev_num = (uint8_t)x; + + /* + * Next the Identifier Authority. This is stored big-endian in a + * 6 byte array. If the authority value is >= UINT_MAX, then it should + * be expressed as a hex value, according to MS-DTYP. + */ + p = q+1; + x = strtoull(p, &q, 0); + if (!q || *q!='-' || (x & AUTHORITY_MASK)) { + wbc_status = WBC_ERR_INVALID_SID; + BAIL_ON_WBC_ERROR(wbc_status); + } + sid->id_auth[5] = (x & 0x0000000000ffULL); + sid->id_auth[4] = (x & 0x00000000ff00ULL) >> 8; + sid->id_auth[3] = (x & 0x000000ff0000ULL) >> 16; + sid->id_auth[2] = (x & 0x0000ff000000ULL) >> 24; + sid->id_auth[1] = (x & 0x00ff00000000ULL) >> 32; + sid->id_auth[0] = (x & 0xff0000000000ULL) >> 40; + + /* now read the the subauthorities */ + p = q +1; + sid->num_auths = 0; + while (sid->num_auths < WBC_MAXSUBAUTHS) { + x = strtoull(p, &q, 10); + if (p == q) + break; + if (x > UINT32_MAX) { + wbc_status = WBC_ERR_INVALID_SID; + BAIL_ON_WBC_ERROR(wbc_status); + } + sid->sub_auths[sid->num_auths++] = x; + + if (*q != '-') { + break; + } + p = q + 1; + } + + /* IF we ended early, then the SID could not be converted */ + + if (q && *q!='\0') { + wbc_status = WBC_ERR_INVALID_SID; + BAIL_ON_WBC_ERROR(wbc_status); + } + + wbc_status = WBC_ERR_SUCCESS; + +done: + return wbc_status; + +} + +const char* wbcSidTypeString(enum wbcSidType type) +{ + switch (type) { + case WBC_SID_NAME_USE_NONE: return "SID_NONE"; + case WBC_SID_NAME_USER: return "SID_USER"; + case WBC_SID_NAME_DOM_GRP: return "SID_DOM_GROUP"; + case WBC_SID_NAME_DOMAIN: return "SID_DOMAIN"; + case WBC_SID_NAME_ALIAS: return "SID_ALIAS"; + case WBC_SID_NAME_WKN_GRP: return "SID_WKN_GROUP"; + case WBC_SID_NAME_DELETED: return "SID_DELETED"; + case WBC_SID_NAME_INVALID: return "SID_INVALID"; + case WBC_SID_NAME_UNKNOWN: return "SID_UNKNOWN"; + case WBC_SID_NAME_COMPUTER: return "SID_COMPUTER"; + default: return "Unknown type"; + } +} diff --git a/nsswitch/libwbclient/wscript b/nsswitch/libwbclient/wscript index da71a9c2f14..8f0109cd5d8 100644 --- a/nsswitch/libwbclient/wscript +++ b/nsswitch/libwbclient/wscript @@ -38,6 +38,7 @@ def build(bld): wbc_pam.c wbc_pwd.c wbc_sid.c + wbc_sid_common.c wbc_util.c''', deps='winbind-client', pc_files='wbclient.pc', -- cgit