summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/librpc/idl/nbt.idl10
-rw-r--r--source3/nsswitch/libwbclient/wbc_pam.c12
-rw-r--r--source3/nsswitch/libwbclient/wbc_sid.c10
-rw-r--r--source3/nsswitch/libwbclient/wbc_util.c219
-rw-r--r--source3/nsswitch/libwbclient/wbclient.c4
-rw-r--r--source3/nsswitch/libwbclient/wbclient.h27
-rw-r--r--source3/nsswitch/wbinfo.c134
7 files changed, 306 insertions, 110 deletions
diff --git a/source3/librpc/idl/nbt.idl b/source3/librpc/idl/nbt.idl
index ca764d2a2b..e5efe1746d 100644
--- a/source3/librpc/idl/nbt.idl
+++ b/source3/librpc/idl/nbt.idl
@@ -440,9 +440,8 @@ interface nbt
nstring unicode_domain;
uint32 db_count;
nbt_db_change dbchange[db_count];
- [value(ndr_size_dom_sid(&sid, ndr->flags))] uint32 sid_size;
- [flag(NDR_ALIGN4)] DATA_BLOB _pad2;
- dom_sid sid;
+ [value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size;
+ [subcontext(0),subcontext_size(sid_size)] dom_sid0 sid;
uint32 nt_version;
uint16 lmnt_token;
uint16 lm20_token;
@@ -560,9 +559,8 @@ interface nbt
nstring user_name;
astring mailslot_name;
uint32 acct_control;
- [value(ndr_size_dom_sid(&sid, ndr->flags))] uint32 sid_size;
- [flag(NDR_ALIGN4)] DATA_BLOB _pad;
- dom_sid sid;
+ [value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size;
+ [subcontext(0),subcontext_size(sid_size)] dom_sid0 sid;
uint32 nt_version;
uint16 lmnt_token;
uint16 lm20_token;
diff --git a/source3/nsswitch/libwbclient/wbc_pam.c b/source3/nsswitch/libwbclient/wbc_pam.c
index f207f3ca0a..a0e91faaf3 100644
--- a/source3/nsswitch/libwbclient/wbc_pam.c
+++ b/source3/nsswitch/libwbclient/wbc_pam.c
@@ -138,7 +138,7 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
p = (char *)resp->extra_data.data;
if (!p) {
- wbc_status = WBC_INVALID_RESPONSE;
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
BAIL_ON_WBC_ERROR(wbc_status);
}
@@ -149,7 +149,7 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
char *s = p;
char *e = strchr(p, '\n');
if (!e) {
- wbc_status = WBC_INVALID_RESPONSE;
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
BAIL_ON_WBC_ERROR(wbc_status);
}
e[0] = '\0';
@@ -157,7 +157,7 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
ret = sscanf(s, "0x%08X:0x%08X", &rid, &attrs);
if (ret != 2) {
- wbc_status = WBC_INVALID_RESPONSE;
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
BAIL_ON_WBC_ERROR(wbc_status);
}
@@ -173,7 +173,7 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
char *a;
char *e = strchr(p, '\n');
if (!e) {
- wbc_status = WBC_INVALID_RESPONSE;
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
BAIL_ON_WBC_ERROR(wbc_status);
}
e[0] = '\0';
@@ -181,7 +181,7 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
e = strchr(s, ':');
if (!e) {
- wbc_status = WBC_INVALID_RESPONSE;
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
BAIL_ON_WBC_ERROR(wbc_status);
}
e[0] = '\0';
@@ -190,7 +190,7 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
ret = sscanf(a, "0x%08X",
&attrs);
if (ret != 1) {
- wbc_status = WBC_INVALID_RESPONSE;
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
BAIL_ON_WBC_ERROR(wbc_status);
}
diff --git a/source3/nsswitch/libwbclient/wbc_sid.c b/source3/nsswitch/libwbclient/wbc_sid.c
index 6ef9f44c3b..de9b02822f 100644
--- a/source3/nsswitch/libwbclient/wbc_sid.c
+++ b/source3/nsswitch/libwbclient/wbc_sid.c
@@ -372,21 +372,21 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
char *q;
if (*p == '\0') {
- wbc_status = WBC_INVALID_RESPONSE;
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
BAIL_ON_WBC_ERROR(wbc_status);
}
(*types)[i] = (enum wbcSidType)strtoul(p, &q, 10);
if (*q != ' ') {
- wbc_status = WBC_INVALID_RESPONSE;
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
BAIL_ON_WBC_ERROR(wbc_status);
}
p = q+1;
if ((q = strchr(p, '\n')) == NULL) {
- wbc_status = WBC_INVALID_RESPONSE;
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
BAIL_ON_WBC_ERROR(wbc_status);
}
@@ -399,7 +399,7 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
}
if (*p != '\0') {
- wbc_status = WBC_INVALID_RESPONSE;
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
BAIL_ON_WBC_ERROR(wbc_status);
}
@@ -471,7 +471,7 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
if (response.data.num_entries &&
!response.extra_data.data) {
- wbc_status = WBC_INVALID_RESPONSE;
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
BAIL_ON_WBC_ERROR(wbc_status);
}
diff --git a/source3/nsswitch/libwbclient/wbc_util.c b/source3/nsswitch/libwbclient/wbc_util.c
index edcad28221..d7af4d1bf2 100644
--- a/source3/nsswitch/libwbclient/wbc_util.c
+++ b/source3/nsswitch/libwbclient/wbc_util.c
@@ -3,7 +3,7 @@
Winbind client API
- Copyright (C) Gerald (Jerry) Carter 2007
+ Copyright (C) Gerald (Jerry) Carter 2007-2008
This library is free software; you can redistribute it and/or
@@ -170,11 +170,11 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
BAIL_ON_WBC_ERROR(wbc_status);
if (response.data.domain_info.native_mode)
- info->flags |= WBC_DOMINFO_NATIVE;
+ info->domain_flags |= WBC_DOMINFO_NATIVE;
if (response.data.domain_info.active_directory)
- info->flags |= WBC_DOMINFO_AD;
+ info->domain_flags |= WBC_DOMINFO_AD;
if (response.data.domain_info.primary)
- info->flags |= WBC_DOMINFO_PRIMARY;
+ info->domain_flags |= WBC_DOMINFO_PRIMARY;
*dinfo = info;
@@ -268,3 +268,214 @@ wbcErr wbcResolveWinsByIP(const char *ip, const char **name)
done:
return wbc_status;
}
+
+/**
+ */
+
+static wbcErr process_domain_info_string(TALLOC_CTX *ctx,
+ struct wbcDomainInfo *info,
+ char *info_string)
+{
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ char *r = NULL;
+ char *s = NULL;
+
+ if (!info || !info_string) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ r = info_string;
+
+ /* Short Name */
+ if ((s = strchr(r, '\\')) == NULL) {
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ *s = '\0';
+ s++;
+
+ info->short_name = talloc_strdup(ctx, r);
+ BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
+
+
+ /* DNS Name */
+ r = s;
+ if ((s = strchr(r, '\\')) == NULL) {
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ *s = '\0';
+ s++;
+
+ info->dns_name = talloc_strdup(ctx, r);
+ BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
+
+ /* SID */
+ r = s;
+ if ((s = strchr(r, '\\')) == NULL) {
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ *s = '\0';
+ s++;
+
+ wbc_status = wbcStringToSid(r, &info->sid);
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ /* Trust type */
+ r = s;
+ if ((s = strchr(r, '\\')) == NULL) {
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ *s = '\0';
+ s++;
+
+ if (strcmp(r, "None") == 0) {
+ info->trust_type = WBC_DOMINFO_TRUSTTYPE_NONE;
+ } else if (strcmp(r, "External") == 0) {
+ info->trust_type = WBC_DOMINFO_TRUSTTYPE_EXTERNAL;
+ } else if (strcmp(r, "Forest") == 0) {
+ info->trust_type = WBC_DOMINFO_TRUSTTYPE_FOREST;
+ } else if (strcmp(r, "In Forest") == 0) {
+ info->trust_type = WBC_DOMINFO_TRUSTTYPE_IN_FOREST;
+ } else {
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ /* Transitive */
+ r = s;
+ if ((s = strchr(r, '\\')) == NULL) {
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ *s = '\0';
+ s++;
+
+ if (strcmp(r, "Yes") == 0) {
+ info->trust_flags |= WBC_DOMINFO_TRUST_TRANSITIVE;
+ }
+
+ /* Incoming */
+ r = s;
+ if ((s = strchr(r, '\\')) == NULL) {
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ *s = '\0';
+ s++;
+
+ if (strcmp(r, "Yes") == 0) {
+ info->trust_flags |= WBC_DOMINFO_TRUST_INCOMING;
+ }
+
+ /* Outgoing */
+ r = s;
+ if (r == NULL) {
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (strcmp(r, "Yes") == 0) {
+ info->trust_flags |= WBC_DOMINFO_TRUST_OUTGOING;
+ }
+
+ wbc_status = WBC_ERR_SUCCESS;
+
+ done:
+ return wbc_status;
+}
+
+/** @brief Enumerate the domain trusts known by Winbind
+ *
+ * @param **domains Pointer to the allocated domain list array
+ * @param *num_domains Pointer to number of domains returned
+ *
+ * @return #wbcErr
+ *
+ **/
+wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains)
+{
+ struct winbindd_response response;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ char *p = NULL;
+ char *q = NULL;
+ char *extra_data = NULL;
+ int count = 0;
+ struct wbcDomainInfo *d_list = NULL;
+ int i = 0;
+
+ *domains = NULL;
+ *num_domains = 0;
+
+ ZERO_STRUCT(response);
+
+ /* Send request */
+
+ wbc_status = wbcRequestResponse(WINBINDD_LIST_TRUSTDOM,
+ NULL,
+ &response);
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ /* Decode the response */
+
+ p = (char *)response.extra_data.data;
+
+ if (strlen(p) == 0) {
+ /* We should always at least get back our
+ own SAM domain */
+
+ wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ /* Count number of domains */
+
+ count = 0;
+ while (p) {
+ count++;
+
+ if ((q = strchr(p, '\n')) != NULL)
+ q++;
+ p = q;
+ }
+
+ d_list = talloc_array(NULL, struct wbcDomainInfo, count);
+ BAIL_ON_PTR_ERROR(d_list, wbc_status);
+
+ extra_data = strdup((char*)response.extra_data.data);
+ BAIL_ON_PTR_ERROR(extra_data, wbc_status);
+
+ p = extra_data;
+
+ /* Outer loop processes the list of domain information */
+
+ for (i=0; i<count && p; i++) {
+ char *next = strchr(p, '\n');
+
+ if (next) {
+ *next = '\0';
+ next++;
+ }
+
+ wbc_status = process_domain_info_string(d_list, &d_list[i], p);
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ p = next;
+ }
+
+ *domains = d_list;
+ *num_domains = i;
+
+ done:
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ if (d_list)
+ talloc_free(d_list);
+ if (extra_data)
+ free(extra_data);
+ }
+
+ return wbc_status;
+}
diff --git a/source3/nsswitch/libwbclient/wbclient.c b/source3/nsswitch/libwbclient/wbclient.c
index b52c6b01e4..9383fd5406 100644
--- a/source3/nsswitch/libwbclient/wbclient.c
+++ b/source3/nsswitch/libwbclient/wbclient.c
@@ -106,8 +106,8 @@ const char *wbcErrorString(wbcErr error)
return "WBC_ERR_WINBIND_NOT_AVAILABLE";
case WBC_ERR_DOMAIN_NOT_FOUND:
return "WBC_ERR_DOMAIN_NOT_FOUND";
- case WBC_INVALID_RESPONSE:
- return "WBC_INVALID_RESPONSE";
+ case WBC_ERR_INVALID_RESPONSE:
+ return "WBC_ERR_INVALID_RESPONSE";
case WBC_ERR_NSS_ERROR:
return "WBC_ERR_NSS_ERROR";
case WBC_ERR_AUTH_ERROR:
diff --git a/source3/nsswitch/libwbclient/wbclient.h b/source3/nsswitch/libwbclient/wbclient.h
index b36b5bbe88..05cee9ab2b 100644
--- a/source3/nsswitch/libwbclient/wbclient.h
+++ b/source3/nsswitch/libwbclient/wbclient.h
@@ -40,7 +40,7 @@ enum _wbcErrType {
WBC_ERR_INVALID_PARAM, /**< An Invalid parameter was supplied **/
WBC_ERR_WINBIND_NOT_AVAILABLE, /**< Winbind daemon is not available **/
WBC_ERR_DOMAIN_NOT_FOUND, /**< Domain is not trusted or cannot be found **/
- WBC_INVALID_RESPONSE, /**< Winbind returned an invalid response **/
+ WBC_ERR_INVALID_RESPONSE, /**< Winbind returned an invalid response **/
WBC_ERR_NSS_ERROR, /**< NSS_STATUS error **/
WBC_ERR_AUTH_ERROR /**< Authentication failed **/
};
@@ -128,15 +128,32 @@ struct wbcDomainInfo {
char *short_name;
char *dns_name;
struct wbcDomainSid sid;
- uint32_t flags;
+ uint32_t domain_flags;
+ uint32_t trust_flags;
+ uint32_t trust_type;
};
-/* wbcDomainInfo->flags */
+/* wbcDomainInfo->domain_flags */
+#define WBC_DOMINFO_UNKNOWN 0x00000000
#define WBC_DOMINFO_NATIVE 0x00000001
#define WBC_DOMINFO_AD 0x00000002
#define WBC_DOMINFO_PRIMARY 0x00000004
+/* wbcDomainInfo->trust_flags */
+
+#define WBC_DOMINFO_TRUST_TRANSITIVE 0x00000001
+#define WBC_DOMINFO_TRUST_INCOMING 0x00000002
+#define WBC_DOMINFO_TRUST_OUTGOING 0x00000004
+
+/* wbcDomainInfo->trust_type */
+
+#define WBC_DOMINFO_TRUSTTYPE_NONE 0x00000000
+#define WBC_DOMINFO_TRUSTTYPE_FOREST 0x00000001
+#define WBC_DOMINFO_TRUSTTYPE_IN_FOREST 0x00000002
+#define WBC_DOMINFO_TRUSTTYPE_EXTERNAL 0x00000003
+
+
/**
* @brief Auth User Parameters
**/
@@ -390,6 +407,10 @@ wbcErr wbcGetGroups(const char *account,
wbcErr wbcDomainInfo(const char *domain,
struct wbcDomainInfo **info);
+wbcErr wbcListTrusts(struct wbcDomainInfo **domains,
+ size_t *num_domains);
+
+
/*
* Athenticate functions
*/
diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c
index 1e943a5eee..ed49be7431 100644
--- a/source3/nsswitch/wbinfo.c
+++ b/source3/nsswitch/wbinfo.c
@@ -341,101 +341,67 @@ static bool wbinfo_wins_byip(const char *ip)
static bool wbinfo_list_domains(bool list_all_domains, bool verbose)
{
- struct winbindd_request request;
- struct winbindd_response response;
-
+ struct wbcDomainInfo *domain_list = NULL;
+ size_t num_domains;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
bool print_all = !list_all_domains && verbose;
+ int i;
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Send request */
-
- request.data.list_all_domains = list_all_domains;
-
- if (winbindd_request_response(WINBINDD_LIST_TRUSTDOM, &request, &response) !=
- NSS_STATUS_SUCCESS)
+ wbc_status = wbcListTrusts(&domain_list, &num_domains);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
return false;
+ }
- /* Display response */
+ if (print_all) {
+ d_printf("%-16s%-24s%-12s%-12s%-5s%-5s\n",
+ "Domain Name", "DNS Domain", "Trust Type",
+ "Transitive", "In", "Out");
+ }
- if (response.extra_data.data) {
- const char *extra_data = (char *)response.extra_data.data;
- char *name;
- char *beg, *end;
- TALLOC_CTX *frame = talloc_stackframe();
+ for (i=0; i<num_domains; i++) {
+ d_printf("%-16s", domain_list[i].short_name);
- if (print_all) {
- d_printf("%-16s%-24s%-12s%-12s%-5s%-5s\n",
- "Domain Name", "DNS Domain", "Trust Type",
- "Transitive", "In", "Out");
+ if (!print_all) {
+ d_printf("\n");
+ continue;
}
- while(next_token_talloc(frame,&extra_data,&name,"\n")) {
- /* Print Domain Name */
- if ((beg = strchr(name, '\\')) == NULL)
- goto error;
- *beg = 0;
- beg++;
- if ((end = strchr(beg, '\\')) == NULL)
- goto error;
- *end = 0;
-
- /* Print short name */
+ d_printf("%-24s", domain_list[i].dns_name);
- d_printf("%-16s", name);
-
- if (!print_all) {
- d_printf("\n");
- continue;
- }
+ switch(domain_list[i].trust_type) {
+ case WBC_DOMINFO_TRUSTTYPE_NONE:
+ d_printf("None ");
+ break;
+ case WBC_DOMINFO_TRUSTTYPE_FOREST:
+ d_printf("Forest ");
+ break;
+ case WBC_DOMINFO_TRUSTTYPE_EXTERNAL:
+ d_printf("External ");
+ break;
+ case WBC_DOMINFO_TRUSTTYPE_IN_FOREST:
+ d_printf("In-Forest ");
+ break;
+ }
- /* Print DNS domain */
+ if (domain_list[i].trust_flags & WBC_DOMINFO_TRUST_TRANSITIVE) {
+ d_printf("Yes ");
+ } else {
+ d_printf("No ");
+ }
- if (beg) {
- d_printf("%-24s", beg);
- }
+ if (domain_list[i].trust_flags & WBC_DOMINFO_TRUST_INCOMING) {
+ d_printf("Yes ");
+ } else {
+ d_printf("No ");
+ }
- /* Skip SID */
- beg = ++end;
- if ((end = strchr(beg, '\\')) == NULL)
- goto error;
-
- /* Print Trust Type */
- beg = ++end;
- if ((end = strchr(beg, '\\')) == NULL)
- goto error;
- *end = 0;
- d_printf("%-12s", beg);
-
- /* Print Transitive */
- beg = ++end;
- if ((end = strchr(beg, '\\')) == NULL)
- goto error;
- *end = 0;
- d_printf("%-12s", beg);
-
- /* Print Incoming */
- beg = ++end;
- if ((end = strchr(beg, '\\')) == NULL)
- goto error;
- *end = 0;
- d_printf("%-5s", beg);
-
- /* Print Outgoing */
- beg = ++end;
- d_printf("%-5s\n", beg);
+ if (domain_list[i].trust_flags & WBC_DOMINFO_TRUST_OUTGOING) {
+ d_printf("Yes ");
+ } else {
+ d_printf("No ");
}
- goto out;
-error:
- d_fprintf(stderr, "Got invalid response: %s\n", extra_data);
- TALLOC_FREE(frame);
- SAFE_FREE(response.extra_data.data);
- return false;
-out:
- TALLOC_FREE(frame);
- SAFE_FREE(response.extra_data.data);
+ d_printf("\n");
}
return true;
@@ -519,12 +485,12 @@ static bool wbinfo_domain_info(const char *domain)
d_printf("SID : %s\n", sid_str);
d_printf("Active Directory : %s\n",
- (dinfo->flags & WBC_DOMINFO_AD) ? "Yes" : "No");
+ (dinfo->domain_flags & WBC_DOMINFO_AD) ? "Yes" : "No");
d_printf("Native : %s\n",
- (dinfo->flags & WBC_DOMINFO_NATIVE) ? "Yes" : "No");
+ (dinfo->domain_flags & WBC_DOMINFO_NATIVE) ? "Yes" : "No");
d_printf("Primary : %s\n",
- (dinfo->flags & WBC_DOMINFO_PRIMARY) ? "Yes" : "No");
+ (dinfo->domain_flags & WBC_DOMINFO_PRIMARY) ? "Yes" : "No");
wbcFreeMemory(sid_str);
wbcFreeMemory(dinfo);