885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/*
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose Unix SMB/CIFS implementation.
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose Winbind client API
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose Copyright (C) Gerald (Jerry) Carter 2007
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose Copyright (C) Volker Lendecke 2010
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose This library is free software; you can redistribute it and/or
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose modify it under the terms of the GNU Lesser General Public
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose License as published by the Free Software Foundation; either
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose version 3 of the License, or (at your option) any later version.
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose This library is distributed in the hope that it will be useful,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose Library General Public License for more details.
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose You should have received a copy of the GNU Lesser General Public License
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose*/
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Required Headers */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose#include <stdio.h>
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose#include "libwbclient.h"
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose#define MAX(a, b) (((a) > (b)) ? (a) : (b))
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Convert a sid to a string into a buffer. Return the string
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose * length. If buflen is too small, return the string length that would
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose * result if it was long enough. */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Boseint wbcSidToStringBuf(const struct wbcDomainSid *sid, char *buf, int buflen)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose uint64_t id_auth;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose int i, ofs;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (!sid) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose strncpy(buf, "(NULL SID)", buflen);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buf[buflen < 10 ? buflen :10] = '\0';
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return 10; /* strlen("(NULL SID)") */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose id_auth = (uint64_t)sid->id_auth[5] +
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ((uint64_t)sid->id_auth[4] << 8) +
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ((uint64_t)sid->id_auth[3] << 16) +
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ((uint64_t)sid->id_auth[2] << 24) +
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ((uint64_t)sid->id_auth[1] << 32) +
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ((uint64_t)sid->id_auth[0] << 40);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ofs = snprintf(buf, buflen, "S-%hhu-", (unsigned char)sid->sid_rev_num);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (id_auth >= UINT32_MAX) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "0x%llx",
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose (unsigned long long)id_auth);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose } else {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "%llu",
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose (unsigned long long)id_auth);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose for (i = 0; i < sid->num_auths; i++) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%u",
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose (unsigned int)sid->sub_auths[i]);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return ofs;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Convert a binary SID to a character string */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcSidToString(const struct wbcDomainSid *sid,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char **sid_string)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char buf[WBC_SID_STRING_BUFLEN];
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *result;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose int len;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (!sid) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_INVALID_SID;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose len = wbcSidToStringBuf(sid, buf, sizeof(buf));
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (len+1 > sizeof(buf)) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_INVALID_SID;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose result = (char *)wbcAllocateMemory(len+1, 1, NULL);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (result == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NO_MEMORY;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose memcpy(result, buf, len+1);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose *sid_string = result;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_SUCCESS;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose#define AUTHORITY_MASK (~(0xffffffffffffULL))
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Convert a character string to a binary SID */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcStringToSid(const char *str,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose struct wbcDomainSid *sid)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose const char *p;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *q;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose uint64_t x;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (!sid) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = WBC_ERR_INVALID_PARAM;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose BAIL_ON_WBC_ERROR(wbc_status);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose /* Sanity check for either "S-" or "s-" */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (!str
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose || (str[0]!='S' && str[0]!='s')
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose || (str[1]!='-'))
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = WBC_ERR_INVALID_PARAM;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose BAIL_ON_WBC_ERROR(wbc_status);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose /* Get the SID revision number */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose p = str+2;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose x = (uint64_t)strtoul(p, &q, 10);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (x==0 || x > UINT8_MAX || !q || *q!='-') {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = WBC_ERR_INVALID_SID;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose BAIL_ON_WBC_ERROR(wbc_status);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose sid->sid_rev_num = (uint8_t)x;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose /*
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose * Next the Identifier Authority. This is stored big-endian in a
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose * 6 byte array. If the authority value is >= UINT_MAX, then it should
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose * be expressed as a hex value, according to MS-DTYP.
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose p = q+1;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose x = strtoull(p, &q, 0);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (!q || *q!='-' || (x & AUTHORITY_MASK)) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = WBC_ERR_INVALID_SID;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose BAIL_ON_WBC_ERROR(wbc_status);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose sid->id_auth[5] = (x & 0x0000000000ffULL);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose sid->id_auth[4] = (x & 0x00000000ff00ULL) >> 8;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose sid->id_auth[3] = (x & 0x000000ff0000ULL) >> 16;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose sid->id_auth[2] = (x & 0x0000ff000000ULL) >> 24;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose sid->id_auth[1] = (x & 0x00ff00000000ULL) >> 32;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose sid->id_auth[0] = (x & 0xff0000000000ULL) >> 40;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
f91029dd8d7dbc026a5c73e222926db957240cb4Yuri Chornoivan /* now read the subauthorities */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose p = q +1;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose sid->num_auths = 0;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose while (sid->num_auths < WBC_MAXSUBAUTHS) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose x = strtoull(p, &q, 10);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (p == q)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose break;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (x > UINT32_MAX) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = WBC_ERR_INVALID_SID;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose BAIL_ON_WBC_ERROR(wbc_status);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose sid->sub_auths[sid->num_auths++] = x;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (*q != '-') {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose break;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose p = q + 1;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose /* IF we ended early, then the SID could not be converted */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (q && *q!='\0') {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = WBC_ERR_INVALID_SID;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose BAIL_ON_WBC_ERROR(wbc_status);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = WBC_ERR_SUCCESS;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bosedone:
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Boseconst char* wbcSidTypeString(enum wbcSidType type)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose switch (type) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose case WBC_SID_NAME_USE_NONE: return "SID_NONE";
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose case WBC_SID_NAME_USER: return "SID_USER";
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose case WBC_SID_NAME_DOM_GRP: return "SID_DOM_GROUP";
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose case WBC_SID_NAME_DOMAIN: return "SID_DOMAIN";
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose case WBC_SID_NAME_ALIAS: return "SID_ALIAS";
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose case WBC_SID_NAME_WKN_GRP: return "SID_WKN_GROUP";
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose case WBC_SID_NAME_DELETED: return "SID_DELETED";
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose case WBC_SID_NAME_INVALID: return "SID_INVALID";
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose case WBC_SID_NAME_UNKNOWN: return "SID_UNKNOWN";
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose case WBC_SID_NAME_COMPUTER: return "SID_COMPUTER";
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose default: return "Unknown type";
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}