/*
Unix SMB/CIFS implementation.
winbind client code
Copyright (C) Tim Potter 2000
Copyright (C) Andrew Tridgell 2000
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 .
*/
#include "includes.h"
#include "nsswitch/winbind_nss.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
NSS_STATUS winbindd_request_response(int req_type,
struct winbindd_request *request,
struct winbindd_response *response);
/* Call winbindd to convert a name to a sid */
bool winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
enum lsa_SidType *name_type)
{
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
if (!sid || !name_type)
return False;
/* Send off request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
fstrcpy(request.data.name.dom_name, dom_name);
fstrcpy(request.data.name.name, name);
if ((result = winbindd_request_response(WINBINDD_LOOKUPNAME, &request,
&response)) == NSS_STATUS_SUCCESS) {
if (!string_to_sid(sid, response.data.sid.sid))
return False;
*name_type = (enum lsa_SidType)response.data.sid.type;
}
return result == NSS_STATUS_SUCCESS;
}
/* Call winbindd to convert sid to name */
bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
const char **domain, const char **name,
enum lsa_SidType *name_type)
{
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
/* Initialise request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
fstrcpy(request.data.sid, sid_string_static(sid));
/* Make request */
result = winbindd_request_response(WINBINDD_LOOKUPSID, &request,
&response);
if (result != NSS_STATUS_SUCCESS) {
return False;
}
/* Copy out result */
if (domain != NULL) {
*domain = talloc_strdup(mem_ctx, response.data.name.dom_name);
if (*domain == NULL) {
DEBUG(0, ("talloc failed\n"));
return False;
}
}
if (name != NULL) {
*name = talloc_strdup(mem_ctx, response.data.name.name);
if (*name == NULL) {
DEBUG(0, ("talloc failed\n"));
return False;
}
}
*name_type = (enum lsa_SidType)response.data.name.type;
DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n",
sid_string_static(sid), response.data.name.dom_name,
response.data.name.name));
return True;
}
bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
const DOM_SID *domain_sid,
int num_rids, uint32 *rids,
const char **domain_name,
const char ***names, enum lsa_SidType **types)
{
size_t i, buflen;
ssize_t len;
char *ridlist;
char *p;
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
if (num_rids == 0) {
return False;
}
/* Initialise request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
fstrcpy(request.data.sid, sid_string_static(domain_sid));
len = 0;
buflen = 0;
ridlist = NULL;
for (i=0; ixid.id;
request.data.dual_idmapset.type = map->xid.type;
sid_to_string(request.data.dual_idmapset.sid, map->sid);
result = winbindd_request_response(WINBINDD_SET_MAPPING, &request, &response);
return (result == NSS_STATUS_SUCCESS);
}
bool winbind_set_uid_hwm(unsigned long id)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
/* Initialise request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
/* Make request */
request.data.dual_idmapset.id = id;
request.data.dual_idmapset.type = ID_TYPE_UID;
result = winbindd_request_response(WINBINDD_SET_HWM, &request, &response);
return (result == NSS_STATUS_SUCCESS);
}
bool winbind_set_gid_hwm(unsigned long id)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
/* Initialise request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
/* Make request */
request.data.dual_idmapset.id = id;
request.data.dual_idmapset.type = ID_TYPE_GID;
result = winbindd_request_response(WINBINDD_SET_HWM, &request, &response);
return (result == NSS_STATUS_SUCCESS);
}
/**********************************************************************
simple wrapper function to see if winbindd is alive
**********************************************************************/
bool winbind_ping( void )
{
NSS_STATUS result;
result = winbindd_request_response(WINBINDD_PING, NULL, NULL);
return result == NSS_STATUS_SUCCESS;
}
/**********************************************************************
Is a domain trusted?
result == NSS_STATUS_UNAVAIL: winbind not around
result == NSS_STATUS_NOTFOUND: winbind around, but domain missing
Due to a bad API NSS_STATUS_NOTFOUND is returned both when winbind_off and
when winbind return WINBINDD_ERROR. So the semantics of this routine depends
on winbind_on. Grepping for winbind_off I just found 3 places where winbind
is turned off, and this does not conflict (as far as I have seen) with the
callers of is_trusted_domains.
I *hate* global variables....
Volker
**********************************************************************/
NSS_STATUS wb_is_trusted_domain(const char *domain)
{
struct winbindd_request request;
struct winbindd_response response;
/* Call winbindd */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
fstrcpy(request.domain_name, domain);
return winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response);
}