View | Details | Raw Unified | Return to bug 19199
Collapse All | Expand All

(-)samba-3.0.28a/source/Makefile.in (-3 / +22 lines)
Lines 151-157 Link Here
151
151
152
# Note that all executable programs now provide for an optional executable suffix.
152
# Note that all executable programs now provide for an optional executable suffix.
153
153
154
SBIN_PROGS = bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ bin/swat@EXEEXT@ @EXTRA_SBIN_PROGS@
154
SBIN_PROGS = bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ bin/swat@EXEEXT@ @EXTRA_SBIN_PROGS@ @CIFSUPCALL_PROGS@
155
155
156
ROOT_SBIN_PROGS = @CIFSMOUNT_PROGS@
156
ROOT_SBIN_PROGS = @CIFSMOUNT_PROGS@
157
157
Lines 653-658 Link Here
653
653
654
CIFS_UMOUNT_OBJ = client/umount.cifs.o
654
CIFS_UMOUNT_OBJ = client/umount.cifs.o
655
655
656
CIFS_UPCALL_OBJ = client/cifs.upcall.o libsmb/clikrb5.o libsmb/clispnego.o \
657
		libsmb/asn1.o libsmb/nterr.o libsmb/dcerpc_err.o \
658
		libsmb/smbdes.o libsmb/smbencrypt.o libsmb/ntlmssp_parse.o \
659
		$(PARAM_OBJ) $(LIBNMB_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ) \
660
		$(ERRORMAP_OBJ) $(RPC_PARSE_OBJ1) $(DOSERR_OBJ) $(LIB_DUMMY_OBJ)
661
656
NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(LIBNMB_OBJ) $(RPC_PARSE_OBJ1) $(DOSERR_OBJ) \
662
NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(LIBNMB_OBJ) $(RPC_PARSE_OBJ1) $(DOSERR_OBJ) \
657
               $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ)
663
               $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ)
658
664
Lines 1029-1034 Link Here
1029
	@echo Linking $@
1035
	@echo Linking $@
1030
	@$(CC) $(FLAGS) -o $@ $(CIFS_UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS)
1036
	@$(CC) $(FLAGS) -o $@ $(CIFS_UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS)
1031
1037
1038
bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ1) $(LIB_OBJ) @BUILD_POPT@
1039
	@echo Linking $@
1040
	@$(CC) $(FLAGS) -o $@ $(CIFS_UPCALL_OBJ) $(DYNEXP) $(LDFLAGS) \
1041
		-lkeyutils $(LIBSMBCLIENT_OBJ1) $(LIB_OBJ) \
1042
		$(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) $(LIBS) 
1043
1032
bin/testparm@EXEEXT@: proto_exists $(TESTPARM_OBJ) @BUILD_POPT@ bin/.dummy
1044
bin/testparm@EXEEXT@: proto_exists $(TESTPARM_OBJ) @BUILD_POPT@ bin/.dummy
1033
	@echo Linking $@
1045
	@echo Linking $@
1034
	@$(CC) $(FLAGS) -o $@ $(TESTPARM_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(LDAP_LIBS) @POPTLIBS@
1046
	@$(CC) $(FLAGS) -o $@ $(TESTPARM_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(LDAP_LIBS) @POPTLIBS@
Lines 1573-1579 Link Here
1573
	@echo Linking $@
1585
	@echo Linking $@
1574
	@$(CC) $(FLAGS) -o $@ $(DYNEXP) script/tests/timelimit.o
1586
	@$(CC) $(FLAGS) -o $@ $(DYNEXP) script/tests/timelimit.o
1575
1587
1576
install: installservers installbin @INSTALL_CIFSMOUNT@ installman installscripts installdat installswat installmodules @INSTALL_LIBSMBCLIENT@ @INSTALL_LIBMSRPC@ @INSTALL_PAM_MODULES@ @INSTALL_LIBSMBSHAREMODES@
1588
install: installservers installbin @INSTALL_CIFSMOUNT@ @INSTALL_CIFSUPCALL@ installman installscripts installdat installswat installmodules @INSTALL_LIBSMBCLIENT@ @INSTALL_LIBMSRPC@ @INSTALL_PAM_MODULES@ @INSTALL_LIBSMBSHAREMODES@
1577
1589
1578
1590
1579
install-everything: install installmodules
1591
install-everything: install installmodules
Lines 1599-1604 Link Here
1599
	@$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS) $(DESTDIR) $(ROOTSBINDIR)
1611
	@$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS) $(DESTDIR) $(ROOTSBINDIR)
1600
	@$(SHELL) script/installbin.sh $(INSTALLPERMS) $(DESTDIR) $(prefix) $(ROOTSBINDIR) @CIFSMOUNT_PROGS@
1612
	@$(SHELL) script/installbin.sh $(INSTALLPERMS) $(DESTDIR) $(prefix) $(ROOTSBINDIR) @CIFSMOUNT_PROGS@
1601
1613
1614
installcifsupcall: @CIFSUPCALL_PROGS@
1615
	@$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS) $(DESTDIR) $(SBINDIR)
1616
	@$(SHELL) script/installbin.sh $(INSTALLPERMS) $(DESTDIR) $(prefix) $(SBINDIR) @CIFSUPCALL_PROGS@
1617
1602
# Some symlinks are required for the 'probing' of modules.
1618
# Some symlinks are required for the 'probing' of modules.
1603
# This mechanism should go at some point..
1619
# This mechanism should go at some point..
1604
installmodules: modules installdirs
1620
installmodules: modules installdirs
Lines 1716-1722 Link Here
1716
	@echo "  swatdir:     $(SWATDIR)"
1732
	@echo "  swatdir:     $(SWATDIR)"
1717
1733
1718
1734
1719
uninstall: uninstallman uninstallservers uninstallbin @UNINSTALL_CIFSMOUNT@ uninstallscripts uninstalldat uninstallswat uninstallmodules @UNINSTALL_LIBSMBCLIENT@ @UNINSTALL_LIBMSRPC@ @UNINSTALL_PAM_MODULES@ @UNINSTALL_LIBSMBSHAREMODES@
1735
uninstall: uninstallman uninstallservers uninstallbin @UNINSTALL_CIFSMOUNT@ @UNINSTALL_CIFSUPCALL@ uninstallscripts uninstalldat uninstallswat uninstallmodules @UNINSTALL_LIBSMBCLIENT@ @UNINSTALL_LIBMSRPC@ @UNINSTALL_PAM_MODULES@ @UNINSTALL_LIBSMBSHAREMODES@
1720
1736
1721
uninstallman:
1737
uninstallman:
1722
	@$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) C
1738
	@$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) C
Lines 1730-1735 Link Here
1730
uninstallcifsmount:
1746
uninstallcifsmount:
1731
	@$(SHELL) script/uninstallbin.sh $(INSTALLPERMS) $(DESTDIR) $(prefix) $(ROOTSBINDIR) @CIFSMOUNT_PROGS@
1747
	@$(SHELL) script/uninstallbin.sh $(INSTALLPERMS) $(DESTDIR) $(prefix) $(ROOTSBINDIR) @CIFSMOUNT_PROGS@
1732
1748
1749
uninstallcifsupcall:
1750
	@$(SHELL) script/uninstallbin.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(SBINDIR) @CIFSUPCALL_PROGS@
1751
1733
uninstallmodules:
1752
uninstallmodules:
1734
	@$(SHELL) $(srcdir)/script/uninstallmodules.sh $(INSTALLPERMS) $(DESTDIR) $(prefix) $(VFSLIBDIR) $(VFS_MODULES)
1753
	@$(SHELL) $(srcdir)/script/uninstallmodules.sh $(INSTALLPERMS) $(DESTDIR) $(prefix) $(VFSLIBDIR) $(VFS_MODULES)
1735
	@$(SHELL) $(srcdir)/script/uninstallmodules.sh $(INSTALLPERMS) $(DESTDIR) $(prefix) $(PDBLIBDIR) $(PDB_MODULES)
1754
	@$(SHELL) $(srcdir)/script/uninstallmodules.sh $(INSTALLPERMS) $(DESTDIR) $(prefix) $(PDBLIBDIR) $(PDB_MODULES)
(-)samba-3.0.28a/source/client/cifs_spnego.h (+46 lines)
Line 0 Link Here
1
/*
2
 *   fs/cifs/cifs_spnego.h -- SPNEGO upcall management for CIFS
3
 *
4
 *   Copyright (c) 2007 Red Hat, Inc.
5
 *   Author(s): Jeff Layton (jlayton@redhat.com)
6
 *              Steve French (sfrench@us.ibm.com)
7
 *
8
 *   This library is free software; you can redistribute it and/or modify
9
 *   it under the terms of the GNU Lesser General Public License as published
10
 *   by the Free Software Foundation; either version 2.1 of the License, or
11
 *   (at your option) any later version.
12
 *
13
 *   This library is distributed in the hope that it will be useful,
14
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16
 *   the GNU Lesser General Public License for more details.
17
 *
18
 *   You should have received a copy of the GNU Lesser General Public License
19
 *   along with this library; if not, write to the Free Software
20
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
 */
22
23
#ifndef _CIFS_SPNEGO_H
24
#define _CIFS_SPNEGO_H
25
26
#define CIFS_SPNEGO_UPCALL_VERSION 2
27
28
/*
29
 * The version field should always be set to CIFS_SPNEGO_UPCALL_VERSION.
30
 * The flags field is for future use. The request-key callout should set
31
 * sesskey_len and secblob_len, and then concatenate the SessKey+SecBlob
32
 * and stuff it in the data field.
33
 */
34
struct cifs_spnego_msg {
35
	uint32_t version;
36
	uint32_t flags;
37
	uint32_t sesskey_len;
38
	uint32_t secblob_len;
39
	uint8_t data[1];
40
};
41
42
#ifdef __KERNEL__
43
extern struct key_type cifs_spnego_key_type;
44
#endif				/* KERNEL */
45
46
#endif				/* _CIFS_SPNEGO_H */
(-)samba-3.0.28a/source/configure.in (+57 lines)
Lines 321-326 Link Here
321
AC_SUBST(CIFSMOUNT_PROGS)
321
AC_SUBST(CIFSMOUNT_PROGS)
322
AC_SUBST(INSTALL_CIFSMOUNT)
322
AC_SUBST(INSTALL_CIFSMOUNT)
323
AC_SUBST(UNINSTALL_CIFSMOUNT)
323
AC_SUBST(UNINSTALL_CIFSMOUNT)
324
AC_SUBST(CIFSUPCALL_PROGS)
325
AC_SUBST(INSTALL_CIFSUPCALL)
326
AC_SUBST(UNINSTALL_CIFSUPCALL)
324
AC_SUBST(EXTRA_SBIN_PROGS)
327
AC_SUBST(EXTRA_SBIN_PROGS)
325
AC_SUBST(EXTRA_ALL_TARGETS)
328
AC_SUBST(EXTRA_ALL_TARGETS)
326
AC_SUBST(CONFIG_LIBS)
329
AC_SUBST(CONFIG_LIBS)
Lines 4242-4247 Link Here
4242
  esac ]
4245
  esac ]
4243
)
4246
)
4244
4247
4248
#################################################
4249
# check for cifs.upcall support
4250
AC_CHECK_HEADERS([keyutils.h], [HAVE_KEYUTILS_H=1], [HAVE_KEYUTILS_H=0])
4251
CIFSUPCALL_PROGS=""
4252
INSTALL_CIFSUPCALL=""
4253
UNINSTALL_CIFSUPCALL=""
4254
AC_MSG_CHECKING(whether to build cifs.upcall)
4255
AC_ARG_WITH(cifsupcall,
4256
[AS_HELP_STRING([--with-cifsupcall], [Include cifs.upcall (Linux only) support (default=yes)])],
4257
[ case "$withval" in
4258
  no)
4259
	AC_MSG_RESULT(no)
4260
	;;
4261
  *)
4262
	case "$host_os" in
4263
	*linux*)
4264
		if test x"$use_ads" != x"yes"; then
4265
			AC_MSG_ERROR(ADS support should be enabled for building cifs.upcall)
4266
		elif test x"$HAVE_KEYUTILS_H" != "x1"; then
4267
			AC_MSG_ERROR(keyutils package is required for cifs.upcall)
4268
		else
4269
			AC_MSG_RESULT(yes)
4270
			AC_DEFINE(WITH_CIFSUPCALL,1,[whether to build cifs.upcall])
4271
			CIFSUPCALL_PROGS="bin/cifs.upcall"
4272
			INSTALL_CIFSUPCALL="installcifsupcall"
4273
			UNINSTALL_CIFSUPCALL="uninstallcifsupcall"
4274
		fi
4275
		;;
4276
	*)
4277
		AC_MSG_ERROR(not on a linux system!)
4278
		;;
4279
	esac
4280
    ;;
4281
  esac ],
4282
[ case "$host_os" in
4283
  *linux*)
4284
        if test x"$use_ads" != x"yes"; then
4285
                AC_MSG_WARN(ADS support should be enabled for building cifs.upcall)
4286
        elif test x"$HAVE_KEYUTILS_H" != "x1"; then
4287
                AC_MSG_WARN(keyutils package is required for cifs.upcall)
4288
        else
4289
                AC_MSG_RESULT(yes)
4290
                AC_DEFINE(WITH_CIFSUPCALL,1,[whether to build cifs.upcall])
4291
                CIFSUPCALL_PROGS="bin/cifs.upcall"
4292
                INSTALL_CIFSUPCALL="installcifsupcall"
4293
                UNINSTALL_CIFSUPCALL="uninstallcifsupcall"
4294
        fi
4295
        ;;
4296
  *)
4297
        AC_MSG_RESULT(no)
4298
        ;;
4299
  esac ]
4300
)
4301
4245
4302
4246
#################################################
4303
#################################################
4247
# check for a PAM clear-text auth, accounts, password and session support
4304
# check for a PAM clear-text auth, accounts, password and session support
(-)samba-3.0.28a/source/include/smb.h (+2 lines)
Lines 558-563 Link Here
558
	void (*free)(struct data_blob_ *data_blob);
558
	void (*free)(struct data_blob_ *data_blob);
559
} DATA_BLOB;
559
} DATA_BLOB;
560
560
561
extern const DATA_BLOB data_blob_null;
562
561
/*
563
/*
562
 * Structure used to keep directory state information around.
564
 * Structure used to keep directory state information around.
563
 * Used in NT change-notify code.
565
 * Used in NT change-notify code.
(-)samba-3.0.28a/source/lib/data_blob.c (+2 lines)
Lines 21-26 Link Here
21
21
22
#include "includes.h"
22
#include "includes.h"
23
23
24
const DATA_BLOB data_blob_null = { NULL, 0, NULL };
25
24
/*******************************************************************
26
/*******************************************************************
25
 Free() a data blob.
27
 Free() a data blob.
26
*******************************************************************/
28
*******************************************************************/
(-)samba-3.0.28a/source/client/cifs.upcall.c (+391 lines)
Line 0 Link Here
1
/*
2
* CIFS user-space helper.
3
* Copyright (C) Igor Mammedov (niallain@gmail.com) 2007
4
*
5
* Used by /sbin/request-key for handling
6
* cifs upcall for kerberos authorization of access to share and
7
* cifs upcall for DFS srver name resolving (IPv4/IPv6 aware).
8
* You should have keyutils installed and add something like the
9
* following lines to /etc/request-key.conf file:
10
11
create cifs.spnego * * /usr/local/sbin/cifs.upcall %k
12
create dns_resolver * * /usr/local/sbin/cifs.upcall %k
13
14
* This program is free software; you can redistribute it and/or modify
15
* it under the terms of the GNU General Public License as published by
16
* the Free Software Foundation; either version 2 of the License, or
17
* (at your option) any later version.
18
* This program is distributed in the hope that it will be useful,
19
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
* GNU General Public License for more details.
22
* You should have received a copy of the GNU General Public License
23
* along with this program; if not, write to the Free Software
24
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
*/
26
27
#include "includes.h"
28
#include <keyutils.h>
29
30
#include "cifs_spnego.h"
31
32
const char *CIFSSPNEGO_VERSION = "1.2";
33
static const char *prog = "cifs.upcall";
34
typedef enum _secType {
35
	NONE = 0,
36
	KRB5,
37
	MS_KRB5
38
} secType_t;
39
40
/*
41
 * Prepares AP-REQ data for mechToken and gets session key
42
 * Uses credentials from cache. It will not ask for password
43
 * you should receive credentials for yuor name manually using
44
 * kinit or whatever you wish.
45
 *
46
 * in:
47
 * 	oid -		string with OID/ Could be OID_KERBEROS5
48
 * 			or OID_KERBEROS5_OLD
49
 * 	principal -	Service name.
50
 * 			Could be "cifs/FQDN" for KRB5 OID
51
 * 			or for MS_KRB5 OID style server principal
52
 * 			like "pdc$@YOUR.REALM.NAME"
53
 *
54
 * out:
55
 * 	secblob -	pointer for spnego wrapped AP-REQ data to be stored
56
 * 	sess_key-	pointer for SessionKey data to be stored
57
 *
58
 * ret: 0 - success, others - failure
59
*/
60
static int
61
handle_krb5_mech(const char *oid, const char *principal,
62
		     DATA_BLOB * secblob, DATA_BLOB * sess_key)
63
{
64
	int retval;
65
	DATA_BLOB tkt, tkt_wrapped;
66
67
	/* get a kerberos ticket for the service and extract the session key */
68
	retval = cli_krb5_get_ticket(principal, 0,
69
				     &tkt, sess_key, 0, NULL, NULL);
70
71
	if (retval)
72
		return retval;
73
74
	/* wrap that up in a nice GSS-API wrapping */
75
	tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
76
77
	/* and wrap that in a shiny SPNEGO wrapper */
78
	*secblob = gen_negTokenInit(oid, tkt_wrapped);
79
80
	data_blob_free(&tkt_wrapped);
81
	data_blob_free(&tkt);
82
	return retval;
83
}
84
85
#define DKD_HAVE_HOSTNAME	1
86
#define DKD_HAVE_VERSION	2
87
#define DKD_HAVE_SEC		4
88
#define DKD_HAVE_IPV4		8
89
#define DKD_HAVE_IPV6		16
90
#define DKD_HAVE_UID		32
91
#define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC)
92
93
static int
94
decode_key_description(const char *desc, int *ver, secType_t * sec,
95
			   char **hostname, uid_t * uid)
96
{
97
	int retval = 0;
98
	char *pos;
99
	const char *tkn = desc;
100
101
	do {
102
		pos = index(tkn, ';');
103
		if (strncmp(tkn, "host=", 5) == 0) {
104
			int len;
105
106
			if (pos == NULL) {
107
				len = strlen(tkn);
108
			} else {
109
				len = pos - tkn;
110
			}
111
			len -= 4;
112
			SAFE_FREE(*hostname);
113
			*hostname = SMB_XMALLOC_ARRAY(char, len);
114
			strlcpy(*hostname, tkn + 5, len);
115
			retval |= DKD_HAVE_HOSTNAME;
116
		} else if (strncmp(tkn, "ipv4=", 5) == 0) {
117
			/* BB: do we need it if we have hostname already? */
118
		} else if (strncmp(tkn, "ipv6=", 5) == 0) {
119
			/* BB: do we need it if we have hostname already? */
120
		} else if (strncmp(tkn, "sec=", 4) == 0) {
121
			if (strncmp(tkn + 4, "krb5", 4) == 0) {
122
				retval |= DKD_HAVE_SEC;
123
				*sec = KRB5;
124
			} else if (strncmp(tkn + 4, "mskrb5", 6) == 0) {
125
				retval |= DKD_HAVE_SEC;
126
				*sec = MS_KRB5;
127
			}
128
		} else if (strncmp(tkn, "uid=", 4) == 0) {
129
			errno = 0;
130
			*uid = strtol(tkn + 4, NULL, 16);
131
			if (errno != 0) {
132
				syslog(LOG_WARNING, "Invalid uid format: %s",
133
				       strerror(errno));
134
				return 1;
135
			} else {
136
				retval |= DKD_HAVE_UID;
137
			}
138
		} else if (strncmp(tkn, "ver=", 4) == 0) {	/* if version */
139
			errno = 0;
140
			*ver = strtol(tkn + 4, NULL, 16);
141
			if (errno != 0) {
142
				syslog(LOG_WARNING,
143
				       "Invalid version format: %s",
144
				       strerror(errno));
145
				return 1;
146
			} else {
147
				retval |= DKD_HAVE_VERSION;
148
			}
149
		}
150
		if (pos == NULL)
151
			break;
152
		tkn = pos + 1;
153
	} while (tkn);
154
	return retval;
155
}
156
157
static int
158
cifs_resolver(const key_serial_t key, const char *key_descr)
159
{
160
	int c;
161
	struct addrinfo *addr;
162
	char ip[INET6_ADDRSTRLEN];
163
	void *p;
164
	const char *keyend = key_descr;
165
	/* skip next 4 ';' delimiters to get to description */
166
	for (c = 1; c <= 4; c++) {
167
		keyend = index(keyend+1, ';');
168
		if (!keyend) {
169
			syslog(LOG_WARNING, "invalid key description: %s",
170
					key_descr);
171
			return 1;
172
		}
173
	}
174
	keyend++;
175
176
	/* resolve name to ip */
177
	c = getaddrinfo(keyend, NULL, NULL, &addr);
178
	if (c) {
179
		syslog(LOG_WARNING, "unable to resolve hostname: %s [%s]",
180
				keyend, gai_strerror(c));
181
		return 1;
182
	}
183
184
	/* conver ip to string form */
185
	if (addr->ai_family == AF_INET) {
186
		p = &(((struct sockaddr_in *)addr->ai_addr)->sin_addr);
187
	} else {
188
		p = &(((struct sockaddr_in6 *)addr->ai_addr)->sin6_addr);
189
	}
190
	if (!inet_ntop(addr->ai_family, p, ip, sizeof(ip))) {
191
		syslog(LOG_WARNING, "%s: inet_ntop: %s",
192
				__FUNCTION__, strerror(errno));
193
		freeaddrinfo(addr);
194
		return 1;
195
	}
196
197
	/* setup key */
198
	c = keyctl_instantiate(key, ip, strlen(ip)+1, 0);
199
	if (c == -1) {
200
		syslog(LOG_WARNING, "%s: keyctl_instantiate: %s",
201
				__FUNCTION__, strerror(errno));
202
		freeaddrinfo(addr);
203
		return 1;
204
	}
205
206
	freeaddrinfo(addr);
207
	return 0;
208
}
209
210
static void
211
usage(void)
212
{
213
	syslog(LOG_WARNING, "Usage: %s [-c] [-v] key_serial", prog);
214
	fprintf(stderr, "Usage: %s [-c] [-v] key_serial\n", prog);
215
}
216
217
int main(const int argc, char *const argv[])
218
{
219
	struct cifs_spnego_msg *keydata = NULL;
220
	DATA_BLOB secblob = data_blob_null;
221
	DATA_BLOB sess_key = data_blob_null;
222
	secType_t sectype = NONE;
223
	key_serial_t key = 0;
224
	size_t datalen;
225
	long rc = 1;
226
	uid_t uid = 0;
227
	int kernel_upcall_version = 0;
228
	int c, use_cifs_service_prefix = 0;
229
	char *buf, *hostname = NULL;
230
	const char *oid;
231
232
	openlog(prog, 0, LOG_DAEMON);
233
234
	while ((c = getopt(argc, argv, "cv")) != -1) {
235
		switch (c) {
236
		case 'c':{
237
			use_cifs_service_prefix = 1;
238
			break;
239
			}
240
		case 'v':{
241
			printf("version: %s\n", CIFSSPNEGO_VERSION);
242
			goto out;
243
			}
244
		default:{
245
			syslog(LOG_WARNING, "unknown option: %c", c);
246
			goto out;
247
			}
248
		}
249
	}
250
251
	/* is there a key? */
252
	if (argc <= optind) {
253
		usage();
254
		goto out;
255
	}
256
257
	/* get key and keyring values */
258
	errno = 0;
259
	key = strtol(argv[optind], NULL, 10);
260
	if (errno != 0) {
261
		key = 0;
262
		syslog(LOG_WARNING, "Invalid key format: %s", strerror(errno));
263
		goto out;
264
	}
265
266
	rc = keyctl_describe_alloc(key, &buf);
267
	if (rc == -1) {
268
		syslog(LOG_WARNING, "keyctl_describe_alloc failed: %s",
269
		       strerror(errno));
270
		rc = 1;
271
		goto out;
272
	}
273
274
	if ((strncmp(buf, "cifs.resolver", sizeof("cifs.resolver")-1) == 0) ||
275
	    (strncmp(buf, "dns_resolver", sizeof("dns_resolver")-1) == 0)) {
276
		rc = cifs_resolver(key, buf);
277
		goto out;
278
	}
279
280
	rc = decode_key_description(buf, &kernel_upcall_version, &sectype,
281
				    &hostname, &uid);
282
	if ((rc & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {
283
		syslog(LOG_WARNING,
284
		       "unable to get from description necessary params");
285
		rc = 1;
286
		SAFE_FREE(buf);
287
		goto out;
288
	}
289
	SAFE_FREE(buf);
290
291
	if (kernel_upcall_version > CIFS_SPNEGO_UPCALL_VERSION) {
292
		syslog(LOG_WARNING,
293
		       "incompatible kernel upcall version: 0x%x",
294
		       kernel_upcall_version);
295
		rc = 1;
296
		goto out;
297
	}
298
299
	if (rc & DKD_HAVE_UID) {
300
		rc = setuid(uid);
301
		if (rc == -1) {
302
			syslog(LOG_WARNING, "setuid: %s", strerror(errno));
303
			goto out;
304
		}
305
	}
306
307
	/* BB: someday upcall SPNEGO blob could be checked here to decide
308
	 * what mech to use */
309
310
	// do mech specific authorization
311
	switch (sectype) {
312
	case MS_KRB5:
313
	case KRB5:{
314
			char *princ;
315
			size_t len;
316
317
			/* for "cifs/" service name + terminating 0 */
318
			len = strlen(hostname) + 5 + 1;
319
			princ = SMB_XMALLOC_ARRAY(char, len);
320
			if (!princ) {
321
				rc = 1;
322
				break;
323
			}
324
			if (use_cifs_service_prefix) {
325
				strlcpy(princ, "cifs/", len);
326
			} else {
327
				strlcpy(princ, "host/", len);
328
			}
329
			strlcpy(princ + 5, hostname, len - 5);
330
331
			if (sectype == MS_KRB5)
332
				oid = OID_KERBEROS5_OLD;
333
			else
334
				oid = OID_KERBEROS5;
335
336
			rc = handle_krb5_mech(oid, princ, &secblob, &sess_key);
337
			SAFE_FREE(princ);
338
			break;
339
		}
340
	default:{
341
			syslog(LOG_WARNING, "sectype: %d is not implemented",
342
			       sectype);
343
			rc = 1;
344
			break;
345
		}
346
	}
347
348
	if (rc) {
349
		goto out;
350
	}
351
352
	/* pack SecurityBLob and SessionKey into downcall packet */
353
	datalen =
354
	    sizeof(struct cifs_spnego_msg) + secblob.length + sess_key.length;
355
	keydata = (struct cifs_spnego_msg*)SMB_XMALLOC_ARRAY(char, datalen);
356
	if (!keydata) {
357
		rc = 1;
358
		goto out;
359
	}
360
	keydata->version = kernel_upcall_version;
361
	keydata->flags = 0;
362
	keydata->sesskey_len = sess_key.length;
363
	keydata->secblob_len = secblob.length;
364
	memcpy(&(keydata->data), sess_key.data, sess_key.length);
365
	memcpy(&(keydata->data) + keydata->sesskey_len,
366
	       secblob.data, secblob.length);
367
368
	/* setup key */
369
	rc = keyctl_instantiate(key, keydata, datalen, 0);
370
	if (rc == -1) {
371
		syslog(LOG_WARNING, "keyctl_instantiate: %s", strerror(errno));
372
		goto out;
373
	}
374
375
	/* BB: maybe we need use timeout for key: for example no more then
376
	 * ticket lifietime? */
377
	/* keyctl_set_timeout( key, 60); */
378
out:
379
	/*
380
	 * on error, negatively instantiate the key ourselves so that we can
381
	 * make sure the kernel doesn't hang it off of a searchable keyring
382
	 * and interfere with the next attempt to instantiate the key.
383
	 */
384
	if (rc != 0  && key == 0)
385
		keyctl_negate(key, 1, KEY_REQKEY_DEFL_DEFAULT);
386
	data_blob_free(&secblob);
387
	data_blob_free(&sess_key);
388
	SAFE_FREE(hostname);
389
	SAFE_FREE(keydata);
390
	return rc;
391
}
(-)samba-3.0.28a/docs/manpages/cifs.upcall.8 (+82 lines)
Line 0 Link Here
1
.\"     Title: cifs.upcall
2
.\"    Author: 
3
.\" Generator: DocBook XSL Stylesheets v1.73.1 <http://docbook.sf.net/>
4
.\"      Date: 09/18/2008
5
.\"    Manual: System Administration tools
6
.\"    Source: Samba 3.2
7
.\"
8
.TH "CIFS\.UPCALL" "8" "09/18/2008" "Samba 3\.2" "System Administration tools"
9
.\" disable hyphenation
10
.nh
11
.\" disable justification (adjust text to left margin only)
12
.ad l
13
.SH "NAME"
14
cifs.upcall - Userspace upcall helper for Common Internet File System (CIFS)
15
.SH "SYNOPSIS"
16
.HP 1
17
cifs\.upcall [\-c] [\-v] {keyid}
18
.SH "DESCRIPTION"
19
.PP
20
This tool is part of the
21
\fBsamba\fR(7)
22
suite\.
23
.PP
24
cifs\.upcall is a userspace helper program for the linux CIFS client filesystem\. There are a number of activities that the kernel cannot easily do itself\. This program is a callout program that does these things for the kernel and then returns the result\.
25
.PP
26
cifs\.upcall is generally intended to be run when the kernel calls request\-key(8)
27
for a particular key type\. While it can be run directly from the command\-line, it\'s not generally intended to be run that way\.
28
.SH "OPTIONS"
29
.PP
30
\-c
31
.RS 4
32
When handling a kerberos upcall, use a service principal that starts with "cifs/"\. The default is to use the "host/" service principal\.
33
.RE
34
.PP
35
\-v
36
.RS 4
37
Print version number and exit\.
38
.RE
39
.SH "CONFIGURATION FOR KEYCTL"
40
.PP
41
cifs\.upcall is designed to be called from the kernel via the request\-key callout program\. This requires that request\-key be told where and how to call this program\. The current cifs\.upcall program handles two different key types:
42
.PP
43
cifs\.spnego
44
.RS 4
45
This keytype is for retrieving kerberos session keys
46
.RE
47
.PP
48
dns_resolver
49
.RS 4
50
This key type is for resolving hostnames into IP addresses
51
.RE
52
.PP
53
To make this program useful for CIFS, you\'ll need to set up entries for them in request\-key\.conf(5)\. Here\'s an example of an entry for each key type:
54
.sp
55
.RS 4
56
.nf
57
#OPERATION  TYPE           D C PROGRAM ARG1 ARG2\.\.\.
58
#=========  =============  = = ==========================================
59
create	    cifs\.spnego    * * /usr/local/sbin/cifs\.upcall \-c %k
60
create      dns_resolver   * * /usr/local/sbin/cifs\.upcall %k
61
.fi
62
.RE
63
.PP
64
See
65
\fBrequest-key.conf5\fR()
66
for more info on each field\.
67
.SH "SEE ALSO"
68
.PP
69
70
\fBrequest-key.conf\fR(5),
71
\fBmount.cifs\fR(8)
72
.SH "AUTHOR"
73
.PP
74
Igor Mammedov wrote the cifs\.upcall program\.
75
.PP
76
Jeff Layton authored this manpage\.
77
.PP
78
The maintainer of the Linux CIFS VFS is Steve French\.
79
.PP
80
The
81
Linux CIFS Mailing list
82
is the preferred place to ask questions regarding these programs\.

Return to bug 19199