diff options
author | Gerald Carter <jerry@samba.org> | 2004-01-16 16:22:05 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2004-01-16 16:22:05 +0000 |
commit | 8c854aee01ea82b4f6da9ba5dddefb55f784cb09 (patch) | |
tree | 80d6dc160b253df936a33daed3bf11c8f35892ce | |
parent | cdbd38790adbe889f07b3e5395d3f167db288230 (diff) | |
download | samba-8c854aee01ea82b4f6da9ba5dddefb55f784cb09.tar.gz samba-8c854aee01ea82b4f6da9ba5dddefb55f784cb09.tar.xz samba-8c854aee01ea82b4f6da9ba5dddefb55f784cb09.zip |
another short rounds of syncs from 3.0
-rw-r--r-- | WHATSNEW.txt | 12 | ||||
-rw-r--r-- | examples/nss/nss_winbind.c | 422 | ||||
-rw-r--r-- | examples/nss/nss_winbind.h | 97 | ||||
-rw-r--r-- | examples/nss/wbtest.c | 268 | ||||
-rw-r--r-- | source/client/client.c | 48 | ||||
-rw-r--r-- | source/nsswitch/winbind_nss_linux.c | 138 | ||||
-rw-r--r-- | source/utils/net_rpc.c | 29 |
7 files changed, 728 insertions, 286 deletions
diff --git a/WHATSNEW.txt b/WHATSNEW.txt index cd563f66d43..5c48cf72664 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -45,7 +45,7 @@ o Andrew Bartlet <abartlet@samba.org> * BUG 722: Allow winbindd to map machine accounts to uids. * More cleanups for winbindd's find_our_domain(). * More clearly detect whether a domain controller is an NT4 - or mixed-mode AD DC. + or mixed-mode AD DC (additional bug fixes by jerry & jmcd). * Increase separation between DNS queries for hosts and queries for AD domain controllers. @@ -74,11 +74,17 @@ o Luke Howard <lukeh@PADL.COM> * Fix segfault in session setup reply caused by a early free(). +o Stoian Ivanov <sdr@bultra.com> + * Implement grepable output for smbclient -L. + + o Volker Lendecke <vl@samba.org> * Add a German translation for SWAT. * Fix a segfaults in winbindd. * Fix the user's domain passed to register_vuid() from reply_spnego_kerberos(). + * Add NSS example code in nss_winbind to convert UNIX + id's <-> Windows SIDs. o Herb Lewis <herb@samba.org> @@ -94,9 +100,11 @@ o John Klinger <john.klinger@lmco.com> * Implement initgroups() call in nss_winbind on Solaris. -o Jim McDonough <jmcd@us.ibm.com> +o Jim McDonough <jmcd@samba.org> * Fix regression in net rpc join caused by recent changes to cli_lsa_query_info_policy(). + * BUG 964: Fix crash bug in 'net rpc join' using a preexisting + machine account. o Stefan Metzmacher <metze@samba.org> diff --git a/examples/nss/nss_winbind.c b/examples/nss/nss_winbind.c new file mode 100644 index 00000000000..968cc7adddc --- /dev/null +++ b/examples/nss/nss_winbind.c @@ -0,0 +1,422 @@ +/* + nss sample code for extended winbindd functionality + + Copyright (C) Andrew Tridgell (tridge@samba.org) + + you are free to use this code in any way you see fit, including + without restriction, using this code in your own products. You do + not need to give any attribution. +*/ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <nss.h> +#include <dlfcn.h> +#include <errno.h> +#include <string.h> +#include <sys/types.h> + +#include "nss_winbind.h" + +/* + find a function in the nss library +*/ +static void *find_fn(struct nss_state *nss, const char *name) +{ + void *res; + char *s = NULL; + + asprintf(&s, "_nss_%s_%s", nss->nss_name, name); + if (!s) { + errno = ENOMEM; + return NULL; + } + res = dlsym(nss->dl_handle, s); + free(s); + if (!res) { + errno = ENOENT; + return NULL; + } + return res; +} + +/* + establish a link to the nss library + Return 0 on success and -1 on error +*/ +int nss_open(struct nss_state *nss, const char *nss_path) +{ + char *p; + p = strrchr(nss_path, '_'); + if (!p) { + errno = EINVAL; + return -1; + } + + nss->nss_name = strdup(p+1); + p = strchr(nss->nss_name, '.'); + if (p) *p = 0; + + nss->dl_handle = dlopen(nss_path, RTLD_LAZY); + if (!nss->dl_handle) { + free(nss->nss_name); + return -1; + } + + return 0; +} + +/* + close and cleanup a nss state +*/ +void nss_close(struct nss_state *nss) +{ + free(nss->nss_name); + dlclose(nss->dl_handle); +} + +/* + make a getpwnam call. + Return 0 on success and -1 on error +*/ +int nss_getpwent(struct nss_state *nss, struct passwd *pwd) +{ + enum nss_status (*_nss_getpwent_r)(struct passwd *, char *, + size_t , int *); + enum nss_status status; + int nss_errno = 0; + + _nss_getpwent_r = find_fn(nss, "getpwent_r"); + + if (!_nss_getpwent_r) { + return -1; + } + + status = _nss_getpwent_r(pwd, nss->pwnam_buf, sizeof(nss->pwnam_buf), + &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + return 0; +} + +/* + make a setpwent call. + Return 0 on success and -1 on error +*/ +int nss_setpwent(struct nss_state *nss) +{ + enum nss_status (*_nss_setpwent)(void) = find_fn(nss, "setpwent"); + enum nss_status status; + if (!_nss_setpwent) { + return -1; + } + status = _nss_setpwent(); + if (status != NSS_STATUS_SUCCESS) { + errno = EINVAL; + return -1; + } + return 0; +} + +/* + make a endpwent call. + Return 0 on success and -1 on error +*/ +int nss_endpwent(struct nss_state *nss) +{ + enum nss_status (*_nss_endpwent)(void) = find_fn(nss, "endpwent"); + enum nss_status status; + if (!_nss_endpwent) { + return -1; + } + status = _nss_endpwent(); + if (status != NSS_STATUS_SUCCESS) { + errno = EINVAL; + return -1; + } + return 0; +} + + +/* + convert a name to a SID + caller frees + Return 0 on success and -1 on error +*/ +int nss_nametosid(struct nss_state *nss, const char *name, char **sid) +{ + enum nss_status (*_nss_nametosid)(const char *, char **, char *, + size_t, int *); + enum nss_status status; + int nss_errno = 0; + char buf[200]; + + _nss_nametosid = find_fn(nss, "nametosid"); + + if (!_nss_nametosid) { + return -1; + } + + status = _nss_nametosid(name, sid, buf, sizeof(buf), &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + *sid = strdup(*sid); + + return 0; +} + +/* + convert a SID to a name + caller frees + Return 0 on success and -1 on error +*/ +int nss_sidtoname(struct nss_state *nss, const char *sid, char **name) +{ + enum nss_status (*_nss_sidtoname)(const char *, char **, char *, + size_t, int *); + enum nss_status status; + int nss_errno = 0; + char buf[200]; + + _nss_sidtoname = find_fn(nss, "sidtoname"); + + if (!_nss_sidtoname) { + return -1; + } + + status = _nss_sidtoname(sid, name, buf, sizeof(buf), &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + *name = strdup(*name); + + return 0; +} + +/* + return a list of group SIDs for a user SID + the returned list is NULL terminated + Return 0 on success and -1 on error +*/ +int nss_getusersids(struct nss_state *nss, const char *user_sid, char ***sids) +{ + enum nss_status (*_nss_getusersids)(const char *, char **, int *, + char *, size_t, int *); + enum nss_status status; + int nss_errno = 0; + char *s; + int i, num_groups = 0; + unsigned bufsize = 10; + char *buf; + + _nss_getusersids = find_fn(nss, "getusersids"); + + if (!_nss_getusersids) { + return -1; + } + +again: + buf = malloc(bufsize); + if (!buf) { + errno = ENOMEM; + return -1; + } + + status = _nss_getusersids(user_sid, &s, &num_groups, buf, bufsize, + &nss_errno); + + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + free(buf); + return -1; + } + + if (status == NSS_STATUS_TRYAGAIN) { + bufsize *= 2; + free(buf); + goto again; + } + + if (status != NSS_STATUS_SUCCESS) { + free(buf); + errno = nss_errno; + return -1; + } + + if (num_groups == 0) { + free(buf); + return 0; + } + + *sids = (char **)malloc(sizeof(char *) * (num_groups+1)); + if (! *sids) { + errno = ENOMEM; + free(buf); + return -1; + } + + for (i=0;i<num_groups;i++) { + (*sids)[i] = strdup(s); + s += strlen(s) + 1; + } + (*sids)[i] = NULL; + + free(buf); + + return 0; +} + +/* + convert a sid to a uid + Return 0 on success and -1 on error +*/ +int nss_sidtouid(struct nss_state *nss, const char *sid, uid_t *uid) +{ + enum nss_status (*_nss_sidtouid)(const char*, uid_t *, int*); + + enum nss_status status; + int nss_errno = 0; + + _nss_sidtouid = find_fn(nss, "sidtouid"); + + if (!_nss_sidtouid) { + return -1; + } + + status = _nss_sidtouid(sid, uid, &nss_errno); + + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + return 0; +} + +/* + convert a sid to a gid + Return 0 on success and -1 on error +*/ +int nss_sidtogid(struct nss_state *nss, const char *sid, gid_t *gid) +{ + enum nss_status (*_nss_sidtogid)(const char*, gid_t *, int*); + + enum nss_status status; + int nss_errno = 0; + + _nss_sidtogid = find_fn(nss, "sidtogid"); + + if (!_nss_sidtogid) { + return -1; + } + + status = _nss_sidtogid(sid, gid, &nss_errno); + + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + return 0; +} + +/* + convert a uid to a sid + caller frees + Return 0 on success and -1 on error +*/ +int nss_uidtosid(struct nss_state *nss, uid_t uid, char **sid) +{ + enum nss_status (*_nss_uidtosid)(uid_t, char **, char *, + size_t, int *); + enum nss_status status; + int nss_errno = 0; + char buf[200]; + + _nss_uidtosid = find_fn(nss, "uidtosid"); + + if (!_nss_uidtosid) { + return -1; + } + + status = _nss_uidtosid(uid, sid, buf, sizeof(buf), &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + *sid = strdup(*sid); + + return 0; +} + +/* + convert a gid to a sid + caller frees + Return 0 on success and -1 on error +*/ +int nss_gidtosid(struct nss_state *nss, gid_t gid, char **sid) +{ + enum nss_status (*_nss_gidtosid)(gid_t, char **, char *, + size_t, int *); + enum nss_status status; + int nss_errno = 0; + char buf[200]; + + _nss_gidtosid = find_fn(nss, "gidtosid"); + + if (!_nss_gidtosid) { + return -1; + } + + status = _nss_gidtosid(gid, sid, buf, sizeof(buf), &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + *sid = strdup(*sid); + + return 0; +} + diff --git a/examples/nss/nss_winbind.h b/examples/nss/nss_winbind.h new file mode 100644 index 00000000000..5a124a5a8ec --- /dev/null +++ b/examples/nss/nss_winbind.h @@ -0,0 +1,97 @@ +/* + nss sample code for extended winbindd functionality + + Copyright (C) Andrew Tridgell (tridge@samba.org) + Copyright (C) Volker Lendecke (vl@samba.org) + + you are free to use this code in any way you see fit, including + without restriction, using this code in your own products. You do + not need to give any attribution. +*/ + +#define _GNU_SOURCE + +#include <pwd.h> +#include <grp.h> + +struct nss_state { + void *dl_handle; + char *nss_name; + char pwnam_buf[512]; +}; + +/* + establish a link to the nss library + Return 0 on success and -1 on error +*/ +int nss_open(struct nss_state *nss, const char *nss_path); + +/* + close and cleanup a nss state +*/ +void nss_close(struct nss_state *nss); + +/* + make a getpwnam call. + Return 0 on success and -1 on error +*/ +int nss_getpwent(struct nss_state *nss, struct passwd *pwd); + +/* + make a setpwent call. + Return 0 on success and -1 on error +*/ +int nss_setpwent(struct nss_state *nss); + +/* + make a endpwent call. + Return 0 on success and -1 on error +*/ +int nss_endpwent(struct nss_state *nss); + +/* + convert a name to a SID + caller frees + Return 0 on success and -1 on error +*/ +int nss_nametosid(struct nss_state *nss, const char *name, char **sid); + +/* + convert a SID to a name + caller frees + Return 0 on success and -1 on error +*/ +int nss_sidtoname(struct nss_state *nss, const char *sid, char **name); + +/* + return a list of group SIDs for a user SID + the returned list is NULL terminated + Return 0 on success and -1 on error +*/ +int nss_getusersids(struct nss_state *nss, const char *user_sid, char ***sids); + +/* + convert a sid to a uid + Return 0 on success and -1 on error +*/ +int nss_sidtouid(struct nss_state *nss, const char *sid, uid_t *uid); + +/* + convert a sid to a gid + Return 0 on success and -1 on error +*/ +int nss_sidtogid(struct nss_state *nss, const char *sid, gid_t *gid); + +/* + convert a uid to a sid + caller frees + Return 0 on success and -1 on error +*/ +int nss_uidtosid(struct nss_state *nss, uid_t uid, char **sid); + +/* + convert a gid to a sid + caller frees + Return 0 on success and -1 on error +*/ +int nss_gidtosid(struct nss_state *nss, gid_t gid, char **sid); diff --git a/examples/nss/wbtest.c b/examples/nss/wbtest.c index fc8f575ef06..14265bd54c1 100644 --- a/examples/nss/wbtest.c +++ b/examples/nss/wbtest.c @@ -11,7 +11,7 @@ /* compile like this: - cc -o wbtest wbtest.c -ldl + cc -o wbtest wbtest.c nss_winbind.c -ldl and run like this: @@ -30,271 +30,7 @@ #include <string.h> #include <sys/types.h> -typedef enum nss_status NSS_STATUS; - -struct nss_state { - void *dl_handle; - char *nss_name; - char pwnam_buf[512]; -}; - -/* - find a function in the nss library -*/ -static void *find_fn(struct nss_state *nss, const char *name) -{ - void *res; - char *s = NULL; - - asprintf(&s, "_nss_%s_%s", nss->nss_name, name); - if (!s) { - errno = ENOMEM; - return NULL; - } - res = dlsym(nss->dl_handle, s); - free(s); - if (!res) { - errno = ENOENT; - return NULL; - } - return res; -} - -/* - establish a link to the nss library - Return 0 on success and -1 on error -*/ -int nss_open(struct nss_state *nss, const char *nss_path) -{ - char *p; - p = strrchr(nss_path, '_'); - if (!p) { - errno = EINVAL; - return -1; - } - - nss->nss_name = strdup(p+1); - p = strchr(nss->nss_name, '.'); - if (p) *p = 0; - - nss->dl_handle = dlopen(nss_path, RTLD_LAZY); - if (!nss->dl_handle) { - free(nss->nss_name); - return -1; - } - - return 0; -} - -/* - close and cleanup a nss state -*/ -void nss_close(struct nss_state *nss) -{ - free(nss->nss_name); - dlclose(nss->dl_handle); -} - -/* - make a getpwnam call. - Return 0 on success and -1 on error -*/ -int nss_getpwent(struct nss_state *nss, struct passwd *pwd) -{ - NSS_STATUS (*_nss_getpwent_r)(struct passwd *, char *, - size_t , int *) = find_fn(nss, "getpwent_r"); - NSS_STATUS status; - int nss_errno = 0; - - if (!_nss_getpwent_r) { - return -1; - } - - status = _nss_getpwent_r(pwd, nss->pwnam_buf, sizeof(nss->pwnam_buf), &nss_errno); - if (status == NSS_STATUS_NOTFOUND) { - errno = ENOENT; - return -1; - } - if (status != NSS_STATUS_SUCCESS) { - errno = nss_errno; - return -1; - } - - return 0; -} - -/* - make a setpwent call. - Return 0 on success and -1 on error -*/ -int nss_setpwent(struct nss_state *nss) -{ - NSS_STATUS (*_nss_setpwent)(void) = find_fn(nss, "setpwent"); - NSS_STATUS status; - if (!_nss_setpwent) { - return -1; - } - status = _nss_setpwent(); - if (status != NSS_STATUS_SUCCESS) { - errno = EINVAL; - return -1; - } - return 0; -} - -/* - make a endpwent call. - Return 0 on success and -1 on error -*/ -int nss_endpwent(struct nss_state *nss) -{ - NSS_STATUS (*_nss_endpwent)(void) = find_fn(nss, "endpwent"); - NSS_STATUS status; - if (!_nss_endpwent) { - return -1; - } - status = _nss_endpwent(); - if (status != NSS_STATUS_SUCCESS) { - errno = EINVAL; - return -1; - } - return 0; -} - - -/* - convert a name to a SID - caller frees - Return 0 on success and -1 on error -*/ -int nss_nametosid(struct nss_state *nss, const char *name, char **sid) -{ - NSS_STATUS (*_nss_nametosid)(const char *, char **, char *, size_t, int *) = - find_fn(nss, "nametosid"); - NSS_STATUS status; - int nss_errno = 0; - char buf[200]; - - if (!_nss_nametosid) { - return -1; - } - - status = _nss_nametosid(name, sid, buf, sizeof(buf), &nss_errno); - if (status == NSS_STATUS_NOTFOUND) { - errno = ENOENT; - return -1; - } - if (status != NSS_STATUS_SUCCESS) { - errno = nss_errno; - return -1; - } - - *sid = strdup(*sid); - - return 0; -} - -/* - convert a SID to a name - caller frees - Return 0 on success and -1 on error -*/ -int nss_sidtoname(struct nss_state *nss, char *sid, char **name) -{ - NSS_STATUS (*_nss_sidtoname)(const char *, char **, char *, size_t, int *) = - find_fn(nss, "sidtoname"); - NSS_STATUS status; - int nss_errno = 0; - char buf[200]; - - if (!_nss_sidtoname) { - return -1; - } - - status = _nss_sidtoname(sid, name, buf, sizeof(buf), &nss_errno); - if (status == NSS_STATUS_NOTFOUND) { - errno = ENOENT; - return -1; - } - if (status != NSS_STATUS_SUCCESS) { - errno = nss_errno; - return -1; - } - - *name = strdup(*name); - - return 0; -} - -/* - return a list of group SIDs for a user SID - the returned list is NULL terminated - Return 0 on success and -1 on error -*/ -int nss_getusersids(struct nss_state *nss, const char *user_sid, char ***sids) -{ - NSS_STATUS (*_nss_getusersids)(const char *, char **, int *, char *, size_t, int *) = - find_fn(nss, "getusersids"); - NSS_STATUS status; - int nss_errno = 0; - char *s; - int i, num_groups = 0; - unsigned bufsize = 10; - char *buf; - - if (!_nss_getusersids) { - return -1; - } - -again: - buf = malloc(bufsize); - if (!buf) { - errno = ENOMEM; - return -1; - } - - status = _nss_getusersids(user_sid, &s, &num_groups, buf, bufsize, &nss_errno); - if (status == NSS_STATUS_NOTFOUND) { - errno = ENOENT; - free(buf); - return -1; - } - - if (status == NSS_STATUS_TRYAGAIN) { - bufsize *= 2; - free(buf); - goto again; - } - - if (status != NSS_STATUS_SUCCESS) { - free(buf); - errno = nss_errno; - return -1; - } - - if (num_groups == 0) { - free(buf); - return 0; - } - - *sids = (char **)malloc(sizeof(char *) * (num_groups+1)); - if (! *sids) { - errno = ENOMEM; - free(buf); - return -1; - } - - for (i=0;i<num_groups;i++) { - (*sids)[i] = strdup(s); - s += strlen(s) + 1; - } - (*sids)[i] = NULL; - - free(buf); - - return 0; -} - +#include "nss_winbind.h" static int nss_test_users(struct nss_state *nss) { diff --git a/source/client/client.c b/source/client/client.c index 6c43a974f2b..22d7260b8f3 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -39,6 +39,7 @@ static pstring username; static pstring password; static BOOL use_kerberos; static BOOL got_pass; +static BOOL grepable=False; static char *cmdstr = NULL; static int io_bufsize = 64512; @@ -2001,8 +2002,12 @@ static void browse_fn(const char *name, uint32 m, /* FIXME: If the remote machine returns non-ascii characters in any of these fields, they can corrupt the output. We should remove them. */ - d_printf("\t%-15.15s%-10.10s%s\n", - name,typestr,comment); + if (!grepable) { + d_printf("\t%-15.15s%-10.10s%s\n", + name,typestr,comment); + } else { + d_printf ("%s|%s|%s\n",typestr,name,comment); + } } /**************************************************************************** @@ -2012,9 +2017,10 @@ static void browse_fn(const char *name, uint32 m, static BOOL browse_host(BOOL sort) { int ret; - - d_printf("\n\tSharename Type Comment\n"); - d_printf("\t--------- ---- -------\n"); + if (!grepable) { + d_printf("\n\tSharename Type Comment\n"); + d_printf("\t--------- ---- -------\n"); + } if((ret = cli_RNetShareEnum(cli, browse_fn, NULL)) == -1) d_printf("Error returning browse list: %s\n", cli_errstr(cli)); @@ -2029,27 +2035,37 @@ static BOOL browse_host(BOOL sort) static void server_fn(const char *name, uint32 m, const char *comment, void *state) { - d_printf("\t%-16.16s %s\n", name, comment); + + if (!grepable){ + d_printf("\t%-16.16s %s\n", name, comment); + } else { + d_printf("%s|%s|%s\n",(char *)state, name, comment); + } } /**************************************************************************** Try and browse available connections on a host. ****************************************************************************/ -static BOOL list_servers(char *wk_grp) +static BOOL list_servers(const char *wk_grp) { if (!cli->server_domain) return False; - - d_printf("\n\tServer Comment\n"); - d_printf("\t--------- -------\n"); - cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn, NULL); + if (!grepable) { + d_printf("\n\tServer Comment\n"); + d_printf("\t--------- -------\n"); + }; + cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn, + "Server"); - d_printf("\n\tWorkgroup Master\n"); - d_printf("\t--------- -------\n"); + if (!grepable) { + d_printf("\n\tWorkgroup Master\n"); + d_printf("\t--------- -------\n"); + }; - cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, server_fn, NULL); + cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, + server_fn, "Workgroup"); return True; } @@ -2794,6 +2810,7 @@ static void remember_query_host(const char *arg, { "command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated commands" }, { "send-buffer", 'b', POPT_ARG_INT, &io_bufsize, 'b', "Changes the transmit/send buffer", "BYTES" }, { "port", 'p', POPT_ARG_INT, &port, 'p', "Port to connect to", "PORT" }, + { "grepable", 'g', POPT_ARG_NONE, NULL, 'g', "Produce grepable output" }, POPT_COMMON_SAMBA POPT_COMMON_CONNECTION POPT_COMMON_CREDENTIALS @@ -2887,6 +2904,9 @@ static void remember_query_host(const char *arg, case 'D': fstrcpy(base_directory,poptGetOptArg(pc)); break; + case 'g': + grepable=True; + break; } } diff --git a/source/nsswitch/winbind_nss_linux.c b/source/nsswitch/winbind_nss_linux.c index ac4a861ff1b..362047f62b1 100644 --- a/source/nsswitch/winbind_nss_linux.c +++ b/source/nsswitch/winbind_nss_linux.c @@ -1009,3 +1009,141 @@ failed: free_response(&response); return ret; } + +/* map a sid to a uid */ +NSS_STATUS +_nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop) +{ + NSS_STATUS ret; + struct winbindd_response response; + struct winbindd_request request; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: sidtouid %s\n", getpid(), sid); +#endif + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1); + request.data.sid[sizeof(request.data.sid) - 1] = '\0'; + + ret = winbindd_request(WINBINDD_SID_TO_UID, &request, &response); + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno = EINVAL; + goto failed; + } + + *uid = response.data.uid; + +failed: + return ret; +} + +/* map a sid to a gid */ +NSS_STATUS +_nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop) +{ + NSS_STATUS ret; + struct winbindd_response response; + struct winbindd_request request; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: sidtogid %s\n", getpid(), sid); +#endif + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1); + request.data.sid[sizeof(request.data.sid) - 1] = '\0'; + + ret = winbindd_request(WINBINDD_SID_TO_GID, &request, &response); + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno = EINVAL; + goto failed; + } + + *gid = response.data.gid; + +failed: + return ret; +} + +/* map a uid to a SID string */ +NSS_STATUS +_nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer, + size_t buflen, int *errnop) +{ + NSS_STATUS ret; + struct winbindd_response response; + struct winbindd_request request; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: uidtosid %s\n", getpid(), name); +#endif + + ZERO_STRUCT(response); + ZERO_STRUCT(request); + + request.data.uid = uid; + + ret = winbindd_request(WINBINDD_UID_TO_SID, &request, &response); + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno = EINVAL; + goto failed; + } + + if (buflen < strlen(response.data.sid.sid)+1) { + ret = NSS_STATUS_TRYAGAIN; + *errnop = errno = ERANGE; + goto failed; + } + + *errnop = errno = 0; + *sid = buffer; + strcpy(*sid, response.data.sid.sid); + +failed: + free_response(&response); + return ret; +} + +/* map a gid to a SID string */ +NSS_STATUS +_nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer, + size_t buflen, int *errnop) +{ + NSS_STATUS ret; + struct winbindd_response response; + struct winbindd_request request; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: gidtosid %s\n", getpid(), name); +#endif + + ZERO_STRUCT(response); + ZERO_STRUCT(request); + + request.data.gid = gid; + + ret = winbindd_request(WINBINDD_GID_TO_SID, &request, &response); + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno = EINVAL; + goto failed; + } + + if (buflen < strlen(response.data.sid.sid)+1) { + ret = NSS_STATUS_TRYAGAIN; + *errnop = errno = ERANGE; + goto failed; + } + + *errnop = errno = 0; + *sid = buffer; + strcpy(*sid, response.data.sid.sid); + +failed: + free_response(&response); + return ret; +} diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c index 9f0f64edecb..93c13bf1f57 100644 --- a/source/utils/net_rpc.c +++ b/source/utils/net_rpc.c @@ -118,8 +118,6 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co return -1; } - domain_sid = net_get_remote_domain_sid(cli, mem_ctx); - /* Create mem_ctx */ if (!(mem_ctx = talloc_init("run_rpc_command"))) { @@ -128,6 +126,8 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co return -1; } + domain_sid = net_get_remote_domain_sid(cli, mem_ctx); + if (!cli_nt_session_open(cli, pipe_idx)) { DEBUG(0, ("Could not initialise pipe\n")); } @@ -276,7 +276,7 @@ static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, struct cli_stat * @return A shell status integer (0 for success) **/ -static int net_rpc_oldjoin(int argc, const char **argv) +static int net_rpc_perform_oldjoin(int argc, const char **argv) { return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, @@ -285,6 +285,27 @@ static int net_rpc_oldjoin(int argc, const char **argv) } /** + * Join a domain, the old way. This function exists to allow + * the message to be displayed when oldjoin was explicitly + * requested, but not when it was implied by "net rpc join" + * + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + * + * @return A shell status integer (0 for success) + **/ + +static int net_rpc_oldjoin(int argc, const char **argv) +{ + int rc = net_rpc_perform_oldjoin(argc, argv); + + if (rc) { + d_printf("Failed to join domain\n"); + } +} + +/** * Basic usage function for 'net rpc join' * @param argc Standard main() style argc * @param argc Standard main() style argv. Initial components are already @@ -319,7 +340,7 @@ static int rpc_join_usage(int argc, const char **argv) int net_rpc_join(int argc, const char **argv) { - if ((net_rpc_oldjoin(argc, argv) == 0)) + if ((net_rpc_perform_oldjoin(argc, argv) == 0)) return 0; return net_rpc_join_newstyle(argc, argv); |