1: This patch adds a kerberos authentication method to daemon mode.
2:
3: NOTE: minimally munged to work with 3.1.1, but as yet untested!
4:
5: To use this patch, run these commands for a successful build:
6:
7: patch -p1 <patches/kerberos.diff
8: ./prepare-source
9: ./configure
10: make
11:
12: based-on: e94bad1c156fc3910f24e2b3b71a81b0b0bdeb70
13: diff --git a/Makefile.in b/Makefile.in
14: --- a/Makefile.in
15: +++ b/Makefile.in
16: @@ -44,7 +44,7 @@ OBJS1=flist.o rsync.o generator.o receiver.o cleanup.o sender.o exclude.o \
17: util.o util2.o main.o checksum.o match.o syscall.o log.o backup.o delete.o
18: OBJS2=options.o io.o compat.o hlink.o token.o uidlist.o socket.o hashtable.o \
19: usage.o fileio.o batch.o clientname.o chmod.o acls.o xattrs.o
20: -OBJS3=progress.o pipe.o @ASM@
21: +OBJS3=progress.o pipe.o gss-auth.o @ASM@
22: DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
23: popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
24: popt/popthelp.o popt/poptparse.o
25: diff --git a/clientserver.c b/clientserver.c
26: --- a/clientserver.c
27: +++ b/clientserver.c
28: @@ -140,7 +140,7 @@ int start_socket_client(char *host, int remote_argc, char *remote_argv[],
29: setup_iconv();
30: #endif
31:
32: - ret = start_inband_exchange(fd, fd, user, remote_argc, remote_argv);
33: + ret = start_inband_exchange(fd, fd, user, host, remote_argc, remote_argv);
34:
35: return ret ? ret : client_run(fd, fd, -1, argc, argv);
36: }
37: @@ -217,7 +217,7 @@ static int exchange_protocols(int f_in, int f_out, char *buf, size_t bufsiz, int
38: return 0;
39: }
40:
41: -int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char *argv[])
42: +int start_inband_exchange(int f_in, int f_out, const char *user, const char *host, int argc, char *argv[])
43: {
44: int i, modlen;
45: char line[BIGPATHBUFLEN];
46: @@ -328,6 +328,17 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
47: continue;
48: }
49:
50: + if (strcmp(line, "@RSYNCD: GSS") == 0) {
51: +#ifdef GSSAPI_OPTION
52: + if (auth_gss_client(f_out, host) < 0)
53: + return -1;
54: + continue;
55: +#else
56: + rprintf(FERROR, "GSSAPI is not supported\n");
57: + return -1;
58: +#endif
59: + }
60: +
61: if (strcmp(line,"@RSYNCD: OK") == 0)
62: break;
63:
64: @@ -685,7 +696,12 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
65: }
66:
67: read_only = lp_read_only(i); /* may also be overridden by auth_server() */
68: - auth_user = auth_server(f_in, f_out, i, host, addr, "@RSYNCD: AUTHREQD ");
69: +#ifdef GSSAPI_OPTION
70: + if (lp_use_gssapi(i))
71: + auth_user = auth_gss_server(f_in, f_out, i, host, addr, "@RSYNCD: GSS");
72: + else
73: +#endif
74: + auth_user = auth_server(f_in, f_out, i, host, addr, "@RSYNCD: AUTHREQD ");
75:
76: if (!auth_user) {
77: io_printf(f_out, "@ERROR: auth failed on module %s\n", name);
78: diff --git a/configure.ac b/configure.ac
79: --- a/configure.ac
80: +++ b/configure.ac
81: @@ -950,6 +950,31 @@ if test x"$enable_iconv" != x"no"; then
82: AC_DEFINE(UTF8_CHARSET, "UTF-8", [String to pass to iconv() for the UTF-8 charset.])
83: fi
84:
85: +AC_ARG_WITH([gssapi],
86: + [AS_HELP_STRING([--with-gssapi],
87: + [support GSSAPI authentication @<:@default=check@:>@])],
88: + [],
89: + [with_gssapi=check])
90: +
91: +AH_TEMPLATE([GSSAPI_OPTION],
92: +[Define if you want GSSAPI authentication. Specifing a value will set the search path.])
93: +
94: +AS_IF([test "x$with_gssapi" != xno],
95: + [AC_SEARCH_LIBS([gss_import_name], gss gssapi_krb5 ,
96: + [AC_CHECK_HEADERS(gssapi/gssapi_generic.h gssapi/gssapi.h) ]
97: + [ AC_DEFINE([GSSAPI_OPTION], [1]) ]
98: + ,
99: + [if test "x$with_gssapi" = xcheck; then
100: + AC_MSG_FAILURE(
101: + [--with-gssapi was given, but test for function failed])
102: + fi
103: + ])
104: + ])
105: +
106: +if test x"$enable_gssapi" != x"no"; then
107: + AC_DEFINE(GSSAPI_OPTION, 1)
108: +fi
109: +
110: AC_CACHE_CHECK([whether chown() modifies symlinks],rsync_cv_chown_modifies_symlink,[
111: AC_RUN_IFELSE([AC_LANG_SOURCE([[
112: #if HAVE_UNISTD_H
113: diff --git a/daemon-parm.txt b/daemon-parm.txt
114: --- a/daemon-parm.txt
115: +++ b/daemon-parm.txt
116: @@ -61,6 +61,7 @@ BOOL reverse_lookup True
117: BOOL strict_modes True
118: BOOL transfer_logging False
119: BOOL use_chroot True
120: +BOOL use_gssapi False
121: BOOL write_only False
122:
123: BOOL3 munge_symlinks Unset
124: diff --git a/gss-auth.c b/gss-auth.c
125: new file mode 100644
126: --- /dev/null
127: +++ b/gss-auth.c
128: @@ -0,0 +1,334 @@
129: +/*
130: + * GSSAPI authentication.
131: + *
132: + * Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
133: + * Copyright (C) 2001-2002 Martin Pool <mbp@samba.org>
134: + * Copyright (C) 2002-2008 Wayne Davison
135: + *
136: + * This program is free software; you can redistribute it and/or modify
137: + * it under the terms of the GNU General Public License as published by
138: + * the Free Software Foundation; either version 3 of the License, or
139: + * (at your option) any later version.
140: + *
141: + * This program is distributed in the hope that it will be useful,
142: + * but WITHOUT ANY WARRANTY; without even the implied warranty of
143: + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
144: + * GNU General Public License for more details.
145: + *
146: + * You should have received a copy of the GNU General Public License along
147: + * with this program; if not, visit the http://fsf.org website.
148: + */
149: +
150: +#include "rsync.h"
151: +
152: +#ifdef GSSAPI_OPTION
153: +
154: +#define RSYNC_GSS_SERVICE "host"
155: +
156: +struct init_context_data {
157: + gss_cred_id_t initiator_cred_handle;
158: + gss_ctx_id_t *context_handle;
159: + gss_name_t target_name;
160: + gss_OID mech_type;
161: + OM_uint32 req_flags;
162: + OM_uint32 time_req;
163: + gss_channel_bindings_t input_chan_bindings;
164: + gss_OID *actual_mech_type;
165: + OM_uint32 *ret_flags;
166: + OM_uint32 *time_rec;
167: +};
168: +
169: +struct accept_context_data {
170: + gss_ctx_id_t *context_handle;
171: + gss_cred_id_t acceptor_cred_handle;
172: + gss_channel_bindings_t input_chan_bindings;
173: + gss_name_t *src_name;
174: + gss_OID *mech_type;
175: + OM_uint32 *ret_flags;
176: + OM_uint32 *time_rec;
177: + gss_cred_id_t *delegated_cred_handle;
178: +};
179: +
180: +int auth_gss_client(int fd, const char *host)
181: +{
182: + gss_ctx_id_t ctxt = GSS_C_NO_CONTEXT;
183: + gss_name_t target_name = GSS_C_NO_NAME;
184: + struct init_context_data cb_data;
185: + char *buffer;
186: + int status;
187: + OM_uint32 min_stat;
188: +
189: + buffer = new_array(char, (strlen(host) + 2 + strlen(RSYNC_GSS_SERVICE)));
190: +
191: + sprintf(buffer, "%s@%s", RSYNC_GSS_SERVICE, host);
192: +
193: + import_gss_name(&target_name, buffer, GSS_C_NT_HOSTBASED_SERVICE);
194: + free(buffer);
195: +
196: + cb_data.initiator_cred_handle = GSS_C_NO_CREDENTIAL;
197: + cb_data.context_handle = &ctxt;
198: + cb_data.target_name = target_name;
199: + cb_data.mech_type = GSS_C_NO_OID;
200: + cb_data.req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
201: + cb_data.time_req = 0;
202: + cb_data.input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
203: + cb_data.actual_mech_type = NULL;
204: + cb_data.ret_flags = NULL;
205: + cb_data.time_rec = NULL;
206: +
207: + status = do_gss_dialog(fd, fd, 0, &cb_init_sec_context, (void *)&cb_data);
208: + if (ctxt != GSS_C_NO_CONTEXT)
209: + gss_delete_sec_context(&min_stat, &ctxt, GSS_C_NO_BUFFER);
210: + free_gss_name(&target_name);
211: +
212: + return status;
213: +}
214: +
215: +/*
216: + * The call back function for a gss_init_sec_context dialog
217: + */
218: +OM_uint32 cb_init_sec_context(OM_uint32 *min_statp, gss_buffer_t in_token, gss_buffer_t out_token, void *cb_data)
219: +{
220: + struct init_context_data *context_data;
221: +
222: + context_data = (struct init_context_data *) cb_data;
223: + return gss_init_sec_context(min_statp, context_data->initiator_cred_handle, context_data->context_handle, context_data->target_name, context_data->mech_type, context_data->req_flags, context_data->time_req, context_data->input_chan_bindings, in_token, context_data->actual_mech_type, out_token, context_data->ret_flags, context_data->time_rec);
224: +}
225: +
226: +/* Possibly negotiate authentication with the client. Use "leader" to
227: + * start off the auth if necessary.
228: + *
229: + * Return NULL if authentication failed. Return "" if anonymous access.
230: + * Otherwise return username.
231: + */
232: +char *auth_gss_server(int fd_in, int fd_out, int module, const char *host, const char *addr, const char *leader)
233: +{
234: + struct accept_context_data cb_data;
235: + gss_cred_id_t server_creds = GSS_C_NO_CREDENTIAL;
236: + gss_ctx_id_t context = GSS_C_NO_CONTEXT;
237: + OM_uint32 ret_flags;
238: + char *users = lp_auth_users(module);
239: + OM_uint32 maj_stat, min_stat;
240: + gss_name_t server_name = GSS_C_NO_NAME;
241: + gss_name_t client_name = GSS_C_NO_NAME;
242: + gss_OID doid = GSS_C_NO_OID;
243: + char *user = NULL;
244: +
245: + /* if no auth list then allow anyone in! */
246: + if (!users || !*users)
247: + return "";
248: +
249: + import_gss_name(&server_name, "host", GSS_C_NT_HOSTBASED_SERVICE);
250: +
251: + maj_stat = gss_acquire_cred(&min_stat, server_name, GSS_C_INDEFINITE, GSS_C_NULL_OID_SET, GSS_C_ACCEPT, &server_creds, NULL, NULL);
252: + if (maj_stat != GSS_S_COMPLETE) {
253: + error_gss(maj_stat, min_stat, "error acquiring credentials on module %s from %s (%s)", lp_name(module), host, addr);
254: + return NULL;
255: + }
256: +
257: + io_printf(fd_out, "%s\n", leader);
258: +
259: + cb_data.context_handle = &context;
260: + cb_data.acceptor_cred_handle = server_creds;
261: + cb_data.input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
262: + cb_data.src_name = &client_name;
263: + cb_data.mech_type = &doid;
264: + cb_data.ret_flags = &ret_flags;
265: + cb_data.time_rec = NULL;
266: + cb_data.delegated_cred_handle = NULL;
267: +
268: + if (do_gss_dialog(fd_in, fd_out, -1, &cb_accept_sec_context, (void *)&cb_data) < 0)
269: + return NULL;
270: +
271: + user = get_cn(client_name, doid);
272: +
273: + free_gss_name(&server_name);
274: + free_gss_name(&client_name);
275: +
276: + return user;
277: +}
278: +
279: +/*
280: + * The call back function for a gss_accept_sec_context dialog
281: + */
282: +OM_uint32 cb_accept_sec_context(OM_uint32 *min_statp, gss_buffer_t in_token, gss_buffer_t out_token, void *cb_data)
283: +{
284: + struct accept_context_data *context_data;
285: +
286: + context_data = (struct accept_context_data *) cb_data;
287: + return gss_accept_sec_context(min_statp, context_data->context_handle, context_data->acceptor_cred_handle, in_token, context_data->input_chan_bindings, context_data->src_name, context_data->mech_type, out_token, context_data->ret_flags, context_data->time_rec, context_data->delegated_cred_handle);
288: +}
289: +
290: +void free_gss_buffer(gss_buffer_t gss_buffer)
291: +{
292: + OM_uint32 maj_stat, min_stat;
293: +
294: + if (gss_buffer->length > 0) {
295: + maj_stat = gss_release_buffer(&min_stat, gss_buffer);
296: + if (maj_stat != GSS_S_COMPLETE) {
297: + error_gss(maj_stat, min_stat, "can't release a buffer");
298: + }
299: + }
300: +}
301: +
302: +void free_gss_name(gss_name_t *gss_buffer)
303: +{
304: + OM_uint32 maj_stat, min_stat;
305: +
306: + if (*gss_buffer != GSS_C_NO_NAME) {
307: + maj_stat = gss_release_name(&min_stat, gss_buffer);
308: + if (maj_stat != GSS_S_COMPLETE) {
309: + error_gss(maj_stat, min_stat, "can't release a name");
310: + }
311: + }
312: +}
313: +
314: +void import_gss_name(gss_name_t *gss_name, const char *name, gss_OID type)
315: +{
316: + gss_buffer_desc gssname;
317: + OM_uint32 maj_stat, min_stat;
318: +
319: + gssname.value = strdup(name);
320: + gssname.length = strlen(name) +1 ;
321: +
322: + maj_stat = gss_import_name(&min_stat, &gssname, type, gss_name);
323: +
324: + if (maj_stat != GSS_S_COMPLETE)
325: + error_gss(maj_stat, min_stat, "can't resolve %s", name);
326: +
327: + free_gss_buffer(&gssname);
328: +}
329: +
330: +char *export_name(const gss_name_t input_name)
331: +{
332: + OM_uint32 maj_stat, min_stat;
333: + gss_buffer_desc exported_name;
334: + char *exported;
335: + gss_OID name_oid;
336: +
337: + exported = NULL;
338: +
339: + maj_stat = gss_display_name(&min_stat, input_name, &exported_name, &name_oid);
340: + if (maj_stat != GSS_S_COMPLETE) {
341: + error_gss(maj_stat, min_stat, "can't get display name");
342: + return NULL;
343: + }
344: +
345: + if (exported_name.length > 0)
346: + exported = strdup(exported_name.value);
347: +
348: + free_gss_buffer(&exported_name);
349: +
350: + return exported;
351: +}
352: +
353: +void error_gss(OM_uint32 major, OM_uint32 minor, const char *format, ...)
354: +{
355: + OM_uint32 min_stat;
356: + gss_buffer_desc gss_msg = GSS_C_EMPTY_BUFFER;
357: + OM_uint32 msg_ctx;
358: + va_list ap;
359: + char message[BIGPATHBUFLEN];
360: +
361: + va_start(ap, format);
362: + vsnprintf(message, sizeof message, format, ap);
363: + va_end(ap);
364: +
365: + msg_ctx = 0;
366: + if (major != GSS_S_FAILURE) /* Don't print unspecified failure, the message is useless */
367: + do {
368: + gss_display_status(&min_stat, major, GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &gss_msg);
369: + rprintf(FERROR, "GSS-API error: %s: %s\n", message, (char *) gss_msg.value);
370: + free_gss_buffer(&gss_msg);
371: + } while (msg_ctx != 0);
372: +
373: + if (minor != 0) {
374: + do {
375: + gss_display_status(&min_stat, minor, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &gss_msg);
376: + rprintf(FERROR, "GSS-API error: %s: %s\n",message, (char *) gss_msg.value);
377: + free_gss_buffer(&gss_msg);
378: + } while (msg_ctx != 0);
379: + }
380: +}
381: +
382: +/*
383: + * This function manage a gss dialog
384: + * gss tokens are eaten by a call-back function and then send by this function.
385: + * Argument to this function can be passed throught the cb_data argument
386: + * When told to act as a server, it just begin to wait for a first token before beginning operation
387: + * on it
388: + */
389: +int do_gss_dialog(int fd_in, int fd_out, int isServer, OM_uint32 (*eat_token)(OM_uint32 *,gss_buffer_t, gss_buffer_t, void *), void *cb_data)
390: +{
391: + OM_uint32 maj_stat, min_stat;
392: + gss_buffer_desc in_token = GSS_C_EMPTY_BUFFER;
393: + gss_buffer_desc out_token = GSS_C_EMPTY_BUFFER;
394: +
395: + if (isServer)
396: + recv_gss_token(fd_in, &in_token);
397: +
398: + do {
399: + maj_stat = (*eat_token)(&min_stat, &in_token, &out_token, cb_data);
400: + free_gss_buffer(&in_token);
401: + if (maj_stat != GSS_S_COMPLETE
402: + && maj_stat != GSS_S_CONTINUE_NEEDED) {
403: + error_gss(maj_stat, min_stat, "error during dialog");
404: + return -1;
405: + }
406: +
407: + if (out_token.length != 0) {
408: + send_gss_token(fd_out, &out_token);
409: + }
410: + free_gss_buffer(&out_token);
411: +
412: + if (maj_stat == GSS_S_CONTINUE_NEEDED) {
413: + recv_gss_token(fd_in, &in_token);
414: + }
415: + } while (maj_stat == GSS_S_CONTINUE_NEEDED);
416: +
417: + return 0;
418: +}
419: +
420: +char *get_cn(const gss_name_t input_name, const gss_OID mech_type)
421: +{
422: + OM_uint32 maj_stat, min_stat;
423: + gss_name_t output_name;
424: + gss_buffer_desc exported_name;
425: + char *cn;
426: +
427: + cn = NULL;
428: + maj_stat = gss_canonicalize_name(&min_stat, input_name, mech_type, &output_name);
429: + if (maj_stat != GSS_S_COMPLETE) {
430: + error_gss(maj_stat, min_stat, "canonizing name");
431: + return NULL;
432: + }
433: +
434: + maj_stat = gss_export_name(&min_stat, output_name, &exported_name);
435: + if (maj_stat != GSS_S_COMPLETE) {
436: + error_gss(maj_stat, min_stat, "canonizing name");
437: + return NULL;
438: + }
439: + if (exported_name.length > 0)
440: + cn = strdup(exported_name.value);
441: +
442: + free_gss_name(&output_name);
443: + free_gss_buffer(&exported_name);
444: +
445: + return cn;
446: +}
447: +
448: +void send_gss_token(int fd, gss_buffer_t token)
449: +{
450: + write_int(fd, token->length);
451: + write_buf(fd, token->value, token->length);
452: +}
453: +
454: +void recv_gss_token(int fd, gss_buffer_t token)
455: +{
456: + token->length = read_int(fd);
457: + if (token->length > 0) {
458: + token->value = new_array(char, token->length);
459: + read_buf(fd, token->value, token->length);
460: + }
461: +}
462: +#endif /* GSSAPI_OPTION */
463: diff --git a/main.c b/main.c
464: --- a/main.c
465: +++ b/main.c
466: @@ -1572,7 +1572,7 @@ static int start_client(int argc, char *argv[])
467: * remote shell command, we need to do the RSYNCD protocol first */
468: if (daemon_connection) {
469: int tmpret;
470: - tmpret = start_inband_exchange(f_in, f_out, shell_user, remote_argc, remote_argv);
471: + tmpret = start_inband_exchange(f_in, f_out, shell_user, shell_machine, remote_argc, remote_argv);
472: if (tmpret < 0)
473: return tmpret;
474: }
475: diff --git a/rsync.h b/rsync.h
476: --- a/rsync.h
477: +++ b/rsync.h
478: @@ -520,6 +520,15 @@ enum delret {
479: #define iconv_t int
480: #endif
481:
482: +#ifdef GSSAPI_OPTION
483: +#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
484: +#include <gssapi/gssapi_generic.h>
485: +#endif
486: +#ifdef HAVE_GSSAPI_GSSAPI_H
487: +#include <gssapi/gssapi.h>
488: +#endif
489: +#endif
490: +
491: #include <assert.h>
492:
493: #include "lib/pool_alloc.h"
494: diff -Nurp a/config.h.in b/config.h.in
495: --- a/config.h.in
496: +++ b/config.h.in
497: @@ -36,6 +36,10 @@
498: /* Define to 1 if the `getpgrp' function requires zero arguments. */
499: #undef GETPGRP_VOID
500:
501: +/* Define if you want GSSAPI authentication. Specifing a value will set the
502: + search path. */
503: +#undef GSSAPI_OPTION
504: +
505: /* Define to 1 if you have the `aclsort' function. */
506: #undef HAVE_ACLSORT
507:
508: @@ -177,6 +181,12 @@
509: /* Define to 1 if you have the <grp.h> header file. */
510: #undef HAVE_GRP_H
511:
512: +/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */
513: +#undef HAVE_GSSAPI_GSSAPI_GENERIC_H
514: +
515: +/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
516: +#undef HAVE_GSSAPI_GSSAPI_H
517: +
518: /* true if you have HPUX ACLs */
519: #undef HAVE_HPUX_ACLS
520:
521: diff -Nurp a/configure.sh b/configure.sh
522: --- a/configure.sh
523: +++ b/configure.sh
524: @@ -731,6 +731,7 @@ enable_zstd
525: enable_lz4
526: enable_iconv_open
527: enable_iconv
528: +with_gssapi
529: enable_acl_support
530: enable_xattr_support
531: '
532: @@ -1402,6 +1403,7 @@ Optional Packages:
533: --with-nobody-group=GROUP
534: set the default unprivileged group (default nobody
535: or nogroup)
536: + --with-gssapi support GSSAPI authentication [default=check]
537:
538: Some influential environment variables:
539: CC C compiler command
540: @@ -9003,6 +9005,105 @@ $as_echo "#define UTF8_CHARSET \"UTF-8\"
541:
542: fi
543:
544: +
545: +# Check whether --with-gssapi was given.
546: +if test "${with_gssapi+set}" = set; then :
547: + withval=$with_gssapi;
548: +else
549: + with_gssapi=check
550: +fi
551: +
552: +
553: +
554: +
555: +if test "x$with_gssapi" != xno; then :
556: + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gss_import_name" >&5
557: +$as_echo_n "checking for library containing gss_import_name... " >&6; }
558: +if ${ac_cv_search_gss_import_name+:} false; then :
559: + $as_echo_n "(cached) " >&6
560: +else
561: + ac_func_search_save_LIBS=$LIBS
562: +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
563: +/* end confdefs.h. */
564: +
565: +/* Override any GCC internal prototype to avoid an error.
566: + Use char because int might match the return type of a GCC
567: + builtin and then its argument prototype would still apply. */
568: +#ifdef __cplusplus
569: +extern "C"
570: +#endif
571: +char gss_import_name ();
572: +int
573: +main ()
574: +{
575: +return gss_import_name ();
576: + ;
577: + return 0;
578: +}
579: +_ACEOF
580: +for ac_lib in '' gss gssapi_krb5 ; do
581: + if test -z "$ac_lib"; then
582: + ac_res="none required"
583: + else
584: + ac_res=-l$ac_lib
585: + LIBS="-l$ac_lib $ac_func_search_save_LIBS"
586: + fi
587: + if ac_fn_c_try_link "$LINENO"; then :
588: + ac_cv_search_gss_import_name=$ac_res
589: +fi
590: +rm -f core conftest.err conftest.$ac_objext \
591: + conftest$ac_exeext
592: + if ${ac_cv_search_gss_import_name+:} false; then :
593: + break
594: +fi
595: +done
596: +if ${ac_cv_search_gss_import_name+:} false; then :
597: +
598: +else
599: + ac_cv_search_gss_import_name=no
600: +fi
601: +rm conftest.$ac_ext
602: +LIBS=$ac_func_search_save_LIBS
603: +fi
604: +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gss_import_name" >&5
605: +$as_echo "$ac_cv_search_gss_import_name" >&6; }
606: +ac_res=$ac_cv_search_gss_import_name
607: +if test "$ac_res" != no; then :
608: + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
609: + for ac_header in gssapi/gssapi_generic.h gssapi/gssapi.h
610: +do :
611: + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
612: +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
613: +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
614: + cat >>confdefs.h <<_ACEOF
615: +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
616: +_ACEOF
617: +
618: +fi
619: +
620: +done
621: +
622: + $as_echo "#define GSSAPI_OPTION 1" >>confdefs.h
623: +
624: +
625: +else
626: + if test "x$with_gssapi" = xcheck; then
627: + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
628: +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
629: +as_fn_error $? "--with-gssapi was given, but test for function failed
630: +See \`config.log' for more details" "$LINENO" 5; }
631: + fi
632: +
633: +fi
634: +
635: +
636: +fi
637: +
638: +if test x"$enable_gssapi" != x"no"; then
639: + $as_echo "#define GSSAPI_OPTION 1" >>confdefs.h
640: +
641: +fi
642: +
643: { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether chown() modifies symlinks" >&5
644: $as_echo_n "checking whether chown() modifies symlinks... " >&6; }
645: if ${rsync_cv_chown_modifies_symlink+:} false; then :
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>