1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

s3: Implement wbcGetSidAliases

* Adds wbcGetSidAliases that calls the lookup_useraliases function.
* Updates wbinfo and winbind_util.c to call the new function.
* Also added winbind_get_groups helper function.
This commit is contained in:
Dan Sledz 2009-02-10 13:59:10 -08:00 committed by Steven Danneman
parent aed8e9aa0a
commit 3b8a57e064
11 changed files with 440 additions and 88 deletions

View File

@ -491,6 +491,145 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
return wbc_status;
}
static inline
wbcErr _sid_to_rid(struct wbcDomainSid *sid, uint32_t *rid)
{
if (sid->num_auths < 1) {
return WBC_ERR_INVALID_RESPONSE;
}
*rid = sid->sub_auths[sid->num_auths - 1];
return WBC_ERR_SUCCESS;
}
/* Get alias membership for sids */
wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid,
struct wbcDomainSid *sids,
uint32_t num_sids,
uint32_t **alias_rids,
uint32_t *num_alias_rids)
{
uint32_t i;
const char *s;
struct winbindd_request request;
struct winbindd_response response;
char *sid_string = NULL;
ssize_t sid_len;
ssize_t extra_data_len = 0;
char * extra_data = NULL;
ssize_t buflen = 0;
struct wbcDomainSid sid;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
uint32_t * rids = NULL;
/* Initialise request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
if (!dom_sid) {
wbc_status = WBC_ERR_INVALID_PARAM;
BAIL_ON_WBC_ERROR(wbc_status);
}
wbc_status = wbcSidToString(dom_sid, &sid_string);
BAIL_ON_WBC_ERROR(wbc_status);
strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
wbcFreeMemory(sid_string);
sid_string = NULL;
/* Lets assume each sid is around 54 characters
* S-1-5-AAAAAAAAAAA-BBBBBBBBBBB-CCCCCCCCCCC-DDDDDDDDDDD\n */
buflen = 54 * num_sids;
extra_data = talloc_array(NULL, char, buflen);
if (!extra_data) {
wbc_status = WBC_ERR_NO_MEMORY;
BAIL_ON_WBC_ERROR(wbc_status);
}
/* Build the sid list */
for (i=0; i<num_sids; i++) {
if (sid_string) {
wbcFreeMemory(sid_string);
sid_string = NULL;
}
wbc_status = wbcSidToString(&sids[i], &sid_string);
BAIL_ON_WBC_ERROR(wbc_status);
sid_len = strlen(sid_string);
if (buflen < extra_data_len + sid_len + 2) {
buflen *= 2;
extra_data = talloc_realloc(NULL, extra_data,
char, buflen);
if (!extra_data) {
wbc_status = WBC_ERR_NO_MEMORY;
BAIL_ON_WBC_ERROR(wbc_status);
}
}
strncpy(&extra_data[extra_data_len], sid_string,
buflen - extra_data_len);
extra_data_len += sid_len;
extra_data[extra_data_len++] = '\n';
extra_data[extra_data_len] = '\0';
}
request.extra_data.data = extra_data;
request.extra_len = extra_data_len;
wbc_status = wbcRequestResponse(WINBINDD_GETSIDALIASES,
&request,
&response);
BAIL_ON_WBC_ERROR(wbc_status);
if (response.data.num_entries &&
!response.extra_data.data) {
wbc_status = WBC_ERR_INVALID_RESPONSE;
BAIL_ON_WBC_ERROR(wbc_status);
}
rids = talloc_array(NULL, uint32_t,
response.data.num_entries);
BAIL_ON_PTR_ERROR(sids, wbc_status);
s = (const char *)response.extra_data.data;
for (i = 0; i < response.data.num_entries; i++) {
char *n = strchr(s, '\n');
if (n) {
*n = '\0';
}
wbc_status = wbcStringToSid(s, &sid);
BAIL_ON_WBC_ERROR(wbc_status);
wbc_status = _sid_to_rid(&sid, &rids[i]);
BAIL_ON_WBC_ERROR(wbc_status);
s += strlen(s) + 1;
}
*num_alias_rids = response.data.num_entries;
*alias_rids = rids;
rids = NULL;
wbc_status = WBC_ERR_SUCCESS;
done:
if (sid_string) {
wbcFreeMemory(sid_string);
}
if (extra_data) {
talloc_free(extra_data);
}
if (response.extra_data.data) {
free(response.extra_data.data);
}
if (rids) {
talloc_free(rids);
}
return wbc_status;
}
/* Lists Users */
wbcErr wbcListUsers(const char *domain_name,
uint32_t *_num_users,

View File

@ -61,6 +61,7 @@ const char *wbcErrorString(wbcErr error);
* 0.2: Added wbcRemoveUidMapping()
* Added wbcRemoveGidMapping()
* 0.3: Added wbcGetpwsid()
* Added wbcGetSidAliases()
**/
#define WBCLIENT_MAJOR_VERSION 0
#define WBCLIENT_MINOR_VERSION 3
@ -616,6 +617,15 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
uint32_t *num_sids,
struct wbcDomainSid **sids);
/*
* @brief Get alias membership for sids
**/
wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid,
struct wbcDomainSid *sids,
uint32_t num_sids,
uint32_t **alias_rids,
uint32_t *num_alias_rids);
/**
* @brief Lists Users
**/

View File

@ -366,6 +366,64 @@ static bool wbinfo_get_userdomgroups(const char *user_sid_str)
return true;
}
static bool wbinfo_get_sidaliases(const char *domain,
const char *user_sid_str)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct wbcDomainInfo *dinfo = NULL;
uint32_t i;
struct wbcDomainSid user_sid;
uint32_t *alias_rids = NULL;
uint32_t num_alias_rids;
char *domain_sid_str = NULL;
/* Send request */
if ((domain == NULL) || (strequal(domain, ".")) ||
(domain[0] == '\0')) {
domain = get_winbind_domain();
}
/* Send request */
wbc_status = wbcDomainInfo(domain, &dinfo);
if (!WBC_ERROR_IS_OK(wbc_status)) {
d_printf("wbcDomainInfo(%s) failed: %s\n", domain,
wbcErrorString(wbc_status));
goto done;
}
wbc_status = wbcStringToSid(user_sid_str, &user_sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
goto done;
}
wbc_status = wbcGetSidAliases(&dinfo->sid, &user_sid, 1,
&alias_rids, &num_alias_rids);
if (!WBC_ERROR_IS_OK(wbc_status)) {
goto done;
}
wbc_status = wbcSidToString(&dinfo->sid, &domain_sid_str);
if (!WBC_ERROR_IS_OK(wbc_status)) {
goto done;
}
for (i = 0; i < num_alias_rids; i++) {
d_printf("%s-%d\n", domain_sid_str, alias_rids[i]);
}
wbcFreeMemory(alias_rids);
done:
if (domain_sid_str) {
wbcFreeMemory(domain_sid_str);
}
if (dinfo) {
wbcFreeMemory(dinfo);
}
return (WBC_ERR_SUCCESS == wbc_status);
}
/* Convert NetBIOS name to IP */
static bool wbinfo_wins_byname(const char *name)
@ -1578,6 +1636,7 @@ enum {
OPT_GETDCNAME,
OPT_DSGETDCNAME,
OPT_USERDOMGROUPS,
OPT_SIDALIASES,
OPT_USERSIDS,
OPT_ALLOCATE_UID,
OPT_ALLOCATE_GID,
@ -1653,6 +1712,7 @@ int main(int argc, char **argv, char **envp)
{ "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" },
{ "user-domgroups", 0, POPT_ARG_STRING, &string_arg,
OPT_USERDOMGROUPS, "Get user domain groups", "SID" },
{ "sid-aliases", 0, POPT_ARG_STRING, &string_arg, OPT_SIDALIASES, "Get sid aliases", "SID" },
{ "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" },
{ "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" },
{ "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
@ -1936,6 +1996,13 @@ int main(int argc, char **argv, char **envp)
goto done;
}
break;
case OPT_SIDALIASES:
if (!wbinfo_get_sidaliases(opt_domain_name, string_arg)) {
d_fprintf(stderr, "Could not get sid aliases "
"for user SID %s\n", string_arg);
goto done;
}
break;
case 'a': {
bool got_error = false;

View File

@ -143,6 +143,9 @@ enum winbindd_cmd {
/* Various group queries */
WINBINDD_GETUSERDOMGROUPS,
/* lookup local groups */
WINBINDD_GETSIDALIASES,
/* Initialize connection in a child */
WINBINDD_INIT_CONNECTION,

View File

@ -1670,6 +1670,17 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
const char ***names, enum lsa_SidType **types);
bool winbind_allocate_uid(uid_t *uid);
bool winbind_allocate_gid(gid_t *gid);
bool winbind_get_groups(TALLOC_CTX *mem_ctx,
const char *account,
uint32_t *num_groups,
gid_t ** _groups);
bool winbind_get_sid_aliases(TALLOC_CTX *mem_ctx,
const DOM_SID *dom_sid,
const DOM_SID *members,
size_t num_members,
uint32_t **pp_alias_rids,
size_t *p_num_alias_rids);
/* The following definitions come from lib/wins_srv.c */

View File

@ -271,6 +271,75 @@ bool winbind_allocate_gid(gid_t *gid)
return (ret == WBC_ERR_SUCCESS);
}
bool winbind_get_groups(TALLOC_CTX * mem_ctx, const char *account, uint32_t *num_groups, gid_t **_groups)
{
wbcErr ret;
uint32_t ngroups;
gid_t *group_list = NULL;
ret = wbcGetGroups(account, &ngroups, &group_list);
if (ret != WBC_ERR_SUCCESS)
return false;
*_groups = TALLOC_ARRAY(mem_ctx, gid_t, ngroups);
if (*_groups == NULL) {
wbcFreeMemory(group_list);
return false;
}
memcpy(*_groups, group_list, ngroups* sizeof(gid_t));
*num_groups = ngroups;
wbcFreeMemory(group_list);
return true;
}
bool winbind_get_sid_aliases(TALLOC_CTX *mem_ctx,
const DOM_SID *dom_sid,
const DOM_SID *members,
size_t num_members,
uint32_t **pp_alias_rids,
size_t *p_num_alias_rids)
{
wbcErr ret;
struct wbcDomainSid domain_sid;
struct wbcDomainSid *sid_list = NULL;
size_t i;
uint32_t * rids;
size_t num_rids;
memcpy(&domain_sid, dom_sid, sizeof(*dom_sid));
sid_list = TALLOC_ARRAY(mem_ctx, struct wbcDomainSid, num_members);
for (i=0; i < num_members; i++) {
memcpy(&sid_list[i], &members[i], sizeof(sid_list[i]));
}
ret = wbcGetSidAliases(&domain_sid,
sid_list,
num_members,
&rids,
&num_rids);
if (ret != WBC_ERR_SUCCESS) {
wbcFreeMemory(rids);
return false;
}
*pp_alias_rids = TALLOC_ARRAY(mem_ctx, uint32_t, num_rids);
if (*pp_alias_rids == NULL) {
wbcFreeMemory(rids);
return false;
}
memcpy(*pp_alias_rids, rids, sizeof(uint32_t) * num_rids);
*p_num_alias_rids = num_rids;
wbcFreeMemory(rids);
return true;
}
#else /* WITH_WINBIND */
struct passwd * winbind_getpwnam(const char * name)
@ -365,4 +434,19 @@ bool winbind_allocate_gid(gid_t *gid)
return false;
}
bool winbind_get_groups(TALLOC_CTX *mem_ctx, const char *account, uint32_t *num_groups, gid_t **_groups)
{
return false;
}
bool winbind_get_sid_aliases(TALLOC_CTX *mem_ctx,
const DOM_SID *dom_sid,
const DOM_SID *members,
size_t num_members,
uint32_t **pp_alias_rids,
size_t *p_num_alias_rids)
{
return false;
}
#endif /* WITH_WINBIND */

View File

@ -430,6 +430,8 @@ static struct winbindd_dispatch_table {
{ WINBINDD_GETUSERSIDS, winbindd_getusersids, "GETUSERSIDS" },
{ WINBINDD_GETUSERDOMGROUPS, winbindd_getuserdomgroups,
"GETUSERDOMGROUPS" },
{ WINBINDD_GETSIDALIASES, winbindd_getsidaliases,
"LOOKUPUSERALIASES" },
/* Group functions */

View File

@ -632,8 +632,8 @@ bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,
return True;
}
static bool parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr,
DOM_SID **sids, size_t *num_sids)
bool parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr,
DOM_SID **sids, size_t *num_sids)
{
char *p, *q;
@ -822,92 +822,6 @@ void winbindd_getsidaliases_async(struct winbindd_domain *domain,
(void *)cont, private_data);
}
enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain,
struct winbindd_cli_state *state)
{
DOM_SID *sids = NULL;
size_t num_sids = 0;
char *sidstr = NULL;
ssize_t len;
size_t i;
uint32 num_aliases;
uint32 *alias_rids;
NTSTATUS result;
DEBUG(3, ("[%5lu]: getsidaliases\n", (unsigned long)state->pid));
sidstr = state->request.extra_data.data;
if (sidstr == NULL) {
sidstr = talloc_strdup(state->mem_ctx, "\n"); /* No SID */
if (!sidstr) {
DEBUG(0, ("Out of memory\n"));
return WINBINDD_ERROR;
}
}
DEBUG(10, ("Sidlist: %s\n", sidstr));
if (!parse_sidlist(state->mem_ctx, sidstr, &sids, &num_sids)) {
DEBUG(0, ("Could not parse SID list: %s\n", sidstr));
return WINBINDD_ERROR;
}
num_aliases = 0;
alias_rids = NULL;
result = domain->methods->lookup_useraliases(domain,
state->mem_ctx,
num_sids, sids,
&num_aliases,
&alias_rids);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(3, ("Could not lookup_useraliases: %s\n",
nt_errstr(result)));
return WINBINDD_ERROR;
}
num_sids = 0;
sids = NULL;
sidstr = NULL;
DEBUG(10, ("Got %d aliases\n", num_aliases));
for (i=0; i<num_aliases; i++) {
DOM_SID sid;
DEBUGADD(10, (" rid %d\n", alias_rids[i]));
sid_copy(&sid, &domain->sid);
sid_append_rid(&sid, alias_rids[i]);
result = add_sid_to_array(state->mem_ctx, &sid, &sids,
&num_sids);
if (!NT_STATUS_IS_OK(result)) {
return WINBINDD_ERROR;
}
}
if (!print_sidlist(state->mem_ctx, sids, num_sids, &sidstr, &len)) {
DEBUG(0, ("Could not print_sidlist\n"));
state->response.extra_data.data = NULL;
return WINBINDD_ERROR;
}
state->response.extra_data.data = NULL;
if (sidstr) {
state->response.extra_data.data = SMB_STRDUP(sidstr);
if (!state->response.extra_data.data) {
DEBUG(0, ("Out of memory\n"));
return WINBINDD_ERROR;
}
DEBUG(10, ("aliases_list: %s\n",
(char *)state->response.extra_data.data));
state->response.length += len+1;
}
return WINBINDD_OK;
}
struct gettoken_state {
TALLOC_CTX *mem_ctx;
DOM_SID user_sid;

View File

@ -109,6 +109,10 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = {
.name = "GETSIDALIASES",
.struct_cmd = WINBINDD_DUAL_GETSIDALIASES,
.struct_fn = winbindd_dual_getsidaliases,
},{
.name = "GETSIDALIASES",
.struct_cmd = WINBINDD_GETSIDALIASES,
.struct_fn = winbindd_dual_getsidaliases,
},{
.name = "CCACHE_NTLM_AUTH",
.struct_cmd = WINBINDD_CCACHE_NTLMAUTH,

View File

@ -1867,3 +1867,118 @@ enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *doma
return WINBINDD_OK;
}
void winbindd_getsidaliases(struct winbindd_cli_state *state)
{
DOM_SID domain_sid;
struct winbindd_domain *domain;
/* Ensure null termination */
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
if (!string_to_sid(&domain_sid, state->request.data.sid)) {
DEBUG(1, ("Could not get convert sid %s from string\n",
state->request.data.sid));
request_error(state);
return;
}
/* Get info for the domain */
if ((domain = find_domain_from_sid_noinit(&domain_sid)) == NULL) {
DEBUG(0,("could not find domain entry for sid %s\n",
sid_string_dbg(&domain_sid)));
request_error(state);
return;
}
sendto_domain(state, domain);
}
enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain,
struct winbindd_cli_state *state)
{
DOM_SID *sids = NULL;
size_t num_sids = 0;
char *sidstr = NULL;
ssize_t len;
size_t i;
uint32 num_aliases;
uint32 *alias_rids;
NTSTATUS result;
DEBUG(3, ("[%5lu]: getsidaliases\n", (unsigned long)state->pid));
sidstr = state->request.extra_data.data;
if (sidstr == NULL) {
sidstr = talloc_strdup(state->mem_ctx, "\n"); /* No SID */
if (!sidstr) {
DEBUG(0, ("Out of memory\n"));
return WINBINDD_ERROR;
}
}
DEBUG(10, ("Sidlist: %s\n", sidstr));
if (!parse_sidlist(state->mem_ctx, sidstr, &sids, &num_sids)) {
DEBUG(0, ("Could not parse SID list: %s\n", sidstr));
return WINBINDD_ERROR;
}
num_aliases = 0;
alias_rids = NULL;
result = domain->methods->lookup_useraliases(domain,
state->mem_ctx,
num_sids, sids,
&num_aliases,
&alias_rids);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(3, ("Could not lookup_useraliases: %s\n",
nt_errstr(result)));
return WINBINDD_ERROR;
}
num_sids = 0;
sids = NULL;
sidstr = NULL;
DEBUG(10, ("Got %d aliases\n", num_aliases));
for (i=0; i<num_aliases; i++) {
DOM_SID sid;
DEBUGADD(10, (" rid %d\n", alias_rids[i]));
sid_copy(&sid, &domain->sid);
sid_append_rid(&sid, alias_rids[i]);
result = add_sid_to_array(state->mem_ctx, &sid, &sids,
&num_sids);
if (!NT_STATUS_IS_OK(result)) {
return WINBINDD_ERROR;
}
}
if (!print_sidlist(state->mem_ctx, sids, num_sids, &sidstr, &len)) {
DEBUG(0, ("Could not print_sidlist\n"));
state->response.extra_data.data = NULL;
return WINBINDD_ERROR;
}
state->response.extra_data.data = NULL;
if (sidstr) {
state->response.extra_data.data = SMB_STRDUP(sidstr);
if (!state->response.extra_data.data) {
DEBUG(0, ("Out of memory\n"));
return WINBINDD_ERROR;
}
DEBUG(10, ("aliases_list: %s\n",
(char *)state->response.extra_data.data));
state->response.length += len+1;
state->response.data.num_entries = num_sids;
}
return WINBINDD_OK;
}

View File

@ -112,6 +112,8 @@ enum winbindd_result winbindd_dual_list_groups(struct winbindd_domain *domain,
struct winbindd_cli_state *state);
bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,
size_t num_sids, char **result, ssize_t *len);
bool parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr,
DOM_SID **sids, size_t *num_sids);
enum winbindd_result winbindd_dual_lookuprids(struct winbindd_domain *domain,
struct winbindd_cli_state *state);
void winbindd_getsidaliases_async(struct winbindd_domain *domain,
@ -342,6 +344,7 @@ void winbindd_list_groups(struct winbindd_cli_state *state);
void winbindd_getgroups(struct winbindd_cli_state *state);
void winbindd_getusersids(struct winbindd_cli_state *state);
void winbindd_getuserdomgroups(struct winbindd_cli_state *state);
void winbindd_getsidaliases(struct winbindd_cli_state *state);
enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *domain,
struct winbindd_cli_state *state);
bool get_sam_group_entries(struct getent_state *ent);