summaryrefslogtreecommitdiffstats
path: root/source4/libcli/wbclient/wbclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli/wbclient/wbclient.c')
-rw-r--r--source4/libcli/wbclient/wbclient.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/source4/libcli/wbclient/wbclient.c b/source4/libcli/wbclient/wbclient.c
new file mode 100644
index 0000000..69d8b43
--- /dev/null
+++ b/source4/libcli/wbclient/wbclient.c
@@ -0,0 +1,193 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client library.
+
+ Copyright (C) 2008 Kai Blin <kai@samba.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include <tevent.h>
+#include "nsswitch/winbind_client.h"
+#include "libcli/wbclient/wbclient.h"
+#include "libcli/security/dom_sid.h"
+#include "nsswitch/libwbclient/wbclient.h"
+
+NTSTATUS wbc_sids_to_xids(struct id_map *ids, uint32_t count)
+{
+ TALLOC_CTX *mem_ctx;
+ uint32_t i;
+ struct wbcDomainSid *sids;
+ struct wbcUnixId *xids;
+ wbcErr result;
+ bool wb_off;
+
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ sids = talloc_array(mem_ctx, struct wbcDomainSid, count);
+ if (sids == NULL) {
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ xids = talloc_array(mem_ctx, struct wbcUnixId, count);
+ if (xids == NULL) {
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<count; i++) {
+ memcpy(&sids[i], ids[i].sid, sizeof(struct dom_sid));
+ }
+
+ wb_off = winbind_env_set();
+ if (wb_off) {
+ (void)winbind_on();
+ }
+
+ result = wbcSidsToUnixIds(sids, count, xids);
+
+ if (wb_off) {
+ (void)winbind_off();
+ }
+
+ if (!WBC_ERROR_IS_OK(result)) {
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ for (i=0; i<count; i++) {
+ struct wbcUnixId *xid = &xids[i];
+ struct unixid *id = &ids[i].xid;
+
+ switch (xid->type) {
+ case WBC_ID_TYPE_UID:
+ id->type = ID_TYPE_UID;
+ id->id = xid->id.uid;
+ break;
+ case WBC_ID_TYPE_GID:
+ id->type = ID_TYPE_GID;
+ id->id = xid->id.gid;
+ break;
+ case WBC_ID_TYPE_BOTH:
+ id->type = ID_TYPE_BOTH;
+ id->id = xid->id.uid;
+ break;
+ case WBC_ID_TYPE_NOT_SPECIFIED:
+ id->type = ID_TYPE_NOT_SPECIFIED;
+ id->id = UINT32_MAX;
+ break;
+ }
+ ids[i].status = ID_MAPPED;
+ }
+
+ TALLOC_FREE(mem_ctx);
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS wbc_xids_to_sids(struct id_map *ids, uint32_t count)
+{
+ TALLOC_CTX *mem_ctx;
+ uint32_t i;
+ struct wbcDomainSid *sids;
+ struct wbcUnixId *xids;
+ wbcErr result;
+ bool wb_off;
+
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ sids = talloc_array(mem_ctx, struct wbcDomainSid, count);
+ if (sids == NULL) {
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ xids = talloc_array(mem_ctx, struct wbcUnixId, count);
+ if (xids == NULL) {
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<count; i++) {
+ struct id_map *id = &ids[i];
+ struct wbcUnixId *xid = &xids[i];
+
+ switch (id->xid.type) {
+ case ID_TYPE_UID:
+ *xid = (struct wbcUnixId) {
+ .type = WBC_ID_TYPE_UID,
+ .id.uid = id->xid.id
+ };
+ break;
+ case ID_TYPE_GID:
+ *xid = (struct wbcUnixId) {
+ .type = WBC_ID_TYPE_GID,
+ .id.uid = id->xid.id
+ };
+ break;
+ default:
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_NOT_FOUND;
+ }
+ }
+
+ wb_off = winbind_env_set();
+ if (wb_off) {
+ (void)winbind_on();
+ }
+
+ result = wbcUnixIdsToSids(xids, count, sids);
+
+ if (wb_off) {
+ (void)winbind_off();
+ }
+
+ if (!WBC_ERROR_IS_OK(result)) {
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ for (i=0; i<count; i++) {
+ struct wbcDomainSid *sid = &sids[i];
+ struct wbcDomainSid null_sid = { 0 };
+ struct id_map *id = &ids[i];
+
+ if (memcmp(sid, &null_sid, sizeof(*sid)) != 0) {
+ struct dom_sid domsid;
+ id->status = ID_MAPPED;
+
+ memcpy(&domsid, sid, sizeof(struct dom_sid));
+ id->sid = dom_sid_dup(ids, &domsid);
+ if (id->sid == NULL) {
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ } else {
+ id->status = ID_UNMAPPED;
+ id->sid = NULL;
+ }
+ }
+
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_OK;
+}