summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcvs2svn Import User <samba-bugs@samba.org>2001-05-31 14:41:54 +0000
committercvs2svn Import User <samba-bugs@samba.org>2001-05-31 14:41:54 +0000
commita5470a6bce218533bdbd238f21f216d7f76b1f88 (patch)
tree154710017344a395bb260b73a8ff8a2c4f79fa64
parent939403fd12f34151b9e1ef920835d8452f51963c (diff)
parent6594a59263c9ec8f62d23f3aa1b56051eefc2f88 (diff)
downloadsamba-a5470a6bce218533bdbd238f21f216d7f76b1f88.tar.gz
samba-a5470a6bce218533bdbd238f21f216d7f76b1f88.tar.xz
samba-a5470a6bce218533bdbd238f21f216d7f76b1f88.zip
This commit was manufactured by cvs2svn to create branch 'SAMBA_2_2'.
-rw-r--r--examples/libsmbclient/README8
-rw-r--r--source/include/util_getent.h45
-rw-r--r--source/lib/util_getent.c211
-rw-r--r--source/libsmb/cli_netlogon.c128
-rw-r--r--source/libsmb/cli_srvsvc.c128
-rw-r--r--source/nsswitch/pam_winbind.h87
-rw-r--r--testsuite/nsswitch/login.exp102
7 files changed, 709 insertions, 0 deletions
diff --git a/examples/libsmbclient/README b/examples/libsmbclient/README
new file mode 100644
index 00000000000..d9a9f829174
--- /dev/null
+++ b/examples/libsmbclient/README
@@ -0,0 +1,8 @@
+Some simple example programs for libsmbclient ...
+
+testsmbc.c is kinda broken as it has many hardcoded bits in it
+
+tree.c is an example of how you might do some of these things with GTK+
+It needs lots of work but shows you some ways to use libsmbclient.
+
+Richard Sharpe, 17-May-2001 ...
diff --git a/source/include/util_getent.h b/source/include/util_getent.h
new file mode 100644
index 00000000000..11926b89641
--- /dev/null
+++ b/source/include/util_getent.h
@@ -0,0 +1,45 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ Samba utility functions
+ Copyright (C) Simo Sorce 2001
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* element for a single linked list of group entries */
+/* replace the use of struct group in some cases */
+/* used by getgrent_list() */
+struct sys_grent {
+ char *gr_name;
+ char *gr_passwd;
+ gid_t gr_gid;
+ char **gr_mem;
+ struct sys_grent *next;
+};
+
+/* element for a single linked list of passwd entries */
+/* replace the use of struct passwd in some cases */
+/* used by getpwent_list() */
+struct sys_pwent {
+ char *pw_name;
+ char *pw_passwd;
+ uid_t pw_uid;
+ gid_t pw_gid;
+ char *pw_gecos;
+ char *pw_dir;
+ char *pw_shell;
+ struct sys_pwent *next;
+};
diff --git a/source/lib/util_getent.c b/source/lib/util_getent.c
new file mode 100644
index 00000000000..4123be8e24c
--- /dev/null
+++ b/source/lib/util_getent.c
@@ -0,0 +1,211 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ Samba utility functions
+ Copyright (C) Simo Sorce 2001
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/****************************************************************
+ Returns a single linked list of group entries.
+ Use grent_free() to free it after use.
+****************************************************************/
+
+struct sys_grent * getgrent_list(void)
+{
+ struct sys_grent *glist;
+ struct sys_grent *gent;
+ struct group *grp;
+
+ gent = (struct sys_grent *) malloc(sizeof(struct sys_grent));
+ if (gent == NULL) {
+ DEBUG (0, ("Out of memory in getgrent_list!\n"));
+ return NULL;
+ }
+ glist = gent;
+
+ setgrent();
+ grp = getgrent();
+ while (grp != NULL) {
+ int i,num;
+
+ memset(gent, '\0', sizeof(struct sys_grent));
+ if (grp->gr_name) {
+ if ((gent->gr_name = strdup(grp->gr_name)) == NULL)
+ goto err;
+ }
+ if (grp->gr_passwd) {
+ if ((gent->gr_passwd = strdup(grp->gr_passwd)) == NULL)
+ goto err;
+ }
+ gent->gr_gid = grp->gr_gid;
+
+ /* number of strings in gr_mem */
+ for (num = 0; grp->gr_mem[num]; num++)
+ ;
+
+ /* alloc space for gr_mem string pointers */
+ if ((gent->gr_mem = (char **) malloc(num+1 * sizeof(char *))) == NULL)
+ goto err;
+
+ for (i=0; i < num; i++) {
+ if ((gent->gr_mem[i] = strdup(grp->gr_mem[i])) == NULL)
+ goto err;
+ }
+ gent->gr_mem[num] = NULL;
+
+ grp = getgrent();
+ if (grp) {
+ gent->next = (struct sys_grent *) malloc(sizeof(struct sys_grent));
+ if (gent->next == NULL)
+ goto err;
+ gent = gent->next;
+ }
+ }
+
+ endgrent();
+ return glist;
+
+ err:
+
+ endgrent();
+ DEBUG(0, ("Out of memory in getgrent_list!\n"));
+ grent_free(glist);
+ return NULL;
+}
+
+/****************************************************************
+ Free the single linked list of group entries made by
+ getgrent_list()
+****************************************************************/
+
+void grent_free (struct sys_grent *glist)
+{
+ while (glist) {
+ char **ary;
+ struct sys_grent *temp;
+
+ if (glist->gr_name)
+ free(glist->gr_name);
+ if (glist->gr_passwd)
+ free(glist->gr_passwd);
+ if (glist->gr_mem) {
+ ary = glist->gr_mem;
+ while (*ary) {
+ free(*ary);
+ ary++;
+ }
+ free(glist->gr_mem);
+ }
+ temp = glist->next;
+ free(glist);
+ glist = temp;
+ }
+}
+
+/****************************************************************
+ Returns a single linked list of passwd entries.
+ Use pwent_free() to free it after use.
+****************************************************************/
+
+struct sys_pwent * getpwent_list(void)
+{
+ struct sys_pwent *plist;
+ struct sys_pwent *pent;
+ struct passwd *pwd;
+
+ pent = (struct sys_pwent *) malloc(sizeof(struct sys_pwent));
+ if (pent == NULL) {
+ DEBUG (0, ("Out of memory in getpwent_list!\n"));
+ return NULL;
+ }
+ plist = pent;
+
+ setpwent();
+ pwd = getpwent();
+ while (pwd != NULL) {
+ memset(pent, '\0', sizeof(struct sys_pwent));
+ if (pwd->pw_name) {
+ if ((pent->pw_name = strdup(pwd->pw_name)) == NULL)
+ goto err;
+ }
+ if (pwd->pw_passwd) {
+ if ((pent->pw_passwd = strdup(pwd->pw_passwd)) == NULL)
+ goto err;
+ }
+ pent->pw_uid = pwd->pw_uid;
+ pent->pw_gid = pwd->pw_gid;
+ if (pwd->pw_gecos) {
+ if ((pent->pw_name = strdup(pwd->pw_gecos)) == NULL)
+ goto err;
+ }
+ if (pwd->pw_dir) {
+ if ((pent->pw_name = strdup(pwd->pw_dir)) == NULL)
+ goto err;
+ }
+ if (pwd->pw_shell) {
+ if ((pent->pw_name = strdup(pwd->pw_shell)) == NULL)
+ goto err;
+ }
+
+ pwd = getpwent();
+ if (pwd) {
+ pent->next = (struct sys_pwent *) malloc(sizeof(struct sys_pwent));
+ if (pent->next == NULL)
+ goto err;
+ pent = pent->next;
+ }
+ }
+
+ endpwent();
+ return plist;
+
+ err:
+
+ endpwent();
+ DEBUG(0, ("Out of memory in getpwent_list!\n"));
+ pwent_free(plist);
+ return NULL;
+}
+
+/****************************************************************
+ Free the single linked list of passwd entries made by
+ getpwent_list()
+****************************************************************/
+
+void pwent_free (struct sys_pwent *plist)
+{
+ while (plist) {
+ struct sys_pwent *temp;
+
+ if (plist->pw_name)
+ free(plist->pw_name);
+ if (plist->pw_passwd)
+ free(plist->pw_passwd);
+ if (plist->pw_gecos)
+ free(plist->pw_gecos);
+ if (plist->pw_dir)
+ free(plist->pw_dir);
+ if (plist->pw_shell)
+ free(plist->pw_shell);
+
+ temp = plist->next;
+ free(plist);
+ plist = temp;
+ }
+}
diff --git a/source/libsmb/cli_netlogon.c b/source/libsmb/cli_netlogon.c
new file mode 100644
index 00000000000..47b7c2f22ec
--- /dev/null
+++ b/source/libsmb/cli_netlogon.c
@@ -0,0 +1,128 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Tim Potter 2001
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/* Opens a SMB connection to the netlogon pipe */
+
+struct cli_state *cli_netlogon_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds)
+{
+ struct in_addr dest_ip;
+ struct nmb_name calling, called;
+ fstring dest_host;
+ extern pstring global_myname;
+ struct ntuser_creds anon;
+
+ /* Initialise cli_state information */
+
+ if (!cli_initialise(cli)) {
+ return NULL;
+ }
+
+ if (!creds) {
+ ZERO_STRUCT(anon);
+ anon.pwd.null_pwd = 1;
+ creds = &anon;
+ }
+
+ cli_init_creds(cli, creds);
+
+ /* Establish a SMB connection */
+
+ if (!resolve_srv_name(system_name, dest_host, &dest_ip)) {
+ return NULL;
+ }
+
+ make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
+ make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
+
+ if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling,
+ &called, "IPC$", "IPC", False, True)) {
+ return NULL;
+ }
+
+ /* Open a NT session thingy */
+
+ if (!cli_nt_session_open(cli, PIPE_NETLOGON)) {
+ cli_shutdown(cli);
+ return NULL;
+ }
+
+ return cli;
+}
+
+/* Shut down a SMB connection to the netlogon pipe */
+
+void cli_netlogon_shutdown(struct cli_state *cli)
+{
+ if (cli->fd != -1) cli_ulogoff(cli);
+ cli_shutdown(cli);
+}
+
+/* Logon Control 2 */
+
+uint32 cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 query_level)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_LOGON_CTRL2 q;
+ NET_R_LOGON_CTRL2 r;
+ uint32 result = NT_STATUS_UNSUCCESSFUL;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Initialise input parameters */
+
+ init_net_q_logon_ctrl2(&q, cli->srv_name_slash, query_level);
+
+ /* Marshall data and send request */
+
+ if (!net_io_q_logon_ctrl2("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!net_io_r_logon_ctrl2("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ result = r.status;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
diff --git a/source/libsmb/cli_srvsvc.c b/source/libsmb/cli_srvsvc.c
new file mode 100644
index 00000000000..8209d9301f1
--- /dev/null
+++ b/source/libsmb/cli_srvsvc.c
@@ -0,0 +1,128 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Tim Potter 2001
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/* Opens a SMB connection to the svrsvc pipe */
+
+struct cli_state *cli_svrsvc_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds)
+{
+ struct in_addr dest_ip;
+ struct nmb_name calling, called;
+ fstring dest_host;
+ extern pstring global_myname;
+ struct ntuser_creds anon;
+
+ /* Initialise cli_state information */
+
+ if (!cli_initialise(cli)) {
+ return NULL;
+ }
+
+ if (!creds) {
+ ZERO_STRUCT(anon);
+ anon.pwd.null_pwd = 1;
+ creds = &anon;
+ }
+
+ cli_init_creds(cli, creds);
+
+ /* Establish a SMB connection */
+
+ if (!resolve_srv_name(system_name, dest_host, &dest_ip)) {
+ return NULL;
+ }
+
+ make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
+ make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
+
+ if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling,
+ &called, "IPC$", "IPC", False, True)) {
+ return NULL;
+ }
+
+ /* Open a NT session thingy */
+
+ if (!cli_nt_session_open(cli, PIPE_SRVSVC)) {
+ cli_shutdown(cli);
+ return NULL;
+ }
+
+ return cli;
+}
+
+/* Shut down a SMB connection to the srvsvc pipe */
+
+void cli_srvsvc_shutdown(struct cli_state *cli)
+{
+ if (cli->fd != -1) cli_ulogoff(cli);
+ cli_shutdown(cli);
+}
+
+uint32 cli_srvsvc_net_srv_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 switch_value, SRV_INFO_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SRV_Q_NET_SRV_GET_INFO q;
+ SRV_R_NET_SRV_GET_INFO r;
+ uint32 result;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Initialise input parameters */
+
+ init_srv_q_net_srv_get_info(&q, cli->srv_name_slash, switch_value);
+
+ /* Marshall data and send request */
+
+ if (!srv_io_q_net_srv_get_info("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ r.ctr = ctr;
+
+ if (!srv_io_r_net_srv_get_info("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ result = r.status;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
diff --git a/source/nsswitch/pam_winbind.h b/source/nsswitch/pam_winbind.h
new file mode 100644
index 00000000000..5618dc1b61f
--- /dev/null
+++ b/source/nsswitch/pam_winbind.h
@@ -0,0 +1,87 @@
+/* pam_winbind header file
+ (Solaris needs some macros from Linux for common PAM code)
+
+ Shirish Kalele 2000
+*/
+
+#ifdef HAVE_FEATURES_H
+#include <features.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <config.h>
+
+#define MODULE_NAME "pam_winbind"
+#define PAM_SM_AUTH
+#define PAM_SM_ACCOUNT
+#define PAM_SM_PASSWORD
+
+#if defined(SUNOS5) || defined(SUNOS4)
+
+/* Solaris always uses dynamic pam modules */
+#define PAM_EXTERN extern
+#include <security/pam_appl.h>
+
+#define PAM_AUTHTOK_RECOVER_ERR PAM_AUTHTOK_RECOVERY_ERR
+#endif
+
+#ifdef HAVE_SECURITY_PAM_MODULES_H
+#include <security/pam_modules.h>
+#endif
+
+#ifdef HAVE_SECURITY__PAM_MACROS_H
+#include <security/_pam_macros.h>
+#else
+/* Define required macros from (Linux PAM 0.68) security/_pam_macros.h */
+#define _pam_drop_reply(/* struct pam_response * */ reply, /* int */ replies) \
+do { \
+ int reply_i; \
+ \
+ for (reply_i=0; reply_i<replies; ++reply_i) { \
+ if (reply[reply_i].resp) { \
+ _pam_overwrite(reply[reply_i].resp); \
+ free(reply[reply_i].resp); \
+ } \
+ } \
+ if (reply) \
+ free(reply); \
+} while (0)
+
+#define _pam_overwrite(x) \
+do { \
+ register char *__xx__; \
+ if ((__xx__=(x))) \
+ while (*__xx__) \
+ *__xx__++ = '\0'; \
+} while (0)
+
+/*
+ * Don't just free it, forget it too.
+ */
+
+#define _pam_drop(X) \
+do { \
+ if (X) { \
+ free(X); \
+ X=NULL; \
+ } \
+} while (0)
+
+#define x_strdup(s) ( (s) ? strdup(s):NULL )
+#endif
+
+#define PAM_DEBUG_ARG (1<<0)
+#define PAM_USE_AUTHTOK_ARG (1<<1)
+#define PAM_UNKNOWN_OK_ARG (1<<2)
+
+#include "winbind_nss_config.h"
+#include "winbindd_nss.h"
diff --git a/testsuite/nsswitch/login.exp b/testsuite/nsswitch/login.exp
new file mode 100644
index 00000000000..c2bb0e5a40a
--- /dev/null
+++ b/testsuite/nsswitch/login.exp
@@ -0,0 +1,102 @@
+#
+# @(#) Test logins using pam_winbind.so module using telnet
+#
+
+load_lib util-defs.exp
+load_lib nsswitch-config.exp
+
+#
+# @(#) Test user can login
+#
+
+spawn telnet localhost
+
+set test_desc "telnet localhost (login)"
+
+expect {
+ "login:" { }
+ timeout { fail "timed out in $test_desc"; return }
+ eof { fail "end of file in $test_desc"; return }
+}
+
+send "$domain/$USER\r"
+
+set test_desc "telnet localhost (password)"
+
+expect {
+ "Password:" { }
+ timeout { fail "timed out in $test_desc"; return }
+ eof { fail "end of file in $test_desc"; return }
+}
+
+send "$PASSWORD\r"
+
+expect {
+ "$ " { }
+ "Login incorrect" { fail "login incorrect"; return }
+ timeout { fail "timed out in $test_desc"; return }
+ eof { fail "end of file in $test_desc"; return }
+}
+
+pass "login $domain/$USER"
+
+#
+# @(#) Check supplementary group membership
+#
+
+set test_desc "supplementary groups"
+
+# Get list of groups
+
+send "id -G\r"
+
+expect {
+ -re "((\[0-9]+ )*\[0-9]+\r)" { exp_continue; }
+ "$ " { }
+ timeout { fail "timed out in $test_desc"; return }
+ eof { fail "end of file in $test_desc"; return }
+}
+
+set groups $expect_out(1,string)
+set wb_groups [util_start "bin/wbinfo" "-r $domain/$USER"]
+
+verbose "id groups are $groups"
+verbose "wbinfo groups are $wb_groups"
+
+# Check all groups from id are in wbinfo and vice-versa
+
+set failed 0
+
+foreach { group } $groups {
+ set got_group 0
+ foreach { wb_group } $wb_groups {
+ if { $wb_group == $group } {
+ set got_group 1
+ break
+ }
+ }
+
+ if { !$got_group } {
+ fail "group $group not in output of wbinfo -r"
+ set failed 1
+ }
+}
+
+foreach { wb_group } $wb_groups {
+ set got_group 0
+ foreach { group } $groups {
+ if { $group == $wb_group } {
+ set got_group 1
+ break
+ }
+ }
+
+ if { !$got_group } {
+ fail "group $group not in output of id -G"
+ set failed 1
+ }
+}
+
+if { !$failed } {
+ pass "id/wbinfo groups match"
+}