Merge lp:~logan/ubuntu/quantal/nfs-utils/debian-merge into lp:ubuntu/quantal/nfs-utils

Proposed by Logan Rosen
Status: Merged
Merged at revision: 59
Proposed branch: lp:~logan/ubuntu/quantal/nfs-utils/debian-merge
Merge into: lp:ubuntu/quantal/nfs-utils
Diff against target: 4328 lines (+58/-3989)
29 files modified
.pc/.quilt_patches (+1/-0)
.pc/.quilt_series (+1/-0)
.pc/01-sm-notify-in-sbin.patch/utils/statd/statd.c (+0/-493)
.pc/02-524255-manpages.patch/utils/exportfs/nfsd.man (+0/-206)
.pc/02-524255-manpages.patch/utils/nfsd/nfsd.man (+0/-105)
.pc/03-handle-mtab-symlink.patch/utils/mount/fstab.c (+0/-649)
.pc/03-handle-mtab-symlink.patch/utils/mount/fstab.h (+0/-31)
.pc/03-handle-mtab-symlink.patch/utils/mount/mount.c (+0/-550)
.pc/11-532048-reduce-verbosity.patch/utils/gssd/gss_util.c (+0/-341)
.pc/11-532048-reduce-verbosity.patch/utils/gssd/gssd_proc.c (+0/-1241)
.pc/16-mount.nfs.man-update-distinction-between-fstype.patch/utils/mount/mount.nfs.man (+0/-86)
.pc/17-multiarch-kerberos-paths.patch/aclocal/kerberos5.m4 (+0/-115)
.pc/18-osd_login-sbindir.patch/utils/osd_login/Makefile.am (+0/-12)
.pc/19-iscsiadm-path.patch/utils/osd_login/osd_login (+0/-118)
.pc/applied-patches (+0/-8)
aclocal/kerberos5.m4 (+0/-2)
debian/changelog (+27/-0)
debian/nfs-kernel-server.init (+7/-1)
utils/exportfs/nfsd.man (+0/-1)
utils/gssd/gss_util.c (+1/-1)
utils/gssd/gssd_proc.c (+3/-3)
utils/mount/fstab.c (+1/-1)
utils/mount/fstab.h (+0/-1)
utils/mount/mount.c (+0/-7)
utils/mount/mount.nfs.man (+4/-8)
utils/nfsd/nfsd.man (+0/-1)
utils/osd_login/Makefile.am (+8/-5)
utils/osd_login/osd_login (+4/-2)
utils/statd/statd.c (+1/-1)
To merge this branch: bzr merge lp:~logan/ubuntu/quantal/nfs-utils/debian-merge
Reviewer Review Type Date Requested Status
Luke Yelavich (community) Approve
Ubuntu branches Pending
Review via email: mp+118261@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Luke Yelavich (themuso) wrote :

Thanks for your work.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file '.pc/.quilt_patches'
--- .pc/.quilt_patches 1970-01-01 00:00:00 +0000
+++ .pc/.quilt_patches 2012-08-05 05:01:18 +0000
@@ -0,0 +1,1 @@
1debian/patches
02
=== added file '.pc/.quilt_series'
--- .pc/.quilt_series 1970-01-01 00:00:00 +0000
+++ .pc/.quilt_series 2012-08-05 05:01:18 +0000
@@ -0,0 +1,1 @@
1series
02
=== removed directory '.pc/01-sm-notify-in-sbin.patch'
=== removed directory '.pc/01-sm-notify-in-sbin.patch/utils'
=== removed directory '.pc/01-sm-notify-in-sbin.patch/utils/statd'
=== removed file '.pc/01-sm-notify-in-sbin.patch/utils/statd/statd.c'
--- .pc/01-sm-notify-in-sbin.patch/utils/statd/statd.c 2010-04-06 16:11:22 +0000
+++ .pc/01-sm-notify-in-sbin.patch/utils/statd/statd.c 1970-01-01 00:00:00 +0000
@@ -1,493 +0,0 @@
1/*
2 * Copyright (C) 1995, 1997-1999 Jeffrey A. Uphoff
3 * Modified by Olaf Kirch, Oct. 1996.
4 * Modified by H.J. Lu, 1998.
5 * Modified by L. Hohberger of Mission Critical Linux, 2000.
6 *
7 * NSM for Linux.
8 */
9
10#ifdef HAVE_CONFIG_H
11#include <config.h>
12#endif
13
14#include <sys/stat.h>
15#include <limits.h>
16#include <signal.h>
17#include <unistd.h>
18#include <fcntl.h>
19#include <errno.h>
20#include <string.h>
21#include <getopt.h>
22#include <rpc/rpc.h>
23#include <rpc/pmap_clnt.h>
24#include <rpcmisc.h>
25#include <sys/resource.h>
26#include <sys/wait.h>
27#include <grp.h>
28
29#include "statd.h"
30#include "nfslib.h"
31#include "nsm.h"
32
33/* Socket operations */
34#include <sys/types.h>
35#include <sys/socket.h>
36
37int run_mode = 0; /* foreground logging mode */
38
39/* LH - I had these local to main, but it seemed silly to have
40 * two copies of each - one in main(), one static in log.c...
41 * It also eliminates the 256-char static in log.c */
42static char *name_p = NULL;
43
44/* PRC: a high-availability callout program can be specified with -H
45 * When this is done, the program will receive callouts whenever clients
46 * are added or deleted to the notify list */
47char *ha_callout_prog = NULL;
48
49static struct option longopts[] =
50{
51 { "foreground", 0, 0, 'F' },
52 { "no-syslog", 0, 0, 'd' },
53 { "help", 0, 0, 'h' },
54 { "version", 0, 0, 'v' },
55 { "outgoing-port", 1, 0, 'o' },
56 { "port", 1, 0, 'p' },
57 { "name", 1, 0, 'n' },
58 { "state-directory-path", 1, 0, 'P' },
59 { "notify-mode", 0, 0, 'N' },
60 { "ha-callout", 1, 0, 'H' },
61 { "no-notify", 0, 0, 'L' },
62 { NULL, 0, 0, 0 }
63};
64
65extern void sm_prog_1 (struct svc_req *, register SVCXPRT *);
66
67#ifdef SIMULATIONS
68extern void simulator (int, char **);
69#endif
70
71
72#ifdef HAVE_TCP_WRAPPER
73#include "tcpwrapper.h"
74
75static void
76sm_prog_1_wrapper (struct svc_req *rqstp, register SVCXPRT *transp)
77{
78 /* remote host authorization check */
79 if (!check_default("statd", nfs_getrpccaller(transp), SM_PROG)) {
80 svcerr_auth (transp, AUTH_FAILED);
81 return;
82 }
83
84 sm_prog_1 (rqstp, transp);
85}
86
87#define sm_prog_1 sm_prog_1_wrapper
88#endif
89
90static void
91statd_unregister(void) {
92 nfs_svc_unregister(SM_PROG, SM_VERS);
93}
94
95/*
96 * Signal handler.
97 */
98static void
99killer (int sig)
100{
101 statd_unregister ();
102 xlog_err ("Caught signal %d, un-registering and exiting", sig);
103}
104
105static void
106sigusr (int sig)
107{
108 extern void my_svc_exit (void);
109 xlog(D_GENERAL, "Caught signal %d, re-notifying (state %d)", sig,
110 MY_STATE);
111 my_svc_exit();
112}
113
114/*
115 * Startup information.
116 */
117static void log_modes(void)
118{
119 char buf[128]; /* watch stack size... */
120
121 /* No flags = no message */
122 if (!run_mode) return;
123
124 memset(buf,0,128);
125 sprintf(buf,"Flags: ");
126 if (run_mode & MODE_NODAEMON)
127 strcat(buf,"No-Daemon ");
128 if (run_mode & MODE_LOG_STDERR)
129 strcat(buf,"Log-STDERR ");
130#ifdef HAVE_LIBTIRPC
131 strcat(buf, "TI-RPC ");
132#endif
133
134 xlog_warn(buf);
135}
136
137/*
138 * Since we do more than standard statd stuff, we might need to
139 * help the occasional admin.
140 */
141static void
142usage(void)
143{
144 fprintf(stderr,"usage: %s [options]\n", name_p);
145 fprintf(stderr," -h, -?, --help Print this help screen.\n");
146 fprintf(stderr," -F, --foreground Foreground (no-daemon mode)\n");
147 fprintf(stderr," -d, --no-syslog Verbose logging to stderr. Foreground mode only.\n");
148 fprintf(stderr," -p, --port Port to listen on\n");
149 fprintf(stderr," -o, --outgoing-port Port for outgoing connections\n");
150 fprintf(stderr," -V, -v, --version Display version information and exit.\n");
151 fprintf(stderr," -n, --name Specify a local hostname.\n");
152 fprintf(stderr," -P State directory path.\n");
153 fprintf(stderr," -N Run in notify only mode.\n");
154 fprintf(stderr," -L, --no-notify Do not perform any notification.\n");
155 fprintf(stderr," -H Specify a high-availability callout program.\n");
156}
157
158static const char *pidfile = "/var/run/rpc.statd.pid";
159
160int pidfd = -1;
161static void create_pidfile(void)
162{
163 FILE *fp;
164
165 unlink(pidfile);
166 fp = fopen(pidfile, "w");
167 if (!fp)
168 xlog_err("Opening %s failed: %m\n", pidfile);
169 fprintf(fp, "%d\n", getpid());
170 pidfd = dup(fileno(fp));
171 if (fclose(fp) < 0) {
172 xlog_warn("Flushing pid file failed: errno %d (%m)\n",
173 errno);
174 }
175}
176
177static void truncate_pidfile(void)
178{
179 if (pidfd >= 0) {
180 if (ftruncate(pidfd, 0) < 0) {
181 xlog_warn("truncating pid file failed: errno %d (%m)\n",
182 errno);
183 }
184 }
185}
186
187static void run_sm_notify(int outport)
188{
189 char op[20];
190 char *av[6];
191 int ac = 0;
192
193 av[ac++] = "/usr/sbin/sm-notify";
194 if (run_mode & MODE_NODAEMON)
195 av[ac++] = "-d";
196 if (outport) {
197 sprintf(op, "-p%d", outport);
198 av[ac++] = op;
199 }
200 if (run_mode & STATIC_HOSTNAME) {
201 av[ac++] = "-v";
202 av[ac++] = MY_NAME;
203 }
204 av[ac] = NULL;
205 execv(av[0], av);
206 fprintf(stderr, "%s: failed to run %s\n", name_p, av[0]);
207 exit(2);
208
209}
210/*
211 * Entry routine/main loop.
212 */
213int main (int argc, char **argv)
214{
215 extern char *optarg;
216 int pid;
217 int arg;
218 int port = 0, out_port = 0;
219 struct rlimit rlim;
220
221 int pipefds[2] = { -1, -1};
222 char status;
223
224 /* Default: daemon mode, no other options */
225 run_mode = 0;
226 xlog_stderr(0);
227 xlog_syslog(1);
228
229 /* Set the basename */
230 if ((name_p = strrchr(argv[0],'/')) != NULL) {
231 name_p ++;
232 } else {
233 name_p = argv[0];
234 }
235
236 /* Set hostname */
237 MY_NAME = NULL;
238
239 /* Process command line switches */
240 while ((arg = getopt_long(argc, argv, "h?vVFNH:dn:p:o:P:L", longopts, NULL)) != EOF) {
241 switch (arg) {
242 case 'V': /* Version */
243 case 'v':
244 printf("%s version " VERSION "\n",name_p);
245 exit(0);
246 case 'F': /* Foreground/nodaemon mode */
247 run_mode |= MODE_NODAEMON;
248 break;
249 case 'N':
250 run_mode |= MODE_NOTIFY_ONLY;
251 break;
252 case 'L': /* Listen only */
253 run_mode |= MODE_NO_NOTIFY;
254 break;
255 case 'd': /* No daemon only - log to stderr */
256 run_mode |= MODE_LOG_STDERR;
257 break;
258 case 'o':
259 out_port = atoi(optarg);
260 if (out_port < 1 || out_port > 65535) {
261 fprintf(stderr, "%s: bad port number: %s\n",
262 argv[0], optarg);
263 usage();
264 exit(1);
265 }
266 break;
267 case 'p':
268 port = atoi(optarg);
269 if (port < 1 || port > 65535) {
270 fprintf(stderr, "%s: bad port number: %s\n",
271 argv[0], optarg);
272 usage();
273 exit(1);
274 }
275 break;
276 case 'n': /* Specify local hostname */
277 run_mode |= STATIC_HOSTNAME;
278 MY_NAME = xstrdup(optarg);
279 break;
280 case 'P':
281 if (!nsm_setup_pathnames(argv[0], optarg))
282 exit(1);
283 break;
284 case 'H': /* PRC: specify the ha-callout program */
285 if ((ha_callout_prog = xstrdup(optarg)) == NULL) {
286 fprintf(stderr, "%s: xstrdup(%s) failed!\n",
287 argv[0], optarg);
288 exit(1);
289 }
290 break;
291 case '?': /* heeeeeelllllllpppp? heh */
292 case 'h':
293 usage();
294 exit (0);
295 default: /* oh dear ... heh */
296 usage();
297 exit(-1);
298 }
299 }
300
301 if (port == out_port && port != 0) {
302 fprintf(stderr, "Listening and outgoing ports cannot be the same!\n");
303 exit(-1);
304 }
305
306 if (run_mode & MODE_NOTIFY_ONLY) {
307 fprintf(stderr, "%s: -N deprecated, consider using /usr/sbin/sm-notify directly\n",
308 name_p);
309 run_sm_notify(out_port);
310 }
311
312 if (!(run_mode & MODE_NODAEMON)) {
313 run_mode &= ~MODE_LOG_STDERR; /* Never log to console in
314 daemon mode. */
315 }
316
317 if (getrlimit (RLIMIT_NOFILE, &rlim) != 0)
318 fprintf(stderr, "%s: getrlimit (RLIMIT_NOFILE) failed: %s\n",
319 argv [0], strerror(errno));
320 else {
321 /* glibc sunrpc code dies if getdtablesize > FD_SETSIZE */
322 if (rlim.rlim_cur > FD_SETSIZE) {
323 rlim.rlim_cur = FD_SETSIZE;
324
325 if (setrlimit (RLIMIT_NOFILE, &rlim) != 0) {
326 fprintf(stderr, "%s: setrlimit (RLIMIT_NOFILE) failed: %s\n",
327 argv [0], strerror(errno));
328 }
329 }
330 }
331
332#ifdef SIMULATIONS
333 if (argc > 1)
334 /* LH - I _really_ need to update simulator... */
335 simulator (--argc, ++argv); /* simulator() does exit() */
336#endif
337
338 if (!(run_mode & MODE_NODAEMON)) {
339 int tempfd;
340
341 if (pipe(pipefds)<0) {
342 perror("statd: unable to create pipe");
343 exit(1);
344 }
345 if ((pid = fork ()) < 0) {
346 perror ("statd: Could not fork");
347 exit (1);
348 } else if (pid != 0) {
349 /* Parent.
350 * Wait for status from child.
351 */
352 close(pipefds[1]);
353 if (read(pipefds[0], &status, 1) != 1)
354 exit(1);
355 exit (0);
356 }
357 /* Child. */
358 close(pipefds[0]);
359 setsid ();
360
361 while (pipefds[1] <= 2) {
362 pipefds[1] = dup(pipefds[1]);
363 if (pipefds[1]<0) {
364 perror("statd: dup");
365 exit(1);
366 }
367 }
368 tempfd = open("/dev/null", O_RDWR);
369 dup2(tempfd, 0);
370 dup2(tempfd, 1);
371 dup2(tempfd, 2);
372 dup2(pipefds[1], 3);
373 pipefds[1] = 3;
374 closeall(4);
375 }
376
377 /* Child. */
378
379 if (run_mode & MODE_LOG_STDERR) {
380 xlog_syslog(0);
381 xlog_stderr(1);
382 xlog_config(D_ALL, 1);
383 }
384 xlog_open(name_p);
385 xlog(L_NOTICE, "Version " VERSION " starting");
386
387 log_modes();
388
389 signal (SIGHUP, killer);
390 signal (SIGINT, killer);
391 signal (SIGTERM, killer);
392 /* PRC: trap SIGUSR1 to re-read notify list from disk */
393 signal(SIGUSR1, sigusr);
394 /* WARNING: the following works on Linux and SysV, but not BSD! */
395 signal(SIGCHLD, SIG_IGN);
396 /*
397 * Ignore SIGPIPE to avoid statd dying when peers close their
398 * TCP connection while we're trying to reply to them.
399 */
400 signal(SIGPIPE, SIG_IGN);
401
402 create_pidfile();
403 atexit(truncate_pidfile);
404
405 if (! (run_mode & MODE_NO_NOTIFY))
406 switch (pid = fork()) {
407 case 0:
408 run_sm_notify(out_port);
409 break;
410 case -1:
411 break;
412 default:
413 waitpid(pid, NULL, 0);
414 }
415
416 /* Make sure we have a privilege port for calling into the kernel */
417 if (statd_get_socket() < 0)
418 exit(1);
419
420 /* If sm-notify didn't take all the state files, load
421 * state information into our notify-list so we can
422 * pass on any SM_NOTIFY that arrives
423 */
424 load_state();
425
426 MY_STATE = nsm_get_state(0);
427 if (MY_STATE == 0)
428 exit(1);
429 xlog(D_GENERAL, "Local NSM state number: %d", MY_STATE);
430 nsm_update_kernel_state(MY_STATE);
431
432 /*
433 * ORDER
434 * Clear old listeners while still root, to override any
435 * permission checking done by rpcbind.
436 */
437 statd_unregister();
438
439 /*
440 * ORDER
441 */
442 if (!nsm_drop_privileges(pidfd))
443 exit(1);
444
445 /*
446 * ORDER
447 * Create RPC listeners after dropping privileges. This permits
448 * statd to unregister its own listeners when it exits.
449 */
450 if (nfs_svc_create("statd", SM_PROG, SM_VERS, sm_prog_1, port) == 0) {
451 xlog(L_ERROR, "failed to create RPC listeners, exiting");
452 exit(1);
453 }
454 atexit(statd_unregister);
455
456 /* If we got this far, we have successfully started, so notify parent */
457 if (pipefds[1] > 0) {
458 status = 0;
459 if (write(pipefds[1], &status, 1) != 1) {
460 xlog_warn("writing to parent pipe failed: errno %d (%s)\n",
461 errno, strerror(errno));
462 }
463 close(pipefds[1]);
464 pipefds[1] = -1;
465 }
466
467 for (;;) {
468 /*
469 * Handle incoming requests: SM_NOTIFY socket requests, as
470 * well as callbacks from lockd.
471 */
472 my_svc_run(); /* I rolled my own, Olaf made it better... */
473
474 /* Only get here when simulating a crash so we should probably
475 * start sm-notify running again. As we have already dropped
476 * privileges, this might not work, but I don't think
477 * responding to SM_SIMU_CRASH is an important use cases to
478 * get perfect.
479 */
480 if (! (run_mode & MODE_NO_NOTIFY))
481 switch (pid = fork()) {
482 case 0:
483 run_sm_notify(out_port);
484 break;
485 case -1:
486 break;
487 default:
488 waitpid(pid, NULL, 0);
489 }
490
491 }
492 return 0;
493}
4940
=== removed directory '.pc/02-524255-manpages.patch'
=== removed directory '.pc/02-524255-manpages.patch/utils'
=== removed directory '.pc/02-524255-manpages.patch/utils/exportfs'
=== removed file '.pc/02-524255-manpages.patch/utils/exportfs/nfsd.man'
--- .pc/02-524255-manpages.patch/utils/exportfs/nfsd.man 2012-05-25 20:41:58 +0000
+++ .pc/02-524255-manpages.patch/utils/exportfs/nfsd.man 1970-01-01 00:00:00 +0000
@@ -1,206 +0,0 @@
1.\"
2.\" nfsd(7) - The nfsd filesystem
3.\"
4.\" Copyright (C) 2003 Neil Brown <neilb@cse.unsw.edu.au>
5.\" Licensed for public use under the terms of the FSF
6.\" General Public License (GPL) version 2.
7.TH nfsd 7 "3 July 2003"
8.SH NAME
9nfsd \- special filesystem for controlling Linux NFS server
10.SH SYNPOSIS
11.B "mount -t nfsd nfsd /proc/fs/nfsd"
12.SH DESCRIPTION
13The
14.B nfsd
15filesystem is a special filesystem which provides access to the Linux
16NFS server. The filesystem consists of a single directory which
17contains a number of files. These files are actually gateways into
18the NFS server. Writing to them can affect the server. Reading from
19them can provide information about the server.
20.P
21This file system is only available in Linux 2.6 and later series
22kernels (and in the later parts of the 2.5 development series leading
23up to 2.6). This man page does not apply to 2.4 and earlier.
24.P
25As well as this filesystem, there are a collection of files in the
26.B procfs
27filesystem (normally mounted at
28.BR /proc )
29which are used to control the NFS server.
30This manual page describes all of these files.
31.P
32The
33.I exportfs
34and
35.I mountd
36programs (part of the nfs-utils package) expect to find this
37filesystem mounted at
38.B /proc/fs/nfsd
39or
40.BR /proc/fs/nfs .
41If it is not mounted, they will fall-back on 2.4 style functionality.
42This involves accessing the NFS server via a systemcall. This
43systemcall is scheduled to be removed after the 2.6 kernel series.
44.SH DETAILS
45The three files in the
46.B nfsd
47filesystem are:
48.TP
49.B exports
50This file contains a list of filesystems that are currently exported
51and clients that each filesystem is exported to, together with a list
52of export options for that client/filesystem pair. This is similar
53to the
54.B /proc/fs/nfs/exports
55file in 2.4.
56One difference is that a client doesn't necessarily correspond to just
57one host. It can respond to a large collection of hosts that are
58being treated identically.
59
60Each line of the file contains a path name, a client name, and a
61number of options in parentheses. Any space, tab, newline or
62back-slash character in the path name or client name will be replaced
63by a backslash followed by the octal ASCII code for that character.
64
65.TP
66.B threads
67This file represents the number of
68.B nfsd
69thread currently running. Reading it will show the number of
70threads. Writing an ASCII decimal number will cause the number of
71threads to be changed (increased or decreased as necessary) to achieve
72that number.
73
74.TP
75.B filehandle
76This is a somewhat unusual file in that what is read from it depends
77on what was just written to it. It provides a transactional interface
78where a program can open the file, write a request, and read a
79response. If two separate programs open, write, and read at the same
80time, their requests will not be mixed up.
81
82The request written to
83.B filehandle
84should be a client name, a path name, and a number of bytes. This
85should be followed by a newline, with white-space separating the
86fields, and octal quoting of special characters.
87
88On writing this, the program will be able to read back a filehandle
89for that path as exported to the given client. The filehandle's length
90will be at most the number of bytes given.
91
92The filehandle will be represented in hex with a leading '\ex'.
93.PP
94The directory
95.B /proc/net/rpc
96in the
97.B procfs
98filesystem contains a number of files and directories.
99The files contain statistics that can be display using the
100.I nfsstat
101program.
102The directories contain information about various caches that the NFS
103server maintains to keep track of access permissions that different
104clients have for different filesystems.
105The caches are:
106
107.TP
108.B auth.domain
109This cache maps the name of a client (or domain) to an internal data
110structure. The only access that is possible is to flush the cache.
111
112.TP
113.B auth.unix.ip
114This cache contains a mapping from IP address to the name of the
115authentication domain that the ipaddress should be treated as part of.
116
117.TP
118.B nfsd.export
119This cache contains a mapping from directory and domain to export
120options.
121
122.TP
123.B nfsd.fh
124This cache contains a mapping from domain and a filesystem identifier
125to a directory. The filesystem identifier is stored in the
126filehandles and consists of a number indicating the type of identifier
127and a number of hex bytes indicating the content of the identifier.
128
129.PP
130Each directory representing a cache can hold from 1 to 3 files. They
131are:
132.TP
133.B flush
134When a number of seconds since epoch (1 Jan 1970) is written to this
135file, all entries in the cache that were last updated before that file
136become invalidated and will be flushed out. Writing 1 will flush
137everything. This is the only file that will always be present.
138
139.TP
140.B content
141This file, if present, contains a textual representation of ever entry
142in the cache, one per line. If an entry is still in the cache
143(because it is actively being used) but has expired or is otherwise
144invalid, it will be presented as a comment (with a leading hash
145character).
146
147.TP
148.B channel
149This file, if present, acts a channel for request from the kernel-based
150nfs server to be passed to a user-space program for handling.
151
152When the kernel needs some information which isn't in the cache, it
153makes a line appear in the
154.B channel
155file giving the key for the information. A user-space program should
156read this, find the answer, and write a line containing the key, an
157expiry time, and the content.
158For example the kernel might make
159.ti +5
160nfsd 127.0.0.1
161.br
162appear in the
163.B auth.unix.ip/content
164file. The user-space program might then write
165.ti +5
166nfsd 127.0.0.1 1057206953 localhost
167.br
168to indicate that 127.0.0.1 should map to localhost, at least for now.
169
170If the program uses select(2) or poll(2) to discover if it can read
171from the
172.B channel
173then it will never see and end-of-file but when all requests have been
174answered, it will block until another request appears.
175
176.PP
177In the
178.B /proc
179filesystem there are 4 files that can be used to enabled extra tracing
180of nfsd and related code. They are:
181.in +5
182.B /proc/sys/sunrpc/nfs_debug
183.br
184.B /proc/sys/sunrpc/nfsd_debug
185.br
186.B /proc/sys/sunrpc/nlm_debug
187.br
188.B /proc/sys/sunrpc/rpc_debug
189.br
190.in -5
191They control tracing for the NFS client, the NFS server, the Network
192Lock Manager (lockd) and the underlying RPC layer respectively.
193Decimal numbers can be read from or written to these files. Each
194number represents a bit-pattern where bits that are set cause certain
195classes of tracing to be enabled. Consult the kernel header files to
196find out what number correspond to what tracing.
197
198.SH SEE ALSO
199.BR rpc.nfsd (8),
200.BR exports (5),
201.BR nfsstat (8),
202.BR mountd (8)
203.BR exportfs (8).
204
205.SH AUTHOR
206NeilBrown
2070
=== removed directory '.pc/02-524255-manpages.patch/utils/nfsd'
=== removed file '.pc/02-524255-manpages.patch/utils/nfsd/nfsd.man'
--- .pc/02-524255-manpages.patch/utils/nfsd/nfsd.man 2012-05-25 20:41:58 +0000
+++ .pc/02-524255-manpages.patch/utils/nfsd/nfsd.man 1970-01-01 00:00:00 +0000
@@ -1,105 +0,0 @@
1.\"
2.\" nfsd(8)
3.\"
4.\" Copyright (C) 1999 Olaf Kirch <okir@monad.swb.de>
5.TH rpc.nfsd 8 "7 Aug 2006"
6.SH NAME
7rpc.nfsd \- NFS server process
8.SH SYNOPSIS
9.BI "/usr/sbin/rpc.nfsd [" options "]" " "nproc
10.SH DESCRIPTION
11The
12.B rpc.nfsd
13program implements the user level part of the NFS service. The
14main functionality is handled by the
15.B nfsd
16kernel module. The user space program merely specifies what sort of sockets
17the kernel service should listen on, what NFS versions it should support, and
18how many kernel threads it should use.
19.P
20The
21.B rpc.mountd
22server provides an ancillary service needed to satisfy mount requests
23by NFS clients.
24.SH OPTIONS
25.TP
26.B \-d " or " \-\-debug
27enable logging of debugging messages
28.TP
29.B \-H " or " \-\-host hostname
30specify a particular hostname (or address) that NFS requests will
31be accepted on. By default,
32.B rpc.nfsd
33will accept NFS requests on all known network addresses.
34Note that
35.B lockd
36(which performs file locking services for NFS) may still accept
37request on all known network addresses. This may change in future
38releases of the Linux Kernel.
39.TP
40.B \-p " or " \-\-port port
41specify a different port to listen on for NFS requests. By default,
42.B rpc.nfsd
43will listen on port 2049.
44.TP
45.B \-N " or " \-\-no-nfs-version vers
46This option can be used to request that
47.B rpc.nfsd
48does not offer certain versions of NFS. The current version of
49.B rpc.nfsd
50can support both NFS version 2,3 and the newer version 4.
51.TP
52.B \-s " or " \-\-syslog
53By default,
54.B rpc.nfsd
55logs error messages (and debug messages, if enabled) to stderr. This option makes
56.B rpc.nfsd
57log these messages to syslog instead. Note that errors encountered during
58option processing will still be logged to stderr regardless of this option.
59.TP
60.B \-T " or " \-\-no-tcp
61Disable
62.B rpc.nfsd
63from accepting TCP connections from clients.
64.TP
65.B \-U " or " \-\-no-udp
66Disable
67.B rpc.nfsd
68from accepting UDP connections from clients.
69.TP
70.I nproc
71specify the number of NFS server threads. By default, just one
72thread is started. However, for optimum performance several threads
73should be used. The actual figure depends on the number of and the work
74load created by the NFS clients, but a useful starting point is
758 threads. Effects of modifying that number can be checked using
76the
77.BR nfsstat (8)
78program.
79.P
80Note that if the NFS server is already running, then the options for
81specifying host, port, and protocol will be ignored. The number of
82processes given will be the only option considered, and the number of
83active
84.B nfsd
85processes will be increased or decreased to match this number.
86In particular
87.B rpc.nfsd 0
88will stop all threads and thus close any open connections.
89
90.SH NOTES
91If the program is built with TI-RPC support, it will enable any protocol and
92address family combinations that are marked visible in the
93.B netconfig
94database.
95
96.SH SEE ALSO
97.BR rpc.mountd (8),
98.BR exports (5),
99.BR exportfs (8),
100.BR rpc.rquotad (8),
101.BR nfsstat (8),
102.BR netconfig(5).
103.SH AUTHOR
104Olaf Kirch, Bill Hawes, H. J. Lu, G. Allan Morris III,
105and a host of others.
1060
=== removed directory '.pc/03-handle-mtab-symlink.patch'
=== removed directory '.pc/03-handle-mtab-symlink.patch/utils'
=== removed directory '.pc/03-handle-mtab-symlink.patch/utils/mount'
=== removed file '.pc/03-handle-mtab-symlink.patch/utils/mount/fstab.c'
--- .pc/03-handle-mtab-symlink.patch/utils/mount/fstab.c 2011-10-02 18:29:53 +0000
+++ .pc/03-handle-mtab-symlink.patch/utils/mount/fstab.c 1970-01-01 00:00:00 +0000
@@ -1,649 +0,0 @@
1/* 1999-02-22 Arkadiusz Miskiewicz <misiek@pld.ORG.PL>
2 * - added Native Language Support
3 * Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
4 * - fixed strerr(errno) in gettext calls
5 *
6 * 2006-06-08 Amit Gud <agud@redhat.com>
7 * - Moved code to nfs-utils/support/nfs from util-linux/mount.
8 */
9
10#include <errno.h>
11#include <stdio.h>
12#include <fcntl.h>
13#include <unistd.h>
14#include <string.h>
15#include <sys/stat.h>
16#include <mntent.h>
17
18#include "fstab.h"
19#include "xcommon.h"
20#include "nfs_mntent.h"
21#include "nfs_paths.h"
22#include "nls.h"
23
24#define LOCK_TIMEOUT 10
25#define streq(s, t) (strcmp ((s), (t)) == 0)
26#define PROC_MOUNTS "/proc/mounts"
27
28extern char *progname;
29extern int verbose;
30
31/* Information about mtab. ------------------------------------*/
32static int have_mtab_info = 0;
33static int var_mtab_does_not_exist = 0;
34static int var_mtab_is_a_symlink = 0;
35
36static void
37get_mtab_info(void) {
38 struct stat mtab_stat;
39
40 if (!have_mtab_info) {
41 if (lstat(MOUNTED, &mtab_stat))
42 var_mtab_does_not_exist = 1;
43 else if (S_ISLNK(mtab_stat.st_mode))
44 var_mtab_is_a_symlink = 1;
45 have_mtab_info = 1;
46 }
47}
48
49void
50reset_mtab_info(void) {
51 have_mtab_info = 0;
52}
53
54int
55mtab_does_not_exist(void) {
56 get_mtab_info();
57 return var_mtab_does_not_exist;
58}
59
60static int
61mtab_is_a_symlink(void) {
62 get_mtab_info();
63 return var_mtab_is_a_symlink;
64}
65
66int
67mtab_is_writable() {
68 int fd;
69
70 /* Should we write to /etc/mtab upon an update?
71 Probably not if it is a symlink to /proc/mounts, since that
72 would create a file /proc/mounts in case the proc filesystem
73 is not mounted. */
74 if (mtab_is_a_symlink())
75 return 0;
76
77 fd = open(MOUNTED, O_RDWR | O_CREAT, 0644);
78 if (fd >= 0) {
79 close(fd);
80 return 1;
81 } else
82 return 0;
83}
84
85/* Contents of mtab and fstab ---------------------------------*/
86
87struct mntentchn mounttable;
88static int got_mtab = 0;
89struct mntentchn procmounts;
90static int got_procmounts = 0;
91struct mntentchn fstab;
92static int got_fstab = 0;
93
94static void read_mounttable(void);
95static void read_procmounts(void);
96static void read_fstab(void);
97
98static struct mntentchn *
99mtab_head(void)
100{
101 if (!got_mtab)
102 read_mounttable();
103 return &mounttable;
104}
105
106static struct mntentchn *
107procmounts_head(void)
108{
109 if (!got_procmounts)
110 read_procmounts();
111 return &procmounts;
112}
113
114static struct mntentchn *
115fstab_head(void)
116{
117 if (!got_fstab)
118 read_fstab();
119 return &fstab;
120}
121
122#if 0
123static void
124my_free(const void *s) {
125 if (s)
126 free((void *) s);
127}
128
129static void
130discard_mntentchn(struct mntentchn *mc0) {
131 struct mntentchn *mc, *mc1;
132
133 for (mc = mc0->nxt; mc && mc != mc0; mc = mc1) {
134 mc1 = mc->nxt;
135 my_free(mc->m.mnt_fsname);
136 my_free(mc->m.mnt_dir);
137 my_free(mc->m.mnt_type);
138 my_free(mc->m.mnt_opts);
139 free(mc);
140 }
141}
142#endif
143
144static void
145read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {
146 struct mntentchn *mc = mc0;
147 struct mntent *mnt;
148
149 while ((mnt = nfs_getmntent(mfp)) != NULL) {
150 if (!streq(mnt->mnt_type, MNTTYPE_IGNORE)) {
151 mc->nxt = (struct mntentchn *) xmalloc(sizeof(*mc));
152 mc->nxt->prev = mc;
153 mc = mc->nxt;
154 mc->m = *mnt;
155 mc->nxt = mc0;
156 }
157 }
158 mc0->prev = mc;
159 if (ferror(mfp->mntent_fp)) {
160 int errsv = errno;
161 nfs_error(_("warning: error reading %s: %s"),
162 fnam, strerror (errsv));
163 mc0->nxt = mc0->prev = NULL;
164 }
165 nfs_endmntent(mfp);
166}
167
168/*
169 * Read /etc/mtab. If that fails, try /proc/mounts.
170 * This produces a linked list. The list head mounttable is a dummy.
171 * Return 0 on success.
172 */
173static void
174read_mounttable() {
175 mntFILE *mfp;
176 const char *fnam;
177 struct mntentchn *mc = &mounttable;
178
179 got_mtab = 1;
180 mc->nxt = mc->prev = NULL;
181
182 fnam = MOUNTED;
183 mfp = nfs_setmntent (fnam, "r");
184 if (mfp == NULL || mfp->mntent_fp == NULL) {
185 int errsv = errno;
186 fnam = PROC_MOUNTS;
187 mfp = nfs_setmntent (fnam, "r");
188 if (mfp == NULL || mfp->mntent_fp == NULL) {
189 nfs_error(_("warning: can't open %s: %s"),
190 MOUNTED, strerror (errsv));
191 return;
192 }
193 if (verbose)
194 printf(_("%s: could not open %s; using %s instead\n"),
195 progname, MOUNTED, PROC_MOUNTS);
196 }
197 read_mntentchn(mfp, fnam, mc);
198}
199
200/*
201 * Read /proc/mounts.
202 * This produces a linked list. The list head procmounts is a dummy.
203 * Return 0 on success.
204 */
205static void
206read_procmounts() {
207 mntFILE *mfp;
208 const char *fnam;
209 struct mntentchn *mc = &procmounts;
210
211 got_procmounts = 1;
212 mc->nxt = mc->prev = NULL;
213
214 fnam = PROC_MOUNTS;
215 mfp = nfs_setmntent(fnam, "r");
216 if (mfp == NULL || mfp->mntent_fp == NULL) {
217 nfs_error(_("warning: can't open %s: %s"),
218 PROC_MOUNTS, strerror (errno));
219 return;
220 }
221 read_mntentchn(mfp, fnam, mc);
222}
223
224static void
225read_fstab()
226{
227 mntFILE *mfp = NULL;
228 const char *fnam;
229 struct mntentchn *mc = &fstab;
230
231 got_fstab = 1;
232 mc->nxt = mc->prev = NULL;
233
234 fnam = _PATH_FSTAB;
235 mfp = nfs_setmntent (fnam, "r");
236 if (mfp == NULL || mfp->mntent_fp == NULL) {
237 int errsv = errno;
238 nfs_error(_("warning: can't open %s: %s"),
239 _PATH_FSTAB, strerror (errsv));
240 return;
241 }
242 read_mntentchn(mfp, fnam, mc);
243}
244
245/*
246 * Given the directory name NAME, and the place MCPREV we found it last time,
247 * try to find more occurrences.
248 */
249struct mntentchn *
250getmntdirbackward (const char *name, struct mntentchn *mcprev) {
251 struct mntentchn *mc, *mc0;
252
253 mc0 = mtab_head();
254 if (!mcprev)
255 mcprev = mc0;
256 for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)
257 if (streq(mc->m.mnt_dir, name))
258 return mc;
259 return NULL;
260}
261
262/*
263 * Given the directory name NAME, and the place MCPREV we found it last time,
264 * try to find more occurrences.
265 */
266struct mntentchn *
267getprocmntdirbackward (const char *name, struct mntentchn *mcprev) {
268 struct mntentchn *mc, *mc0;
269
270 mc0 = procmounts_head();
271 if (!mcprev)
272 mcprev = mc0;
273 for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)
274 if (streq(mc->m.mnt_dir, name))
275 return mc;
276 return NULL;
277}
278
279/*
280 * Given the device name NAME, and the place MCPREV we found it last time,
281 * try to find more occurrences.
282 */
283struct mntentchn *
284getmntdevbackward (const char *name, struct mntentchn *mcprev) {
285 struct mntentchn *mc, *mc0;
286
287 mc0 = mtab_head();
288 if (!mcprev)
289 mcprev = mc0;
290 for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)
291 if (streq(mc->m.mnt_fsname, name))
292 return mc;
293 return NULL;
294}
295
296/* Find the dir FILE in fstab. */
297struct mntentchn *
298getfsfile (const char *file)
299{
300 struct mntentchn *mc, *mc0;
301
302 mc0 = fstab_head();
303 for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
304 if (streq(mc->m.mnt_dir, file))
305 return mc;
306 return NULL;
307}
308
309/* Find the device SPEC in fstab. */
310struct mntentchn *
311getfsspec (const char *spec)
312{
313 struct mntentchn *mc, *mc0;
314
315 mc0 = fstab_head();
316 for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
317 if (streq(mc->m.mnt_fsname, spec))
318 return mc;
319 return NULL;
320}
321
322/* Updating mtab ----------------------------------------------*/
323
324/* Flag for already existing lock file. */
325static int we_created_lockfile = 0;
326static int lockfile_fd = -1;
327
328/* Flag to indicate that signals have been set up. */
329static int signals_have_been_setup = 0;
330
331/* Ensure that the lock is released if we are interrupted. */
332extern char *strsignal(int sig); /* not always in <string.h> */
333
334static void
335handler (int sig) {
336 die(EX_USER, "%s", strsignal(sig));
337}
338
339static void
340setlkw_timeout (__attribute__((unused)) int sig) {
341 /* nothing, fcntl will fail anyway */
342}
343
344/* Remove lock file. */
345void
346unlock_mtab (void) {
347 if (we_created_lockfile) {
348 close(lockfile_fd);
349 lockfile_fd = -1;
350 unlink (MOUNTED_LOCK);
351 we_created_lockfile = 0;
352 }
353}
354
355/* Create the lock file.
356 The lock file will be removed if we catch a signal or when we exit. */
357/* The old code here used flock on a lock file /etc/mtab~ and deleted
358 this lock file afterwards. However, as rgooch remarks, that has a
359 race: a second mount may be waiting on the lock and proceed as
360 soon as the lock file is deleted by the first mount, and immediately
361 afterwards a third mount comes, creates a new /etc/mtab~, applies
362 flock to that, and also proceeds, so that the second and third mount
363 now both are scribbling in /etc/mtab.
364 The new code uses a link() instead of a creat(), where we proceed
365 only if it was us that created the lock, and hence we always have
366 to delete the lock afterwards. Now the use of flock() is in principle
367 superfluous, but avoids an arbitrary sleep(). */
368
369/* Where does the link point to? Obvious choices are mtab and mtab~~.
370 HJLu points out that the latter leads to races. Right now we use
371 mtab~.<pid> instead. Use 20 as upper bound for the length of %d. */
372#define MOUNTLOCK_LINKTARGET MOUNTED_LOCK "%d"
373#define MOUNTLOCK_LINKTARGET_LTH (sizeof(MOUNTED_LOCK)+20)
374
375void
376lock_mtab (void) {
377 int tries = 100000, i;
378 char linktargetfile[MOUNTLOCK_LINKTARGET_LTH];
379
380 at_die = unlock_mtab;
381
382 if (!signals_have_been_setup) {
383 int sig = 0;
384 struct sigaction sa;
385
386 sa.sa_flags = 0;
387 sigfillset (&sa.sa_mask);
388
389 while (sigismember (&sa.sa_mask, ++sig) != -1) {
390 switch(sig) {
391 case SIGCHLD:
392 case SIGKILL:
393 case SIGCONT:
394 case SIGSTOP:
395 /* The cannot be caught, or should not,
396 * so don't even try.
397 */
398 continue;
399 case SIGALRM:
400 sa.sa_handler = setlkw_timeout;
401 break;
402 case SIGHUP:
403 case SIGINT:
404 case SIGQUIT:
405 case SIGWINCH:
406 case SIGTSTP:
407 case SIGTTIN:
408 case SIGTTOU:
409 case SIGPIPE:
410 case SIGXFSZ:
411 case SIGXCPU:
412 /* non-priv user can cause these to be
413 * generated, so ignore them.
414 */
415 sa.sa_handler = SIG_IGN;
416 break;
417 default:
418 /* The rest should not be possible, so just
419 * print a message and unlock mtab.
420 */
421 sa.sa_handler = handler;
422 }
423 sigaction (sig, &sa, (struct sigaction *) 0);
424 }
425 signals_have_been_setup = 1;
426 }
427
428 sprintf(linktargetfile, MOUNTLOCK_LINKTARGET, getpid ());
429
430 i = open (linktargetfile, O_WRONLY|O_CREAT, 0);
431 if (i < 0) {
432 int errsv = errno;
433 /* linktargetfile does not exist (as a file)
434 and we cannot create it. Read-only filesystem?
435 Too many files open in the system?
436 Filesystem full? */
437 die (EX_FILEIO, _("can't create lock file %s: %s "
438 "(use -n flag to override)"),
439 linktargetfile, strerror (errsv));
440 }
441 close(i);
442
443 /* Repeat until it was us who made the link */
444 while (!we_created_lockfile) {
445 struct flock flock;
446 int j;
447
448 j = link(linktargetfile, MOUNTED_LOCK);
449
450 {
451 int errsv = errno;
452
453 if (j == 0)
454 we_created_lockfile = 1;
455
456 if (j < 0 && errsv != EEXIST) {
457 (void) unlink(linktargetfile);
458 die (EX_FILEIO, _("can't link lock file %s: %s "
459 "(use -n flag to override)"),
460 MOUNTED_LOCK, strerror (errsv));
461 }
462 }
463
464 lockfile_fd = open (MOUNTED_LOCK, O_WRONLY);
465
466 if (lockfile_fd < 0) {
467 int errsv = errno;
468 /* Strange... Maybe the file was just deleted? */
469 if (errno == ENOENT && tries-- > 0) {
470 if (tries % 200 == 0)
471 usleep(30);
472 continue;
473 }
474 (void) unlink(linktargetfile);
475 die (EX_FILEIO, _("can't open lock file %s: %s "
476 "(use -n flag to override)"),
477 MOUNTED_LOCK, strerror (errsv));
478 }
479
480 flock.l_type = F_WRLCK;
481 flock.l_whence = SEEK_SET;
482 flock.l_start = 0;
483 flock.l_len = 0;
484
485 if (j == 0) {
486 /* We made the link. Now claim the lock. */
487 if (fcntl (lockfile_fd, F_SETLK, &flock) == -1) {
488 if (verbose) {
489 int errsv = errno;
490 nfs_error(_("%s: Can't lock lock file "
491 "%s: %s"), progname,
492 MOUNTED_LOCK,
493 strerror (errsv));
494 }
495 /* proceed anyway */
496 }
497 (void) unlink(linktargetfile);
498 } else {
499 static int retries = 0;
500
501 /* Someone else made the link. Wait. */
502 alarm(LOCK_TIMEOUT);
503 if (fcntl (lockfile_fd, F_SETLKW, &flock) == -1) {
504 int errsv = errno;
505 (void) unlink(linktargetfile);
506 die (EX_FILEIO, _("can't lock lock file %s: %s"),
507 MOUNTED_LOCK, (errno == EINTR) ?
508 _("timed out") : strerror (errsv));
509 }
510 alarm(0);
511 /* Limit the number of iterations - maybe there
512 still is some old /etc/mtab~ */
513 ++retries;
514 if (retries % 200 == 0)
515 usleep(30);
516 if (retries > 100000) {
517 (void) unlink(linktargetfile);
518 close(lockfile_fd);
519 die (EX_FILEIO, _("Cannot create link %s\n"
520 "Perhaps there is a stale lock file?\n"),
521 MOUNTED_LOCK);
522 }
523 close(lockfile_fd);
524 }
525 }
526}
527
528/*
529 * Update the mtab.
530 * Used by umount with null INSTEAD: remove the last DIR entry.
531 * Used by mount upon a remount: update option part,
532 * and complain if a wrong device or type was given.
533 * [Note that often a remount will be a rw remount of /
534 * where there was no entry before, and we'll have to believe
535 * the values given in INSTEAD.]
536 */
537
538void
539update_mtab (const char *dir, struct mntent *instead)
540{
541 mntFILE *mfp, *mftmp;
542 const char *fnam = MOUNTED;
543 struct mntentchn mtabhead; /* dummy */
544 struct mntentchn *mc, *mc0, *absent = NULL;
545
546 if (mtab_does_not_exist() || !mtab_is_writable())
547 return;
548
549 lock_mtab();
550
551 /* having locked mtab, read it again */
552 mc0 = mc = &mtabhead;
553 mc->nxt = mc->prev = NULL;
554
555 mfp = nfs_setmntent(fnam, "r");
556 if (mfp == NULL || mfp->mntent_fp == NULL) {
557 int errsv = errno;
558 nfs_error (_("cannot open %s (%s) - mtab not updated"),
559 fnam, strerror (errsv));
560 goto leave;
561 }
562
563 read_mntentchn(mfp, fnam, mc);
564
565 /* find last occurrence of dir */
566 for (mc = mc0->prev; mc && mc != mc0; mc = mc->prev)
567 if (streq(mc->m.mnt_dir, dir))
568 break;
569 if (mc && mc != mc0) {
570 if (instead == NULL) {
571 /* An umount - remove entry */
572 if (mc && mc != mc0) {
573 mc->prev->nxt = mc->nxt;
574 mc->nxt->prev = mc->prev;
575 free(mc);
576 }
577 } else {
578 /* A remount */
579 mc->m.mnt_opts = instead->mnt_opts;
580 }
581 } else if (instead) {
582 /* not found, add a new entry */
583 absent = xmalloc(sizeof(*absent));
584 absent->m = *instead;
585 absent->nxt = mc0;
586 absent->prev = mc0->prev;
587 mc0->prev = absent;
588 if (mc0->nxt == NULL)
589 mc0->nxt = absent;
590 }
591
592 /* write chain to mtemp */
593 mftmp = nfs_setmntent (MOUNTED_TEMP, "w");
594 if (mftmp == NULL || mftmp->mntent_fp == NULL) {
595 int errsv = errno;
596 nfs_error (_("cannot open %s (%s) - mtab not updated"),
597 MOUNTED_TEMP, strerror (errsv));
598 goto leave;
599 }
600
601 for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) {
602 if (nfs_addmntent(mftmp, &(mc->m)) == 1) {
603 int errsv = errno;
604 die (EX_FILEIO, _("error writing %s: %s"),
605 MOUNTED_TEMP, strerror (errsv));
606 }
607 }
608
609#if 0
610 /* the chain might have strings copied from 'instead',
611 * so we cannot safely free it.
612 * And there is no need anyway because we are going to exit
613 * shortly. So just don't call discard_mntentchn....
614 */
615 discard_mntentchn(mc0);
616#endif
617 if (fchmod (fileno (mftmp->mntent_fp),
618 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
619 int errsv = errno;
620 nfs_error(_("%s: error changing mode of %s: %s"),
621 progname, MOUNTED_TEMP, strerror (errsv));
622 }
623 nfs_endmntent (mftmp);
624
625 { /*
626 * If mount is setuid and some non-root user mounts sth,
627 * then mtab.tmp might get the group of this user. Copy uid/gid
628 * from the present mtab before renaming.
629 */
630 struct stat sbuf;
631 if (stat (MOUNTED, &sbuf) == 0) {
632 if (chown (MOUNTED_TEMP, sbuf.st_uid, sbuf.st_gid) < 0) {
633 nfs_error(_("%s: error changing owner of %s: %s"),
634 progname, MOUNTED_TEMP, strerror (errno));
635 }
636 }
637 }
638
639 /* rename mtemp to mtab */
640 if (rename (MOUNTED_TEMP, MOUNTED) < 0) {
641 int errsv = errno;
642 nfs_error(_("%s: can't rename %s to %s: %s\n"),
643 progname, MOUNTED_TEMP, MOUNTED,
644 strerror(errsv));
645 }
646
647 leave:
648 unlock_mtab();
649}
6500
=== removed file '.pc/03-handle-mtab-symlink.patch/utils/mount/fstab.h'
--- .pc/03-handle-mtab-symlink.patch/utils/mount/fstab.h 2011-10-02 18:29:53 +0000
+++ .pc/03-handle-mtab-symlink.patch/utils/mount/fstab.h 1970-01-01 00:00:00 +0000
@@ -1,31 +0,0 @@
1#ifndef _NFS_UTILS_MOUNT_FSTAB_H
2#define _NFS_UTILS_MOUNT_FSTAB_H
3
4#include "nfs_mntent.h"
5
6#ifndef _PATH_FSTAB
7#define _PATH_FSTAB "/etc/fstab"
8#endif
9
10int mtab_is_writable(void);
11int mtab_does_not_exist(void);
12void reset_mtab_info(void);
13
14struct mntentchn {
15 struct mntentchn *nxt, *prev;
16 struct mntent m;
17};
18
19struct mntentchn *getmntoptfile (const char *file);
20struct mntentchn *getmntdirbackward (const char *dir, struct mntentchn *mc);
21struct mntentchn *getprocmntdirbackward (const char *name, struct mntentchn *mc);
22struct mntentchn *getmntdevbackward (const char *dev, struct mntentchn *mc);
23
24struct mntentchn *getfsfile (const char *file);
25struct mntentchn *getfsspec (const char *spec);
26
27void lock_mtab (void);
28void unlock_mtab (void);
29void update_mtab (const char *special, struct mntent *with);
30
31#endif /* _NFS_UTILS_MOUNT_FSTAB_H */
320
=== removed file '.pc/03-handle-mtab-symlink.patch/utils/mount/mount.c'
--- .pc/03-handle-mtab-symlink.patch/utils/mount/mount.c 2011-07-09 16:28:32 +0000
+++ .pc/03-handle-mtab-symlink.patch/utils/mount/mount.c 1970-01-01 00:00:00 +0000
@@ -1,550 +0,0 @@
1/*
2 * mount.c -- Linux NFS mount
3 *
4 * Copyright (C) 2006 Amit Gud <agud@redhat.com>
5 *
6 * - Basic code and wrapper around mount and umount code of NFS.
7 * Based on util-linux/mount/mount.c.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24
25#include <unistd.h>
26#include <sys/types.h>
27#include <sys/stat.h>
28#include <stdio.h>
29#include <string.h>
30#include <errno.h>
31#include <fcntl.h>
32#include <sys/mount.h>
33#include <getopt.h>
34#include <mntent.h>
35#include <pwd.h>
36
37#include "fstab.h"
38#include "xcommon.h"
39#include "nls.h"
40#include "mount_constants.h"
41#include "mount_config.h"
42#include "nfs_paths.h"
43#include "nfs_mntent.h"
44
45#include "nfs_mount.h"
46#include "nfs4_mount.h"
47#include "mount.h"
48#include "error.h"
49#include "stropts.h"
50#include "utils.h"
51
52char *progname;
53int nfs_mount_data_version;
54int nomtab;
55int verbose;
56int sloppy;
57int string;
58
59#define FOREGROUND (0)
60#define BACKGROUND (1)
61
62static struct option longopts[] = {
63 { "fake", 0, 0, 'f' },
64 { "help", 0, 0, 'h' },
65 { "no-mtab", 0, 0, 'n' },
66 { "read-only", 0, 0, 'r' },
67 { "ro", 0, 0, 'r' },
68 { "verbose", 0, 0, 'v' },
69 { "version", 0, 0, 'V' },
70 { "read-write", 0, 0, 'w' },
71 { "rw", 0, 0, 'w' },
72 { "options", 1, 0, 'o' },
73 { NULL, 0, 0, 0 }
74};
75
76/*
77 * Map from -o and fstab option strings to the flag argument to mount(2).
78 */
79struct opt_map {
80 const char *opt; /* option name */
81 int skip; /* skip in mtab option string */
82 int inv; /* true if flag value should be inverted */
83 int mask; /* flag mask value */
84};
85
86static const struct opt_map opt_map[] = {
87 { "defaults", 0, 0, 0 }, /* default options */
88 { "ro", 1, 0, MS_RDONLY }, /* read-only */
89 { "rw", 1, 1, MS_RDONLY }, /* read-write */
90 { "exec", 0, 1, MS_NOEXEC }, /* permit execution of binaries */
91 { "noexec", 0, 0, MS_NOEXEC }, /* don't execute binaries */
92 { "suid", 0, 1, MS_NOSUID }, /* honor suid executables */
93 { "nosuid", 0, 0, MS_NOSUID }, /* don't honor suid executables */
94 { "dev", 0, 1, MS_NODEV }, /* interpret device files */
95 { "nodev", 0, 0, MS_NODEV }, /* don't interpret devices */
96 { "sync", 0, 0, MS_SYNCHRONOUS}, /* synchronous I/O */
97 { "async", 0, 1, MS_SYNCHRONOUS}, /* asynchronous I/O */
98 { "dirsync", 0, 0, MS_DIRSYNC}, /* synchronous directory modifications */
99 { "remount", 0, 0, MS_REMOUNT}, /* Alter flags of mounted FS */
100 { "bind", 0, 0, MS_BIND }, /* Remount part of tree elsewhere */
101 { "rbind", 0, 0, MS_BIND|MS_REC }, /* Idem, plus mounted subtrees */
102 { "auto", 0, 0, MS_DUMMY }, /* Can be mounted using -a */
103 { "noauto", 0, 0, MS_DUMMY }, /* Can only be mounted explicitly */
104 { "users", 1, 0, MS_USERS }, /* Allow ordinary user to mount */
105 { "nousers", 0, 1, MS_DUMMY }, /* Forbid ordinary user to mount */
106 { "user", 1, 0, MS_USER }, /* Allow ordinary user to mount */
107 { "nouser", 0, 1, MS_DUMMY }, /* Forbid ordinary user to mount */
108 { "owner", 0, 0, MS_DUMMY }, /* Let the owner of the device mount */
109 { "noowner", 0, 0, MS_DUMMY }, /* Device owner has no special privs */
110 { "group", 0, 0, MS_DUMMY }, /* Let the group of the device mount */
111 { "nogroup", 0, 0, MS_DUMMY }, /* Device group has no special privs */
112 { "_netdev", 0, 0, MS_DUMMY}, /* Device requires network */
113 { "comment", 0, 0, MS_DUMMY}, /* fstab comment only (kudzu,_netdev)*/
114
115 /* add new options here */
116#ifdef MS_NOSUB
117 { "sub", 0, 1, MS_NOSUB }, /* allow submounts */
118 { "nosub", 0, 0, MS_NOSUB }, /* don't allow submounts */
119#endif
120#ifdef MS_SILENT
121 { "quiet", 0, 0, MS_SILENT }, /* be quiet */
122 { "loud", 0, 1, MS_SILENT }, /* print out messages. */
123#endif
124#ifdef MS_MANDLOCK
125 { "mand", 0, 0, MS_MANDLOCK }, /* Allow mandatory locks on this FS */
126 { "nomand", 0, 1, MS_MANDLOCK }, /* Forbid mandatory locks on this FS */
127#endif
128 { "loop", 1, 0, MS_DUMMY }, /* use a loop device */
129#ifdef MS_NOATIME
130 { "atime", 0, 1, MS_NOATIME }, /* Update access time */
131 { "noatime", 0, 0, MS_NOATIME }, /* Do not update access time */
132#endif
133#ifdef MS_NODIRATIME
134 { "diratime", 0, 1, MS_NODIRATIME }, /* Update dir access times */
135 { "nodiratime", 0, 0, MS_NODIRATIME },/* Do not update dir access times */
136#endif
137#ifdef MS_RELATIME
138 { "relatime", 0, 0, MS_RELATIME }, /* Update access times relative to
139 mtime/ctime */
140 { "norelatime", 0, 1, MS_RELATIME }, /* Update access time without regard
141 to mtime/ctime */
142#endif
143 { "noquota", 0, 0, MS_DUMMY }, /* Don't enforce quota */
144 { "quota", 0, 0, MS_DUMMY }, /* Enforce user quota */
145 { "usrquota", 0, 0, MS_DUMMY }, /* Enforce user quota */
146 { "grpquota", 0, 0, MS_DUMMY }, /* Enforce group quota */
147 { NULL, 0, 0, 0 }
148};
149
150static void parse_opts(const char *options, int *flags, char **extra_opts);
151
152/*
153 * Build a canonical mount option string for /etc/mtab.
154 */
155static char *fix_opts_string(int flags, const char *extra_opts)
156{
157 const struct opt_map *om;
158 char *new_opts;
159
160 new_opts = xstrdup((flags & MS_RDONLY) ? "ro" : "rw");
161 if (flags & MS_USER) {
162 /* record who mounted this so they can unmount */
163 struct passwd *pw = getpwuid(getuid());
164 if(pw)
165 new_opts = xstrconcat3(new_opts, ",user=", pw->pw_name);
166 }
167 if (flags & MS_USERS)
168 new_opts = xstrconcat3(new_opts, ",users", "");
169
170 for (om = opt_map; om->opt != NULL; om++) {
171 if (om->skip)
172 continue;
173 if (om->inv || !om->mask || (flags & om->mask) != om->mask)
174 continue;
175 new_opts = xstrconcat3(new_opts, ",", om->opt);
176 flags &= ~om->mask;
177 }
178 if (extra_opts && *extra_opts) {
179 new_opts = xstrconcat3(new_opts, ",", extra_opts);
180 }
181 return new_opts;
182}
183
184static void
185init_mntent(struct mntent *mnt, char *fsname, char *dir, char *type,
186 int flags, char *opts)
187{
188 mnt->mnt_fsname = fsname;
189 mnt->mnt_dir = dir;
190 mnt->mnt_type = type;
191 mnt->mnt_opts = fix_opts_string(flags & ~MS_NOMTAB, opts);
192
193 /* these are always zero for NFS */
194 mnt->mnt_freq = 0;
195 mnt->mnt_passno = 0;
196}
197
198/* Create mtab with a root entry. */
199static void
200create_mtab (void) {
201 struct mntentchn *fstab;
202 struct mntent mnt;
203 int flags;
204 mntFILE *mfp;
205
206 lock_mtab();
207
208 mfp = nfs_setmntent (MOUNTED, "a+");
209 if (mfp == NULL || mfp->mntent_fp == NULL) {
210 int errsv = errno;
211 die (EX_FILEIO, _("mount: can't open %s for writing: %s"),
212 MOUNTED, strerror (errsv));
213 }
214
215 /* Find the root entry by looking it up in fstab */
216 if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) {
217 char *extra_opts;
218 parse_opts (fstab->m.mnt_opts, &flags, &extra_opts);
219 init_mntent(&mnt, xstrdup(fstab->m.mnt_fsname), "/",
220 fstab->m.mnt_type, flags, extra_opts);
221 free(extra_opts);
222
223 if (nfs_addmntent (mfp, &mnt) == 1) {
224 int errsv = errno;
225 die (EX_FILEIO, _("mount: error writing %s: %s"),
226 _PATH_MOUNTED, strerror (errsv));
227 }
228 }
229 if (fchmod (fileno (mfp->mntent_fp), 0644) < 0)
230 if (errno != EROFS) {
231 int errsv = errno;
232 die (EX_FILEIO,
233 _("mount: error changing mode of %s: %s"),
234 _PATH_MOUNTED, strerror (errsv));
235 }
236 nfs_endmntent (mfp);
237
238 unlock_mtab();
239
240 reset_mtab_info();
241}
242
243static int add_mtab(char *spec, char *mount_point, char *fstype,
244 int flags, char *opts)
245{
246 struct mntent ment;
247 int result = EX_SUCCESS;
248
249 init_mntent(&ment, spec, mount_point, fstype, flags, opts);
250
251 if (!nomtab && mtab_does_not_exist()) {
252 if (verbose > 1)
253 printf(_("mount: no %s found - creating it..\n"),
254 MOUNTED);
255 create_mtab ();
256 }
257
258 if (!nomtab && mtab_is_writable()) {
259 if (flags & MS_REMOUNT)
260 update_mtab(ment.mnt_dir, &ment);
261 else {
262 mntFILE *mtab;
263
264 lock_mtab();
265 mtab = nfs_setmntent(MOUNTED, "a+");
266 if (mtab == NULL || mtab->mntent_fp == NULL) {
267 nfs_error(_("Can't open mtab: %s"),
268 strerror(errno));
269 result = EX_FILEIO;
270 } else {
271 if (nfs_addmntent(mtab, &ment) == 1) {
272 nfs_error(_("Can't write mount entry to mtab: %s"),
273 strerror(errno));
274 result = EX_FILEIO;
275 }
276 }
277 nfs_endmntent(mtab);
278 unlock_mtab();
279 }
280 }
281
282 free(ment.mnt_opts);
283
284 return result;
285}
286
287static void parse_opt(const char *opt, int *mask, char *extra_opts, size_t len)
288{
289 const struct opt_map *om;
290
291 for (om = opt_map; om->opt != NULL; om++) {
292 if (!strcmp (opt, om->opt)) {
293 if (om->inv)
294 *mask &= ~om->mask;
295 else
296 *mask |= om->mask;
297 return;
298 }
299 }
300
301 len -= strlen(extra_opts);
302
303 if (*extra_opts && --len > 0)
304 strcat(extra_opts, ",");
305
306 if ((len -= strlen(opt)) > 0)
307 strcat(extra_opts, opt);
308}
309
310/*
311 * Convert the provided mount command-line options into the 4th &
312 * 5th arguments to mount(2). Output parameter "@flags" gets the
313 * standard options (indicated by MS_ bits), and output parameter
314 * "@extra_opts" gets all the filesystem-specific options.
315 */
316static void parse_opts(const char *options, int *flags, char **extra_opts)
317{
318 if (options != NULL) {
319 char *opts = xstrdup(options);
320 char *opt, *p;
321 size_t len = strlen(opts) + 1; /* include room for a null */
322 int open_quote = 0;
323
324 *extra_opts = xmalloc(len);
325 **extra_opts = '\0';
326
327 for (p = opts, opt = NULL; p && *p; p++) {
328 if (!opt)
329 opt = p; /* begin of the option item */
330 if (*p == '"')
331 open_quote ^= 1; /* reverse the status */
332 if (open_quote)
333 continue; /* still in a quoted block */
334 if (*p == ',')
335 *p = '\0'; /* terminate the option item */
336
337 /* end of option item or last item */
338 if (*p == '\0' || *(p + 1) == '\0') {
339 parse_opt(opt, flags, *extra_opts, len);
340 opt = NULL;
341 }
342 }
343 free(opts);
344 }
345}
346
347static int try_mount(char *spec, char *mount_point, int flags,
348 char *fs_type, char **extra_opts, char *mount_opts,
349 int fake, int bg)
350{
351 int ret;
352
353 if (string)
354 ret = nfsmount_string(spec, mount_point, fs_type, flags,
355 extra_opts, fake, bg);
356 else {
357 if (strcmp(fs_type, "nfs4") == 0)
358 ret = nfs4mount(spec, mount_point, flags,
359 extra_opts, fake, bg);
360 else
361 ret = nfsmount(spec, mount_point, flags,
362 extra_opts, fake, bg);
363 }
364
365 if (ret)
366 return ret;
367
368 if (!fake)
369 print_one(spec, mount_point, fs_type, mount_opts);
370
371 return add_mtab(spec, mount_point, fs_type, flags, *extra_opts);
372}
373
374int main(int argc, char *argv[])
375{
376 int c, flags = 0, mnt_err = 1, fake = 0;
377 char *spec = NULL, *mount_point = NULL, *fs_type = "nfs";
378 char *extra_opts = NULL, *mount_opts = NULL;
379 uid_t uid = getuid();
380
381 progname = basename(argv[0]);
382
383 nfs_mount_data_version = discover_nfs_mount_data_version(&string);
384
385 if(!strncmp(progname, "umount", strlen("umount")))
386 exit(nfsumount(argc, argv));
387
388 if ((argc < 3)) {
389 mount_usage();
390 exit(EX_USAGE);
391 }
392
393 mount_config_init(progname);
394
395 while ((c = getopt_long(argc, argv, "rvVwfno:hs",
396 longopts, NULL)) != -1) {
397 switch (c) {
398 case 'r':
399 flags |= MS_RDONLY;
400 break;
401 case 'v':
402 ++verbose;
403 break;
404 case 'V':
405 printf("%s: ("PACKAGE_STRING")\n", progname);
406 exit(EX_SUCCESS);
407 case 'w':
408 flags &= ~MS_RDONLY;
409 break;
410 case 'f':
411 ++fake;
412 break;
413 case 'n':
414 ++nomtab;
415 break;
416 case 'o': /* specify mount options */
417 if (mount_opts)
418 mount_opts = xstrconcat3(mount_opts, ",", optarg);
419 else
420 mount_opts = xstrdup(optarg);
421 break;
422 case 's':
423 ++sloppy;
424 break;
425 case 'h':
426 default:
427 mount_usage();
428 goto out_usage;
429 }
430 }
431
432 /*
433 * Extra non-option words at the end are bogus...
434 */
435 if (optind != argc - 2) {
436 mount_usage();
437 goto out_usage;
438 } else {
439 while (optind < argc) {
440 if (!spec)
441 spec = argv[optind];
442 else
443 mount_point = argv[optind];
444 optind++;
445 }
446 }
447
448 if (strcmp(progname, "mount.nfs4") == 0)
449 fs_type = "nfs4";
450
451 /*
452 * If a non-root user is attempting to mount, make sure the
453 * user's requested options match the options specified in
454 * /etc/fstab; otherwise, don't allow the mount.
455 */
456 if (uid != 0) {
457 struct mntentchn *mc;
458
459 if ((mc = getfsfile(mount_point)) == NULL ||
460 strcmp(mc->m.mnt_fsname, spec) != 0 ||
461 strcmp(mc->m.mnt_type, fs_type) != 0) {
462 nfs_error(_("%s: permission denied: no match for %s "
463 "found in /etc/fstab"), progname, mount_point);
464 goto out_usage;
465 }
466
467 /*
468 * 'mount' munges the options from fstab before passing them
469 * to us, so it is non-trivial to test that we have the correct
470 * set of options and we don't want to trust what the user
471 * gave us, so just take whatever is in /etc/fstab.
472 */
473 mount_opts = strdup(mc->m.mnt_opts);
474 }
475
476 mount_point = canonicalize(mount_point);
477 if (!mount_point) {
478 nfs_error(_("%s: no mount point provided"), progname);
479 goto out_usage;
480 }
481 if (mount_point[0] != '/') {
482 nfs_error(_("%s: unrecognized mount point %s"),
483 progname, mount_point);
484 mnt_err = EX_USAGE;
485 goto out;
486 }
487 /*
488 * Concatenate mount options from the configuration file
489 */
490 mount_opts = mount_config_opts(spec, mount_point, mount_opts);
491
492 parse_opts(mount_opts, &flags, &extra_opts);
493
494 if (uid != 0) {
495 if (!(flags & (MS_USERS|MS_USER))) {
496 nfs_error(_("%s: permission denied"), progname);
497 mnt_err = EX_USAGE;
498 goto out;
499 }
500
501 if (geteuid() != 0) {
502 nfs_error(_("%s: not installed setuid - "
503 "\"user\" NFS mounts not supported."), progname);
504 exit(EX_FAIL);
505 }
506 }
507
508 if (chk_mountpoint(mount_point)) {
509 mnt_err = EX_USAGE;
510 goto out;
511 }
512
513 mnt_err = try_mount(spec, mount_point, flags, fs_type, &extra_opts,
514 mount_opts, fake, FOREGROUND);
515 if (mnt_err == EX_BG) {
516 printf(_("%s: backgrounding \"%s\"\n"),
517 progname, spec);
518 printf(_("%s: mount options: \"%s\"\n"),
519 progname, extra_opts);
520
521 fflush(stdout);
522
523 /*
524 * Parent exits immediately with success.
525 */
526 if (daemon(0, 0)) {
527 nfs_error(_("%s: failed to start "
528 "background process: %s\n"),
529 progname, strerror(errno));
530 exit(EX_FAIL);
531 }
532
533 mnt_err = try_mount(spec, mount_point, flags, fs_type,
534 &extra_opts, mount_opts, fake,
535 BACKGROUND);
536 if (verbose && mnt_err)
537 printf(_("%s: giving up \"%s\"\n"),
538 progname, spec);
539 }
540
541out:
542 free(mount_opts);
543 free(extra_opts);
544 free(mount_point);
545 exit(mnt_err);
546
547out_usage:
548 free(mount_opts);
549 exit(EX_USAGE);
550}
5510
=== removed directory '.pc/11-532048-reduce-verbosity.patch'
=== removed directory '.pc/11-532048-reduce-verbosity.patch/utils'
=== removed directory '.pc/11-532048-reduce-verbosity.patch/utils/gssd'
=== removed file '.pc/11-532048-reduce-verbosity.patch/utils/gssd/gss_util.c'
--- .pc/11-532048-reduce-verbosity.patch/utils/gssd/gss_util.c 2011-07-09 16:28:32 +0000
+++ .pc/11-532048-reduce-verbosity.patch/utils/gssd/gss_util.c 1970-01-01 00:00:00 +0000
@@ -1,341 +0,0 @@
1/*
2 * Adapted in part from MIT Kerberos 5-1.2.1 slave/kprop.c and from
3 * http://docs.sun.com/?p=/doc/816-1331/6m7oo9sms&a=view
4 *
5 * Copyright (c) 2002 The Regents of the University of Michigan.
6 * All rights reserved.
7 *
8 * Andy Adamson <andros@umich.edu>
9 * J. Bruce Fields <bfields@umich.edu>
10 * Marius Aamodt Eriksen <marius@umich.edu>
11 */
12
13/*
14 * slave/kprop.c
15 *
16 * Copyright 1990,1991 by the Massachusetts Institute of Technology.
17 * All Rights Reserved.
18 *
19 * Export of this software from the United States of America may
20 * require a specific license from the United States Government.
21 * It is the responsibility of any person or organization contemplating
22 * export to obtain such a license before exporting.
23 *
24 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
25 * distribute this software and its documentation for any purpose and
26 * without fee is hereby granted, provided that the above copyright
27 * notice appear in all copies and that both that copyright notice and
28 * this permission notice appear in supporting documentation, and that
29 * the name of M.I.T. not be used in advertising or publicity pertaining
30 * to distribution of the software without specific, written prior
31 * permission. Furthermore if you modify this software you must label
32 * your software as modified software and not distribute it in such a
33 * fashion that it might be confused with the original M.I.T. software.
34 * M.I.T. makes no representations about the suitability of
35 * this software for any purpose. It is provided "as is" without express
36 * or implied warranty.
37 */
38
39/*
40 * Copyright 1994 by OpenVision Technologies, Inc.
41 *
42 * Permission to use, copy, modify, distribute, and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appears in all copies and
45 * that both that copyright notice and this permission notice appear in
46 * supporting documentation, and that the name of OpenVision not be used
47 * in advertising or publicity pertaining to distribution of the software
48 * without specific, written prior permission. OpenVision makes no
49 * representations about the suitability of this software for any
50 * purpose. It is provided "as is" without express or implied warranty.
51 *
52 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
53 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
54 * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
55 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
56 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
57 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
58 * PERFORMANCE OF THIS SOFTWARE.
59 */
60
61#ifdef HAVE_CONFIG_H
62#include <config.h>
63#endif /* HAVE_CONFIG_H */
64
65#include <errno.h>
66#include <stdio.h>
67#include <ctype.h>
68#include <sys/file.h>
69#include <signal.h>
70#include <string.h>
71#include <sys/types.h>
72#include <sys/time.h>
73#include <sys/stat.h>
74#include <sys/socket.h>
75#include <netinet/in.h>
76#include <sys/param.h>
77#include <netdb.h>
78#include <fcntl.h>
79#include <gssapi/gssapi.h>
80#if defined(HAVE_KRB5) && !defined(GSS_C_NT_HOSTBASED_SERVICE)
81#include <gssapi/gssapi_generic.h>
82#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
83#endif
84#include "gss_util.h"
85#include "err_util.h"
86#include "gssd.h"
87#ifdef HAVE_UNISTD_H
88#include <unistd.h>
89#endif
90#include <stdlib.h>
91#ifdef HAVE_COM_ERR_H
92#include <com_err.h>
93#endif
94
95/* Global gssd_credentials handle */
96gss_cred_id_t gssd_creds;
97
98gss_OID g_mechOid = GSS_C_NULL_OID;;
99
100#if 0
101static void
102display_status_1(char *m, u_int32_t code, int type, const gss_OID mech)
103{
104 u_int32_t maj_stat, min_stat;
105 gss_buffer_desc msg = GSS_C_EMPTY_BUFFER;
106 u_int32_t msg_ctx = 0;
107 char *typestr;
108
109 switch (type) {
110 case GSS_C_GSS_CODE:
111 typestr = "GSS";
112 break;
113 case GSS_C_MECH_CODE:
114 typestr = "mechanism";
115 break;
116 default:
117 return;
118 /* NOTREACHED */
119 }
120
121 for (;;) {
122 maj_stat = gss_display_status(&min_stat, code,
123 type, mech, &msg_ctx, &msg);
124 if (maj_stat != GSS_S_COMPLETE) {
125 printerr(0, "ERROR: in call to "
126 "gss_display_status called from %s\n", m);
127 break;
128 } else {
129 printerr(0, "ERROR: GSS-API: (%s) error in %s(): %s\n",
130 typestr, m, (char *)msg.value);
131 }
132
133 if (msg.length != 0)
134 (void) gss_release_buffer(&min_stat, &msg);
135
136 if (msg_ctx == 0)
137 break;
138 }
139}
140#endif
141static char *
142gss_display_error(OM_uint32 status)
143{
144 char *error = NULL;
145
146 switch(status) {
147 case GSS_S_COMPLETE:
148 error = "GSS_S_COMPLETE";
149 break;
150 case GSS_S_CALL_INACCESSIBLE_READ:
151 error = "GSS_S_CALL_INACCESSIBLE_READ";
152 break;
153 case GSS_S_CALL_INACCESSIBLE_WRITE:
154 error = "GSS_S_CALL_INACCESSIBLE_WRITE";
155 break;
156 case GSS_S_CALL_BAD_STRUCTURE:
157 error = "GSS_S_CALL_BAD_STRUCTURE";
158 break;
159 case GSS_S_BAD_MECH:
160 error = "GSS_S_BAD_MECH";
161 break;
162 case GSS_S_BAD_NAME:
163 error = "GSS_S_BAD_NAME";
164 break;
165 case GSS_S_BAD_NAMETYPE:
166 error = "GSS_S_BAD_NAMETYPE";
167 break;
168 case GSS_S_BAD_BINDINGS:
169 error = "GSS_S_BAD_BINDINGS";
170 break;
171 case GSS_S_BAD_STATUS:
172 error = "GSS_S_BAD_STATUS";
173 break;
174 case GSS_S_BAD_SIG:
175 error = "GSS_S_BAD_SIG";
176 break;
177 case GSS_S_NO_CRED:
178 error = "GSS_S_NO_CRED";
179 break;
180 case GSS_S_NO_CONTEXT:
181 error = "GSS_S_NO_CONTEXT";
182 break;
183 case GSS_S_DEFECTIVE_TOKEN:
184 error = "GSS_S_DEFECTIVE_TOKEN";
185 break;
186 case GSS_S_DEFECTIVE_CREDENTIAL:
187 error = "GSS_S_DEFECTIVE_CREDENTIAL";
188 break;
189 case GSS_S_CREDENTIALS_EXPIRED:
190 error = "GSS_S_CREDENTIALS_EXPIRED";
191 break;
192 case GSS_S_CONTEXT_EXPIRED:
193 error = "GSS_S_CONTEXT_EXPIRED";
194 break;
195 case GSS_S_FAILURE:
196 error = "GSS_S_FAILURE";
197 break;
198 case GSS_S_BAD_QOP:
199 error = "GSS_S_BAD_QOP";
200 break;
201 case GSS_S_UNAUTHORIZED:
202 error = "GSS_S_UNAUTHORIZED";
203 break;
204 case GSS_S_UNAVAILABLE:
205 error = "GSS_S_UNAVAILABLE";
206 break;
207 case GSS_S_DUPLICATE_ELEMENT:
208 error = "GSS_S_DUPLICATE_ELEMENT";
209 break;
210 case GSS_S_NAME_NOT_MN:
211 error = "GSS_S_NAME_NOT_MN";
212 break;
213 default:
214 error = "Not defined";
215 }
216 return error;
217}
218
219static void
220display_status_2(char *m, u_int32_t major, u_int32_t minor, const gss_OID mech)
221{
222 u_int32_t maj_stat1, min_stat1;
223 u_int32_t maj_stat2, min_stat2;
224 gss_buffer_desc maj_gss_buf = GSS_C_EMPTY_BUFFER;
225 gss_buffer_desc min_gss_buf = GSS_C_EMPTY_BUFFER;
226 char maj_buf[30], min_buf[30];
227 char *maj, *min;
228 u_int32_t msg_ctx = 0;
229 int msg_verbosity = 0;
230
231 /* Get major status message */
232 maj_stat1 = gss_display_status(&min_stat1, major,
233 GSS_C_GSS_CODE, mech, &msg_ctx, &maj_gss_buf);
234
235 if (maj_stat1 != GSS_S_COMPLETE) {
236 snprintf(maj_buf, sizeof(maj_buf), "(0x%08x)", major);
237 maj = &maj_buf[0];
238 } else {
239 maj = maj_gss_buf.value;
240 }
241
242 /* Get minor status message */
243 maj_stat2 = gss_display_status(&min_stat2, minor,
244 GSS_C_MECH_CODE, mech, &msg_ctx, &min_gss_buf);
245
246 if (maj_stat2 != GSS_S_COMPLETE) {
247 snprintf(min_buf, sizeof(min_buf), "(0x%08x)", minor);
248 min = &min_buf[0];
249 } else {
250 min = min_gss_buf.value;
251 }
252
253 if (major == GSS_S_CREDENTIALS_EXPIRED)
254 msg_verbosity = 1;
255
256 printerr(msg_verbosity, "ERROR: GSS-API: error in %s(): %s (%s) - %s\n",
257 m, gss_display_error(major), maj, min);
258
259 if (maj_gss_buf.length != 0)
260 (void) gss_release_buffer(&min_stat1, &maj_gss_buf);
261 if (min_gss_buf.length != 0)
262 (void) gss_release_buffer(&min_stat2, &min_gss_buf);
263}
264
265void
266pgsserr(char *msg, u_int32_t maj_stat, u_int32_t min_stat, const gss_OID mech)
267{
268 display_status_2(msg, maj_stat, min_stat, mech);
269}
270
271int
272gssd_acquire_cred(char *server_name, const gss_OID oid)
273{
274 gss_buffer_desc name;
275 gss_name_t target_name;
276 u_int32_t maj_stat, min_stat;
277 u_int32_t ignore_maj_stat, ignore_min_stat;
278 gss_buffer_desc pbuf;
279
280 /* If server_name is NULL, get cred for GSS_C_NO_NAME */
281 if (server_name == NULL) {
282 target_name = GSS_C_NO_NAME;
283 } else {
284 name.value = (void *)server_name;
285 name.length = strlen(server_name);
286
287 maj_stat = gss_import_name(&min_stat, &name,
288 oid,
289 &target_name);
290
291 if (maj_stat != GSS_S_COMPLETE) {
292 pgsserr("gss_import_name", maj_stat, min_stat, g_mechOid);
293 return (FALSE);
294 }
295 }
296
297 maj_stat = gss_acquire_cred(&min_stat, target_name, GSS_C_INDEFINITE,
298 GSS_C_NO_OID_SET, GSS_C_ACCEPT,
299 &gssd_creds, NULL, NULL);
300
301 if (maj_stat != GSS_S_COMPLETE) {
302 pgsserr("gss_acquire_cred", maj_stat, min_stat, g_mechOid);
303 ignore_maj_stat = gss_display_name(&ignore_min_stat,
304 target_name, &pbuf, NULL);
305 if (ignore_maj_stat == GSS_S_COMPLETE) {
306 printerr(1, "Unable to obtain credentials for '%.*s'\n",
307 pbuf.length, pbuf.value);
308 ignore_maj_stat = gss_release_buffer(&ignore_min_stat,
309 &pbuf);
310 }
311 }
312
313 ignore_maj_stat = gss_release_name(&ignore_min_stat, &target_name);
314
315 return (maj_stat == GSS_S_COMPLETE);
316}
317
318int gssd_check_mechs(void)
319{
320 u_int32_t maj_stat, min_stat;
321 gss_OID_set supported_mechs = GSS_C_NO_OID_SET;
322 int retval = -1;
323
324 maj_stat = gss_indicate_mechs(&min_stat, &supported_mechs);
325 if (maj_stat != GSS_S_COMPLETE) {
326 printerr(0, "Unable to obtain list of supported mechanisms. "
327 "Check that gss library is properly configured.\n");
328 goto out;
329 }
330 if (supported_mechs == GSS_C_NO_OID_SET ||
331 supported_mechs->count == 0) {
332 printerr(0, "Unable to obtain list of supported mechanisms. "
333 "Check that gss library is properly configured.\n");
334 goto out;
335 }
336 maj_stat = gss_release_oid_set(&min_stat, &supported_mechs);
337 retval = 0;
338out:
339 return retval;
340}
341
3420
=== removed file '.pc/11-532048-reduce-verbosity.patch/utils/gssd/gssd_proc.c'
--- .pc/11-532048-reduce-verbosity.patch/utils/gssd/gssd_proc.c 2012-05-25 20:41:58 +0000
+++ .pc/11-532048-reduce-verbosity.patch/utils/gssd/gssd_proc.c 1970-01-01 00:00:00 +0000
@@ -1,1241 +0,0 @@
1/*
2 gssd_proc.c
3
4 Copyright (c) 2000-2004 The Regents of the University of Michigan.
5 All rights reserved.
6
7 Copyright (c) 2000 Dug Song <dugsong@UMICH.EDU>.
8 Copyright (c) 2001 Andy Adamson <andros@UMICH.EDU>.
9 Copyright (c) 2002 Marius Aamodt Eriksen <marius@UMICH.EDU>.
10 Copyright (c) 2002 Bruce Fields <bfields@UMICH.EDU>
11 Copyright (c) 2004 Kevin Coffman <kwc@umich.edu>
12 All rights reserved, all wrongs reversed.
13
14 Redistribution and use in source and binary forms, with or without
15 modification, are permitted provided that the following conditions
16 are met:
17
18 1. Redistributions of source code must retain the above copyright
19 notice, this list of conditions and the following disclaimer.
20 2. Redistributions in binary form must reproduce the above copyright
21 notice, this list of conditions and the following disclaimer in the
22 documentation and/or other materials provided with the distribution.
23 3. Neither the name of the University nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without specific prior written permission.
26
27 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
28 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
29 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
34 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39*/
40
41#ifdef HAVE_CONFIG_H
42#include <config.h>
43#endif /* HAVE_CONFIG_H */
44
45#ifndef _GNU_SOURCE
46#define _GNU_SOURCE
47#endif
48
49#include <sys/param.h>
50#include <rpc/rpc.h>
51#include <sys/stat.h>
52#include <sys/socket.h>
53#include <arpa/inet.h>
54#include <sys/fsuid.h>
55
56#include <stdio.h>
57#include <stdlib.h>
58#include <pwd.h>
59#include <grp.h>
60#include <string.h>
61#include <dirent.h>
62#include <poll.h>
63#include <fcntl.h>
64#include <signal.h>
65#include <unistd.h>
66#include <errno.h>
67#include <gssapi/gssapi.h>
68#include <netdb.h>
69
70#include "gssd.h"
71#include "err_util.h"
72#include "gss_util.h"
73#include "krb5_util.h"
74#include "context.h"
75#include "nfsrpc.h"
76#include "nfslib.h"
77
78/*
79 * pollarray:
80 * array of struct pollfd suitable to pass to poll. initialized to
81 * zero - a zero struct is ignored by poll() because the events mask is 0.
82 *
83 * clnt_list:
84 * linked list of struct clnt_info which associates a clntXXX directory
85 * with an index into pollarray[], and other basic data about that client.
86 *
87 * Directory structure: created by the kernel
88 * {rpc_pipefs}/{dir}/clntXX : one per rpc_clnt struct in the kernel
89 * {rpc_pipefs}/{dir}/clntXX/krb5 : read uid for which kernel wants
90 * a context, write the resulting context
91 * {rpc_pipefs}/{dir}/clntXX/info : stores info such as server name
92 * {rpc_pipefs}/{dir}/clntXX/gssd : pipe for all gss mechanisms using
93 * a text-based string of parameters
94 *
95 * Algorithm:
96 * Poll all {rpc_pipefs}/{dir}/clntXX/YYYY files. When data is ready,
97 * read and process; performs rpcsec_gss context initialization protocol to
98 * get a cred for that user. Writes result to corresponding krb5 file
99 * in a form the kernel code will understand.
100 * In addition, we make sure we are notified whenever anything is
101 * created or destroyed in {rpc_pipefs} or in any of the clntXX directories,
102 * and rescan the whole {rpc_pipefs} when this happens.
103 */
104
105struct pollfd * pollarray;
106
107int pollsize; /* the size of pollaray (in pollfd's) */
108
109/*
110 * convert a presentation address string to a sockaddr_storage struct. Returns
111 * true on success or false on failure.
112 *
113 * Note that we do not populate the sin6_scope_id field here for IPv6 addrs.
114 * gssd nececessarily relies on hostname resolution and DNS AAAA records
115 * do not generally contain scope-id's. This means that GSSAPI auth really
116 * can't work with IPv6 link-local addresses.
117 *
118 * We *could* consider changing this if we did something like adopt the
119 * Microsoft "standard" of using the ipv6-literal.net domainname, but it's
120 * not really feasible at present.
121 */
122static int
123addrstr_to_sockaddr(struct sockaddr *sa, const char *node, const char *port)
124{
125 int rc;
126 struct addrinfo *res;
127 struct addrinfo hints = { .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV };
128
129#ifndef IPV6_SUPPORTED
130 hints.ai_family = AF_INET;
131#endif /* IPV6_SUPPORTED */
132
133 rc = getaddrinfo(node, port, &hints, &res);
134 if (rc) {
135 printerr(0, "ERROR: unable to convert %s|%s to sockaddr: %s\n",
136 node, port, rc == EAI_SYSTEM ? strerror(errno) :
137 gai_strerror(rc));
138 return 0;
139 }
140
141#ifdef IPV6_SUPPORTED
142 /*
143 * getnameinfo ignores the scopeid. If the address turns out to have
144 * a non-zero scopeid, we can't use it -- the resolved host might be
145 * completely different from the one intended.
146 */
147 if (res->ai_addr->sa_family == AF_INET6) {
148 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)res->ai_addr;
149 if (sin6->sin6_scope_id) {
150 printerr(0, "ERROR: address %s has non-zero "
151 "sin6_scope_id!\n", node);
152 freeaddrinfo(res);
153 return 0;
154 }
155 }
156#endif /* IPV6_SUPPORTED */
157
158 memcpy(sa, res->ai_addr, res->ai_addrlen);
159 freeaddrinfo(res);
160 return 1;
161}
162
163/*
164 * convert a sockaddr to a hostname
165 */
166static char *
167sockaddr_to_hostname(const struct sockaddr *sa, const char *addr)
168{
169 socklen_t addrlen;
170 int err;
171 char *hostname;
172 char hbuf[NI_MAXHOST];
173
174 switch (sa->sa_family) {
175 case AF_INET:
176 addrlen = sizeof(struct sockaddr_in);
177 break;
178#ifdef IPV6_SUPPORTED
179 case AF_INET6:
180 addrlen = sizeof(struct sockaddr_in6);
181 break;
182#endif /* IPV6_SUPPORTED */
183 default:
184 printerr(0, "ERROR: unrecognized addr family %d\n",
185 sa->sa_family);
186 return NULL;
187 }
188
189 err = getnameinfo(sa, addrlen, hbuf, sizeof(hbuf), NULL, 0,
190 NI_NAMEREQD);
191 if (err) {
192 printerr(0, "ERROR: unable to resolve %s to hostname: %s\n",
193 addr, err == EAI_SYSTEM ? strerror(err) :
194 gai_strerror(err));
195 return NULL;
196 }
197
198 hostname = strdup(hbuf);
199
200 return hostname;
201}
202
203/* XXX buffer problems: */
204static int
205read_service_info(char *info_file_name, char **servicename, char **servername,
206 int *prog, int *vers, char **protocol,
207 struct sockaddr *addr) {
208#define INFOBUFLEN 256
209 char buf[INFOBUFLEN + 1];
210 static char dummy[128];
211 int nbytes;
212 static char service[128];
213 static char address[128];
214 char program[16];
215 char version[16];
216 char protoname[16];
217 char port[128];
218 char *p;
219 int fd = -1;
220 int numfields;
221
222 *servicename = *servername = *protocol = NULL;
223
224 if ((fd = open(info_file_name, O_RDONLY)) == -1) {
225 printerr(0, "ERROR: can't open %s: %s\n", info_file_name,
226 strerror(errno));
227 goto fail;
228 }
229 if ((nbytes = read(fd, buf, INFOBUFLEN)) == -1)
230 goto fail;
231 close(fd);
232 buf[nbytes] = '\0';
233
234 numfields = sscanf(buf,"RPC server: %127s\n"
235 "service: %127s %15s version %15s\n"
236 "address: %127s\n"
237 "protocol: %15s\n",
238 dummy,
239 service, program, version,
240 address,
241 protoname);
242
243 if (numfields == 5) {
244 strcpy(protoname, "tcp");
245 } else if (numfields != 6) {
246 goto fail;
247 }
248
249 port[0] = '\0';
250 if ((p = strstr(buf, "port")) != NULL)
251 sscanf(p, "port: %127s\n", port);
252
253 /* check service, program, and version */
254 if (memcmp(service, "nfs", 3) != 0)
255 return -1;
256 *prog = atoi(program + 1); /* skip open paren */
257 *vers = atoi(version);
258
259 if (strlen(service) == 3 ) {
260 if ((*prog != 100003) || ((*vers != 2) && (*vers != 3) &&
261 (*vers != 4)))
262 goto fail;
263 } else if (memcmp(service, "nfs4_cb", 7) == 0) {
264 if (*vers != 1)
265 goto fail;
266 }
267
268 if (!addrstr_to_sockaddr(addr, address, port))
269 goto fail;
270
271 *servername = sockaddr_to_hostname(addr, address);
272 if (*servername == NULL)
273 goto fail;
274
275 nbytes = snprintf(buf, INFOBUFLEN, "%s@%s", service, *servername);
276 if (nbytes > INFOBUFLEN)
277 goto fail;
278
279 if (!(*servicename = calloc(strlen(buf) + 1, 1)))
280 goto fail;
281 memcpy(*servicename, buf, strlen(buf));
282
283 if (!(*protocol = strdup(protoname)))
284 goto fail;
285 return 0;
286fail:
287 printerr(0, "ERROR: failed to read service info\n");
288 if (fd != -1) close(fd);
289 free(*servername);
290 free(*servicename);
291 free(*protocol);
292 *servicename = *servername = *protocol = NULL;
293 return -1;
294}
295
296static void
297destroy_client(struct clnt_info *clp)
298{
299 if (clp->krb5_poll_index != -1)
300 memset(&pollarray[clp->krb5_poll_index], 0,
301 sizeof(struct pollfd));
302 if (clp->gssd_poll_index != -1)
303 memset(&pollarray[clp->gssd_poll_index], 0,
304 sizeof(struct pollfd));
305 if (clp->dir_fd != -1) close(clp->dir_fd);
306 if (clp->krb5_fd != -1) close(clp->krb5_fd);
307 if (clp->gssd_fd != -1) close(clp->gssd_fd);
308 free(clp->dirname);
309 free(clp->servicename);
310 free(clp->servername);
311 free(clp->protocol);
312 free(clp);
313}
314
315static struct clnt_info *
316insert_new_clnt(void)
317{
318 struct clnt_info *clp = NULL;
319
320 if (!(clp = (struct clnt_info *)calloc(1,sizeof(struct clnt_info)))) {
321 printerr(0, "ERROR: can't malloc clnt_info: %s\n",
322 strerror(errno));
323 goto out;
324 }
325 clp->krb5_poll_index = -1;
326 clp->gssd_poll_index = -1;
327 clp->krb5_fd = -1;
328 clp->gssd_fd = -1;
329 clp->dir_fd = -1;
330
331 TAILQ_INSERT_HEAD(&clnt_list, clp, list);
332out:
333 return clp;
334}
335
336static int
337process_clnt_dir_files(struct clnt_info * clp)
338{
339 char name[PATH_MAX];
340 char gname[PATH_MAX];
341 char info_file_name[PATH_MAX];
342
343 if (clp->gssd_fd == -1) {
344 snprintf(gname, sizeof(gname), "%s/gssd", clp->dirname);
345 clp->gssd_fd = open(gname, O_RDWR);
346 }
347 if (clp->gssd_fd == -1) {
348 if (clp->krb5_fd == -1) {
349 snprintf(name, sizeof(name), "%s/krb5", clp->dirname);
350 clp->krb5_fd = open(name, O_RDWR);
351 }
352
353 /* If we opened a gss-specific pipe, let's try opening
354 * the new upcall pipe again. If we succeed, close
355 * gss-specific pipe(s).
356 */
357 if (clp->krb5_fd != -1) {
358 clp->gssd_fd = open(gname, O_RDWR);
359 if (clp->gssd_fd != -1) {
360 if (clp->krb5_fd != -1)
361 close(clp->krb5_fd);
362 clp->krb5_fd = -1;
363 }
364 }
365 }
366
367 if ((clp->krb5_fd == -1) && (clp->gssd_fd == -1))
368 return -1;
369 snprintf(info_file_name, sizeof(info_file_name), "%s/info",
370 clp->dirname);
371 if ((clp->servicename == NULL) &&
372 read_service_info(info_file_name, &clp->servicename,
373 &clp->servername, &clp->prog, &clp->vers,
374 &clp->protocol, (struct sockaddr *) &clp->addr))
375 return -1;
376 return 0;
377}
378
379static int
380get_poll_index(int *ind)
381{
382 int i;
383
384 *ind = -1;
385 for (i=0; i<FD_ALLOC_BLOCK; i++) {
386 if (pollarray[i].events == 0) {
387 *ind = i;
388 break;
389 }
390 }
391 if (*ind == -1) {
392 printerr(0, "ERROR: No pollarray slots open\n");
393 return -1;
394 }
395 return 0;
396}
397
398
399static int
400insert_clnt_poll(struct clnt_info *clp)
401{
402 if ((clp->gssd_fd != -1) && (clp->gssd_poll_index == -1)) {
403 if (get_poll_index(&clp->gssd_poll_index)) {
404 printerr(0, "ERROR: Too many gssd clients\n");
405 return -1;
406 }
407 pollarray[clp->gssd_poll_index].fd = clp->gssd_fd;
408 pollarray[clp->gssd_poll_index].events |= POLLIN;
409 }
410
411 if ((clp->krb5_fd != -1) && (clp->krb5_poll_index == -1)) {
412 if (get_poll_index(&clp->krb5_poll_index)) {
413 printerr(0, "ERROR: Too many krb5 clients\n");
414 return -1;
415 }
416 pollarray[clp->krb5_poll_index].fd = clp->krb5_fd;
417 pollarray[clp->krb5_poll_index].events |= POLLIN;
418 }
419
420 return 0;
421}
422
423static void
424process_clnt_dir(char *dir, char *pdir)
425{
426 struct clnt_info * clp;
427
428 if (!(clp = insert_new_clnt()))
429 goto fail_destroy_client;
430
431 /* An extra for the '/', and an extra for the null */
432 if (!(clp->dirname = calloc(strlen(dir) + strlen(pdir) + 2, 1))) {
433 goto fail_destroy_client;
434 }
435 sprintf(clp->dirname, "%s/%s", pdir, dir);
436 if ((clp->dir_fd = open(clp->dirname, O_RDONLY)) == -1) {
437 printerr(0, "ERROR: can't open %s: %s\n",
438 clp->dirname, strerror(errno));
439 goto fail_destroy_client;
440 }
441 fcntl(clp->dir_fd, F_SETSIG, DNOTIFY_SIGNAL);
442 fcntl(clp->dir_fd, F_NOTIFY, DN_CREATE | DN_DELETE | DN_MULTISHOT);
443
444 if (process_clnt_dir_files(clp))
445 goto fail_keep_client;
446
447 if (insert_clnt_poll(clp))
448 goto fail_destroy_client;
449
450 return;
451
452fail_destroy_client:
453 if (clp) {
454 TAILQ_REMOVE(&clnt_list, clp, list);
455 destroy_client(clp);
456 }
457fail_keep_client:
458 /* We couldn't find some subdirectories, but we keep the client
459 * around in case we get a notification on the directory when the
460 * subdirectories are created. */
461 return;
462}
463
464void
465init_client_list(void)
466{
467 TAILQ_INIT(&clnt_list);
468 /* Eventually plan to grow/shrink poll array: */
469 pollsize = FD_ALLOC_BLOCK;
470 pollarray = calloc(pollsize, sizeof(struct pollfd));
471}
472
473/*
474 * This is run after a DNOTIFY signal, and should clear up any
475 * directories that are no longer around, and re-scan any existing
476 * directories, since the DNOTIFY could have been in there.
477 */
478static void
479update_old_clients(struct dirent **namelist, int size, char *pdir)
480{
481 struct clnt_info *clp;
482 void *saveprev;
483 int i, stillhere;
484 char fname[PATH_MAX];
485
486 for (clp = clnt_list.tqh_first; clp != NULL; clp = clp->list.tqe_next) {
487 /* only compare entries in the global list that are from the
488 * same pipefs parent directory as "pdir"
489 */
490 if (strncmp(clp->dirname, pdir, strlen(pdir)) != 0) continue;
491
492 stillhere = 0;
493 for (i=0; i < size; i++) {
494 snprintf(fname, sizeof(fname), "%s/%s",
495 pdir, namelist[i]->d_name);
496 if (strcmp(clp->dirname, fname) == 0) {
497 stillhere = 1;
498 break;
499 }
500 }
501 if (!stillhere) {
502 printerr(2, "destroying client %s\n", clp->dirname);
503 saveprev = clp->list.tqe_prev;
504 TAILQ_REMOVE(&clnt_list, clp, list);
505 destroy_client(clp);
506 clp = saveprev;
507 }
508 }
509 for (clp = clnt_list.tqh_first; clp != NULL; clp = clp->list.tqe_next) {
510 if (!process_clnt_dir_files(clp))
511 insert_clnt_poll(clp);
512 }
513}
514
515/* Search for a client by directory name, return 1 if found, 0 otherwise */
516static int
517find_client(char *dirname, char *pdir)
518{
519 struct clnt_info *clp;
520 char fname[PATH_MAX];
521
522 for (clp = clnt_list.tqh_first; clp != NULL; clp = clp->list.tqe_next) {
523 snprintf(fname, sizeof(fname), "%s/%s", pdir, dirname);
524 if (strcmp(clp->dirname, fname) == 0)
525 return 1;
526 }
527 return 0;
528}
529
530static int
531process_pipedir(char *pipe_name)
532{
533 struct dirent **namelist;
534 int i, j;
535
536 if (chdir(pipe_name) < 0) {
537 printerr(0, "ERROR: can't chdir to %s: %s\n",
538 pipe_name, strerror(errno));
539 return -1;
540 }
541
542 j = scandir(pipe_name, &namelist, NULL, alphasort);
543 if (j < 0) {
544 printerr(0, "ERROR: can't scandir %s: %s\n",
545 pipe_name, strerror(errno));
546 return -1;
547 }
548
549 update_old_clients(namelist, j, pipe_name);
550 for (i=0; i < j; i++) {
551 if (i < FD_ALLOC_BLOCK
552 && !strncmp(namelist[i]->d_name, "clnt", 4)
553 && !find_client(namelist[i]->d_name, pipe_name))
554 process_clnt_dir(namelist[i]->d_name, pipe_name);
555 free(namelist[i]);
556 }
557
558 free(namelist);
559
560 return 0;
561}
562
563/* Used to read (and re-read) list of clients, set up poll array. */
564int
565update_client_list(void)
566{
567 int retval = -1;
568 struct topdirs_info *tdi;
569
570 TAILQ_FOREACH(tdi, &topdirs_list, list) {
571 retval = process_pipedir(tdi->dirname);
572 if (retval)
573 printerr(1, "WARNING: error processing %s\n",
574 tdi->dirname);
575
576 }
577 return retval;
578}
579
580/* Encryption types supported by the kernel rpcsec_gss code */
581int num_krb5_enctypes = 0;
582krb5_enctype *krb5_enctypes = NULL;
583
584/*
585 * Parse the supported encryption type information
586 */
587static int
588parse_enctypes(char *enctypes)
589{
590 int n = 0;
591 char *curr, *comma;
592 int i;
593 static char *cached_types;
594
595 if (cached_types && strcmp(cached_types, enctypes) == 0)
596 return 0;
597 free(cached_types);
598
599 if (krb5_enctypes != NULL) {
600 free(krb5_enctypes);
601 krb5_enctypes = NULL;
602 num_krb5_enctypes = 0;
603 }
604
605 /* count the number of commas */
606 for (curr = enctypes; curr && *curr != '\0'; curr = ++comma) {
607 comma = strchr(curr, ',');
608 if (comma != NULL)
609 n++;
610 else
611 break;
612 }
613 /* If no more commas and we're not at the end, there's one more value */
614 if (*curr != '\0')
615 n++;
616
617 /* Empty string, return an error */
618 if (n == 0)
619 return ENOENT;
620
621 /* Allocate space for enctypes array */
622 if ((krb5_enctypes = (int *) calloc(n, sizeof(int))) == NULL) {
623 return ENOMEM;
624 }
625
626 /* Now parse each value into the array */
627 for (curr = enctypes, i = 0; curr && *curr != '\0'; curr = ++comma) {
628 krb5_enctypes[i++] = atoi(curr);
629 comma = strchr(curr, ',');
630 if (comma == NULL)
631 break;
632 }
633
634 num_krb5_enctypes = n;
635 if ((cached_types = malloc(strlen(enctypes)+1)))
636 strcpy(cached_types, enctypes);
637
638 return 0;
639}
640
641static int
642do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd,
643 gss_buffer_desc *context_token)
644{
645 char *buf = NULL, *p = NULL, *end = NULL;
646 unsigned int timeout = context_timeout;
647 unsigned int buf_size = 0;
648
649 printerr(1, "doing downcall\n");
650 buf_size = sizeof(uid) + sizeof(timeout) + sizeof(pd->pd_seq_win) +
651 sizeof(pd->pd_ctx_hndl.length) + pd->pd_ctx_hndl.length +
652 sizeof(context_token->length) + context_token->length;
653 p = buf = malloc(buf_size);
654 end = buf + buf_size;
655
656 if (WRITE_BYTES(&p, end, uid)) goto out_err;
657 if (WRITE_BYTES(&p, end, timeout)) goto out_err;
658 if (WRITE_BYTES(&p, end, pd->pd_seq_win)) goto out_err;
659 if (write_buffer(&p, end, &pd->pd_ctx_hndl)) goto out_err;
660 if (write_buffer(&p, end, context_token)) goto out_err;
661
662 if (write(k5_fd, buf, p - buf) < p - buf) goto out_err;
663 if (buf) free(buf);
664 return 0;
665out_err:
666 if (buf) free(buf);
667 printerr(1, "Failed to write downcall!\n");
668 return -1;
669}
670
671static int
672do_error_downcall(int k5_fd, uid_t uid, int err)
673{
674 char buf[1024];
675 char *p = buf, *end = buf + 1024;
676 unsigned int timeout = 0;
677 int zero = 0;
678
679 printerr(1, "doing error downcall\n");
680
681 if (WRITE_BYTES(&p, end, uid)) goto out_err;
682 if (WRITE_BYTES(&p, end, timeout)) goto out_err;
683 /* use seq_win = 0 to indicate an error: */
684 if (WRITE_BYTES(&p, end, zero)) goto out_err;
685 if (WRITE_BYTES(&p, end, err)) goto out_err;
686
687 if (write(k5_fd, buf, p - buf) < p - buf) goto out_err;
688 return 0;
689out_err:
690 printerr(1, "Failed to write error downcall!\n");
691 return -1;
692}
693
694/*
695 * If the port isn't already set, do an rpcbind query to the remote server
696 * using the program and version and get the port.
697 *
698 * Newer kernels send the value of the port= mount option in the "info"
699 * file for the upcall or '0' for NFSv2/3. For NFSv4 it sends the value
700 * of the port= option or '2049'. The port field in a new sockaddr should
701 * reflect the value that was sent by the kernel.
702 */
703static int
704populate_port(struct sockaddr *sa, const socklen_t salen,
705 const rpcprog_t program, const rpcvers_t version,
706 const unsigned short protocol)
707{
708 struct sockaddr_in *s4 = (struct sockaddr_in *) sa;
709#ifdef IPV6_SUPPORTED
710 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa;
711#endif /* IPV6_SUPPORTED */
712 unsigned short port;
713
714 /*
715 * Newer kernels send the port in the upcall. If we already have
716 * the port, there's no need to look it up.
717 */
718 switch (sa->sa_family) {
719 case AF_INET:
720 if (s4->sin_port != 0) {
721 printerr(2, "DEBUG: port already set to %d\n",
722 ntohs(s4->sin_port));
723 return 1;
724 }
725 break;
726#ifdef IPV6_SUPPORTED
727 case AF_INET6:
728 if (s6->sin6_port != 0) {
729 printerr(2, "DEBUG: port already set to %d\n",
730 ntohs(s6->sin6_port));
731 return 1;
732 }
733 break;
734#endif /* IPV6_SUPPORTED */
735 default:
736 printerr(0, "ERROR: unsupported address family %d\n",
737 sa->sa_family);
738 return 0;
739 }
740
741 /*
742 * Newer kernels that send the port in the upcall set the value to
743 * 2049 for NFSv4 mounts when one isn't specified. The check below is
744 * only for kernels that don't send the port in the upcall. For those
745 * we either have to do an rpcbind query or set it to the standard
746 * port. Doing a query could be problematic (firewalls, etc), so take
747 * the latter approach.
748 */
749 if (program == 100003 && version == 4) {
750 port = 2049;
751 goto set_port;
752 }
753
754 port = nfs_getport(sa, salen, program, version, protocol);
755 if (!port) {
756 printerr(0, "ERROR: unable to obtain port for prog %ld "
757 "vers %ld\n", program, version);
758 return 0;
759 }
760
761set_port:
762 printerr(2, "DEBUG: setting port to %hu for prog %lu vers %lu\n", port,
763 program, version);
764
765 switch (sa->sa_family) {
766 case AF_INET:
767 s4->sin_port = htons(port);
768 break;
769#ifdef IPV6_SUPPORTED
770 case AF_INET6:
771 s6->sin6_port = htons(port);
772 break;
773#endif /* IPV6_SUPPORTED */
774 }
775
776 return 1;
777}
778
779/*
780 * Create an RPC connection and establish an authenticated
781 * gss context with a server.
782 */
783int create_auth_rpc_client(struct clnt_info *clp,
784 CLIENT **clnt_return,
785 AUTH **auth_return,
786 uid_t uid,
787 int authtype)
788{
789 CLIENT *rpc_clnt = NULL;
790 struct rpc_gss_sec sec;
791 AUTH *auth = NULL;
792 uid_t save_uid = -1;
793 int retval = -1;
794 OM_uint32 min_stat;
795 char rpc_errmsg[1024];
796 int protocol;
797 struct timeval timeout = {5, 0};
798 struct sockaddr *addr = (struct sockaddr *) &clp->addr;
799 socklen_t salen;
800
801 /* Create the context as the user (not as root) */
802 save_uid = geteuid();
803 if (setfsuid(uid) != 0) {
804 printerr(0, "WARNING: Failed to setfsuid for "
805 "user with uid %d\n", uid);
806 goto out_fail;
807 }
808 printerr(2, "creating context using fsuid %d (save_uid %d)\n",
809 uid, save_uid);
810
811 sec.qop = GSS_C_QOP_DEFAULT;
812 sec.svc = RPCSEC_GSS_SVC_NONE;
813 sec.cred = GSS_C_NO_CREDENTIAL;
814 sec.req_flags = 0;
815 if (authtype == AUTHTYPE_KRB5) {
816 sec.mech = (gss_OID)&krb5oid;
817 sec.req_flags = GSS_C_MUTUAL_FLAG;
818 }
819 else {
820 printerr(0, "ERROR: Invalid authentication type (%d) "
821 "in create_auth_rpc_client\n", authtype);
822 goto out_fail;
823 }
824
825
826 if (authtype == AUTHTYPE_KRB5) {
827#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
828 /*
829 * Do this before creating rpc connection since we won't need
830 * rpc connection if it fails!
831 */
832 if (limit_krb5_enctypes(&sec)) {
833 printerr(1, "WARNING: Failed while limiting krb5 "
834 "encryption types for user with uid %d\n",
835 uid);
836 goto out_fail;
837 }
838#endif
839 }
840
841 /* create an rpc connection to the nfs server */
842
843 printerr(2, "creating %s client for server %s\n", clp->protocol,
844 clp->servername);
845
846 if ((strcmp(clp->protocol, "tcp")) == 0) {
847 protocol = IPPROTO_TCP;
848 } else if ((strcmp(clp->protocol, "udp")) == 0) {
849 protocol = IPPROTO_UDP;
850 } else {
851 printerr(0, "WARNING: unrecognized protocol, '%s', requested "
852 "for connection to server %s for user with uid %d\n",
853 clp->protocol, clp->servername, uid);
854 goto out_fail;
855 }
856
857 switch (addr->sa_family) {
858 case AF_INET:
859 salen = sizeof(struct sockaddr_in);
860 break;
861#ifdef IPV6_SUPPORTED
862 case AF_INET6:
863 salen = sizeof(struct sockaddr_in6);
864 break;
865#endif /* IPV6_SUPPORTED */
866 default:
867 printerr(1, "ERROR: Unknown address family %d\n",
868 addr->sa_family);
869 goto out_fail;
870 }
871
872 if (!populate_port(addr, salen, clp->prog, clp->vers, protocol))
873 goto out_fail;
874
875 rpc_clnt = nfs_get_rpcclient(addr, salen, protocol, clp->prog,
876 clp->vers, &timeout);
877 if (!rpc_clnt) {
878 snprintf(rpc_errmsg, sizeof(rpc_errmsg),
879 "WARNING: can't create %s rpc_clnt to server %s for "
880 "user with uid %d",
881 protocol == IPPROTO_TCP ? "tcp" : "udp",
882 clp->servername, uid);
883 printerr(0, "%s\n",
884 clnt_spcreateerror(rpc_errmsg));
885 goto out_fail;
886 }
887
888 printerr(2, "creating context with server %s\n", clp->servicename);
889 auth = authgss_create_default(rpc_clnt, clp->servicename, &sec);
890 if (!auth) {
891 /* Our caller should print appropriate message */
892 printerr(2, "WARNING: Failed to create krb5 context for "
893 "user with uid %d for server %s\n",
894 uid, clp->servername);
895 goto out_fail;
896 }
897
898 /* Success !!! */
899 rpc_clnt->cl_auth = auth;
900 *clnt_return = rpc_clnt;
901 *auth_return = auth;
902 retval = 0;
903
904 out:
905 if (sec.cred != GSS_C_NO_CREDENTIAL)
906 gss_release_cred(&min_stat, &sec.cred);
907 /* Restore euid to original value */
908 if (((int)save_uid != -1) && (setfsuid(save_uid) != (int)uid)) {
909 printerr(0, "WARNING: Failed to restore fsuid"
910 " to uid %d from %d\n", save_uid, uid);
911 }
912 return retval;
913
914 out_fail:
915 /* Only destroy here if failure. Otherwise, caller is responsible */
916 if (rpc_clnt) clnt_destroy(rpc_clnt);
917
918 goto out;
919}
920
921static char *
922user_cachedir(char *dirname, uid_t uid)
923{
924 struct passwd *pw;
925 char *ptr;
926
927 if ((pw = getpwuid(uid)) == NULL) {
928 printerr(0, "user_cachedir: Failed to find '%d' uid"
929 " for cache directory\n");
930 return NULL;
931 }
932 ptr = malloc(strlen(dirname)+strlen(pw->pw_name)+2);
933 if (ptr)
934 sprintf(ptr, "%s/%s", dirname, pw->pw_name);
935
936 return ptr;
937}
938/*
939 * this code uses the userland rpcsec gss library to create a krb5
940 * context on behalf of the kernel
941 */
942static void
943process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
944 char *service)
945{
946 CLIENT *rpc_clnt = NULL;
947 AUTH *auth = NULL;
948 struct authgss_private_data pd;
949 gss_buffer_desc token;
950 char **credlist = NULL;
951 char **ccname;
952 char **dirname, *dir, *userdir;
953 int create_resp = -1;
954 int err, downcall_err = -EACCES;
955
956 printerr(1, "handling krb5 upcall (%s)\n", clp->dirname);
957
958 if (tgtname) {
959 if (clp->servicename) {
960 free(clp->servicename);
961 clp->servicename = strdup(tgtname);
962 }
963 }
964 token.length = 0;
965 token.value = NULL;
966 memset(&pd, 0, sizeof(struct authgss_private_data));
967
968 /*
969 * If "service" is specified, then the kernel is indicating that
970 * we must use machine credentials for this request. (Regardless
971 * of the uid value or the setting of root_uses_machine_creds.)
972 * If the service value is "*", then any service name can be used.
973 * Otherwise, it specifies the service name that should be used.
974 * (For now, the values of service will only be "*" or "nfs".)
975 *
976 * Restricting gssd to use "nfs" service name is needed for when
977 * the NFS server is doing a callback to the NFS client. In this
978 * case, the NFS server has to authenticate itself as "nfs" --
979 * even if there are other service keys such as "host" or "root"
980 * in the keytab.
981 *
982 * Another case when the kernel may specify the service attribute
983 * is when gssd is being asked to create the context for a
984 * SETCLIENT_ID operation. In this case, machine credentials
985 * must be used for the authentication. However, the service name
986 * used for this case is not important.
987 *
988 */
989 printerr(2, "%s: service is '%s'\n", __func__,
990 service ? service : "<null>");
991 if (uid != 0 || (uid == 0 && root_uses_machine_creds == 0 &&
992 service == NULL)) {
993 /* Tell krb5 gss which credentials cache to use */
994 for (dirname = ccachesearch; *dirname != NULL; dirname++) {
995 /* See if the user name is needed */
996 if (strncmp(*dirname, GSSD_USER_CRED_DIR,
997 strlen(GSSD_USER_CRED_DIR)) == 0) {
998 userdir = user_cachedir(*dirname, uid);
999 if (userdir == NULL)
1000 continue;
1001 dir = userdir;
1002 } else
1003 dir = *dirname;
1004
1005 err = gssd_setup_krb5_user_gss_ccache(uid, clp->servername, dir);
1006
1007 if (userdir) {
1008 free(userdir);
1009 userdir = NULL;
1010 }
1011 if (err == -EKEYEXPIRED)
1012 downcall_err = -EKEYEXPIRED;
1013 else if (!err)
1014 create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
1015 AUTHTYPE_KRB5);
1016 if (create_resp == 0)
1017 break;
1018 }
1019 }
1020 if (create_resp != 0) {
1021 if (uid == 0 && (root_uses_machine_creds == 1 ||
1022 service != NULL)) {
1023 int nocache = 0;
1024 int success = 0;
1025 do {
1026 gssd_refresh_krb5_machine_credential(clp->servername,
1027 NULL, service);
1028 /*
1029 * Get a list of credential cache names and try each
1030 * of them until one works or we've tried them all
1031 */
1032 if (gssd_get_krb5_machine_cred_list(&credlist)) {
1033 printerr(0, "ERROR: No credentials found "
1034 "for connection to server %s\n",
1035 clp->servername);
1036 goto out_return_error;
1037 }
1038 for (ccname = credlist; ccname && *ccname; ccname++) {
1039 gssd_setup_krb5_machine_gss_ccache(*ccname);
1040 if ((create_auth_rpc_client(clp, &rpc_clnt,
1041 &auth, uid,
1042 AUTHTYPE_KRB5)) == 0) {
1043 /* Success! */
1044 success++;
1045 break;
1046 }
1047 printerr(2, "WARNING: Failed to create machine krb5 context "
1048 "with credentials cache %s for server %s\n",
1049 *ccname, clp->servername);
1050 }
1051 gssd_free_krb5_machine_cred_list(credlist);
1052 if (!success) {
1053 if(nocache == 0) {
1054 nocache++;
1055 printerr(2, "WARNING: Machine cache is prematurely expired or corrupted "
1056 "trying to recreate cache for server %s\n", clp->servername);
1057 } else {
1058 printerr(1, "WARNING: Failed to create machine krb5 context "
1059 "with any credentials cache for server %s\n",
1060 clp->servername);
1061 goto out_return_error;
1062 }
1063 }
1064 } while(!success);
1065 } else {
1066 printerr(1, "WARNING: Failed to create krb5 context "
1067 "for user with uid %d for server %s\n",
1068 uid, clp->servername);
1069 goto out_return_error;
1070 }
1071 }
1072
1073 if (!authgss_get_private_data(auth, &pd)) {
1074 printerr(1, "WARNING: Failed to obtain authentication "
1075 "data for user with uid %d for server %s\n",
1076 uid, clp->servername);
1077 goto out_return_error;
1078 }
1079
1080 if (serialize_context_for_kernel(pd.pd_ctx, &token, &krb5oid, NULL)) {
1081 printerr(0, "WARNING: Failed to serialize krb5 context for "
1082 "user with uid %d for server %s\n",
1083 uid, clp->servername);
1084 goto out_return_error;
1085 }
1086
1087 do_downcall(fd, uid, &pd, &token);
1088
1089out:
1090 if (token.value)
1091 free(token.value);
1092#ifndef HAVE_LIBTIRPC
1093 if (pd.pd_ctx_hndl.length != 0)
1094 authgss_free_private_data(&pd);
1095#endif
1096 if (auth)
1097 AUTH_DESTROY(auth);
1098 if (rpc_clnt)
1099 clnt_destroy(rpc_clnt);
1100 return;
1101
1102out_return_error:
1103 do_error_downcall(fd, uid, downcall_err);
1104 goto out;
1105}
1106
1107void
1108handle_krb5_upcall(struct clnt_info *clp)
1109{
1110 uid_t uid;
1111
1112 if (read(clp->krb5_fd, &uid, sizeof(uid)) < (ssize_t)sizeof(uid)) {
1113 printerr(0, "WARNING: failed reading uid from krb5 "
1114 "upcall pipe: %s\n", strerror(errno));
1115 return;
1116 }
1117
1118 return process_krb5_upcall(clp, uid, clp->krb5_fd, NULL, NULL);
1119}
1120
1121void
1122handle_gssd_upcall(struct clnt_info *clp)
1123{
1124 uid_t uid;
1125 char *lbuf = NULL;
1126 int lbuflen = 0;
1127 char *p;
1128 char *mech = NULL;
1129 char *target = NULL;
1130 char *service = NULL;
1131 char *enctypes = NULL;
1132
1133 printerr(1, "handling gssd upcall (%s)\n", clp->dirname);
1134
1135 if (readline(clp->gssd_fd, &lbuf, &lbuflen) != 1) {
1136 printerr(0, "WARNING: handle_gssd_upcall: "
1137 "failed reading request\n");
1138 return;
1139 }
1140 printerr(2, "%s: '%s'\n", __func__, lbuf);
1141
1142 /* find the mechanism name */
1143 if ((p = strstr(lbuf, "mech=")) != NULL) {
1144 mech = malloc(lbuflen);
1145 if (!mech)
1146 goto out;
1147 if (sscanf(p, "mech=%s", mech) != 1) {
1148 printerr(0, "WARNING: handle_gssd_upcall: "
1149 "failed to parse gss mechanism name "
1150 "in upcall string '%s'\n", lbuf);
1151 goto out;
1152 }
1153 } else {
1154 printerr(0, "WARNING: handle_gssd_upcall: "
1155 "failed to find gss mechanism name "
1156 "in upcall string '%s'\n", lbuf);
1157 goto out;
1158 }
1159
1160 /* read uid */
1161 if ((p = strstr(lbuf, "uid=")) != NULL) {
1162 if (sscanf(p, "uid=%d", &uid) != 1) {
1163 printerr(0, "WARNING: handle_gssd_upcall: "
1164 "failed to parse uid "
1165 "in upcall string '%s'\n", lbuf);
1166 goto out;
1167 }
1168 } else {
1169 printerr(0, "WARNING: handle_gssd_upcall: "
1170 "failed to find uid "
1171 "in upcall string '%s'\n", lbuf);
1172 goto out;
1173 }
1174
1175 /* read supported encryption types if supplied */
1176 if ((p = strstr(lbuf, "enctypes=")) != NULL) {
1177 enctypes = malloc(lbuflen);
1178 if (!enctypes)
1179 goto out;
1180 if (sscanf(p, "enctypes=%s", enctypes) != 1) {
1181 printerr(0, "WARNING: handle_gssd_upcall: "
1182 "failed to parse encryption types "
1183 "in upcall string '%s'\n", lbuf);
1184 goto out;
1185 }
1186 if (parse_enctypes(enctypes) != 0) {
1187 printerr(0, "WARNING: handle_gssd_upcall: "
1188 "parsing encryption types failed: errno %d\n", errno);
1189 }
1190 }
1191
1192 /* read target name */
1193 if ((p = strstr(lbuf, "target=")) != NULL) {
1194 target = malloc(lbuflen);
1195 if (!target)
1196 goto out;
1197 if (sscanf(p, "target=%s", target) != 1) {
1198 printerr(0, "WARNING: handle_gssd_upcall: "
1199 "failed to parse target name "
1200 "in upcall string '%s'\n", lbuf);
1201 goto out;
1202 }
1203 }
1204
1205 /*
1206 * read the service name
1207 *
1208 * The presence of attribute "service=" indicates that machine
1209 * credentials should be used for this request. If the value
1210 * is "*", then any machine credentials available can be used.
1211 * If the value is anything else, then machine credentials for
1212 * the specified service name (always "nfs" for now) should be
1213 * used.
1214 */
1215 if ((p = strstr(lbuf, "service=")) != NULL) {
1216 service = malloc(lbuflen);
1217 if (!service)
1218 goto out;
1219 if (sscanf(p, "service=%s", service) != 1) {
1220 printerr(0, "WARNING: handle_gssd_upcall: "
1221 "failed to parse service type "
1222 "in upcall string '%s'\n", lbuf);
1223 goto out;
1224 }
1225 }
1226
1227 if (strcmp(mech, "krb5") == 0)
1228 process_krb5_upcall(clp, uid, clp->gssd_fd, target, service);
1229 else
1230 printerr(0, "WARNING: handle_gssd_upcall: "
1231 "received unknown gss mech '%s'\n", mech);
1232
1233out:
1234 free(lbuf);
1235 free(mech);
1236 free(enctypes);
1237 free(target);
1238 free(service);
1239 return;
1240}
1241
12420
=== removed directory '.pc/16-mount.nfs.man-update-distinction-between-fstype.patch'
=== removed directory '.pc/16-mount.nfs.man-update-distinction-between-fstype.patch/utils'
=== removed directory '.pc/16-mount.nfs.man-update-distinction-between-fstype.patch/utils/mount'
=== removed file '.pc/16-mount.nfs.man-update-distinction-between-fstype.patch/utils/mount/mount.nfs.man'
--- .pc/16-mount.nfs.man-update-distinction-between-fstype.patch/utils/mount/mount.nfs.man 2011-03-27 18:54:45 +0000
+++ .pc/16-mount.nfs.man-update-distinction-between-fstype.patch/utils/mount/mount.nfs.man 1970-01-01 00:00:00 +0000
@@ -1,86 +0,0 @@
1.\"@(#)mount.nfs.8"
2.TH MOUNT.NFS 8 "5 Jun 2006"
3.SH NAME
4mount.nfs, mount.nfs4 \- mount a Network File System
5.SH SYNOPSIS
6.BI "mount.nfs" " remotetarget dir" " [\-rvVwfnsh ] [\-o " options "]
7.SH DESCRIPTION
8.BR mount.nfs
9is a part of
10.BR nfs (5)
11utilities package, which provides NFS client functionality.
12
13.BR mount.nfs
14is meant to be used by the
15.BR mount (8)
16command for mounting NFS shares. This subcommand, however, can also be used as a standalone command with limited functionality.
17
18.BR mount.nfs4
19is used for mounting NFSv4 file system, while
20.BR mount.nfs
21is used to mount NFS file systems versions 3 or 2.
22.I remotetarget
23is a server share usually in the form of
24.BR servername:/path/to/share.
25.I dir
26is the directory on which the file system is to be mounted.
27
28.SH OPTIONS
29.TP
30.BI "\-r"
31Mount file system readonly.
32.TP
33.BI "\-v"
34Be verbose.
35.TP
36.BI "\-V"
37Print version.
38.TP
39.BI "\-w"
40Mount file system read-write.
41.TP
42.BI "\-f"
43Fake mount. Don't actually call the mount system call.
44.TP
45.BI "\-n"
46Do not update
47.I /etc/mtab.
48By default, an entry is created in
49.I /etc/mtab
50for every mounted file system. Use this option to skip making an entry.
51.TP
52.BI "\-s"
53Tolerate sloppy mount options rather than fail.
54.TP
55.BI "\-h"
56Print help message.
57.TP
58.BI "nfsoptions"
59Refer to
60.BR nfs (5)
61or
62.BR mount (8)
63manual pages.
64
65.SH NOTE
66For further information please refer
67.BR nfs (5)
68and
69.BR mount (8)
70manual pages.
71
72.SH FILES
73.TP 18n
74.I /etc/fstab
75file system table
76.TP
77.I /etc/mtab
78table of mounted file systems
79
80.PD
81.SH "SEE ALSO"
82.BR nfs (5),
83.BR mount (8),
84
85.SH "AUTHOR"
86Amit Gud <agud@redhat.com>
870
=== removed directory '.pc/17-multiarch-kerberos-paths.patch'
=== removed directory '.pc/17-multiarch-kerberos-paths.patch/aclocal'
=== removed file '.pc/17-multiarch-kerberos-paths.patch/aclocal/kerberos5.m4'
--- .pc/17-multiarch-kerberos-paths.patch/aclocal/kerberos5.m4 2012-05-25 20:41:58 +0000
+++ .pc/17-multiarch-kerberos-paths.patch/aclocal/kerberos5.m4 1970-01-01 00:00:00 +0000
@@ -1,115 +0,0 @@
1dnl Checks for Kerberos
2dnl NOTE: while we intend to do generic gss-api, currently we
3dnl have a requirement to get an initial Kerberos machine
4dnl credential. Thus, the requirement for Kerberos.
5dnl The Kerberos gssapi library will be dynamically loaded?
6AC_DEFUN([AC_KERBEROS_V5],[
7 AC_MSG_CHECKING(for Kerberos v5)
8 AC_ARG_WITH(krb5,
9 [AC_HELP_STRING([--with-krb5=DIR], [use Kerberos v5 installation in DIR])],
10 [ case "$withval" in
11 yes|no)
12 krb5_with=""
13 ;;
14 *)
15 krb5_with="$withval"
16 ;;
17 esac ]
18 )
19
20 for dir in $krb5_with /usr /usr/kerberos /usr/local /usr/local/krb5 \
21 /usr/krb5 /usr/heimdal /usr/local/heimdal /usr/athena ; do
22 dnl This ugly hack brought on by the split installation of
23 dnl MIT Kerberos on Fedora Core 1
24 K5CONFIG=""
25 if test -f $dir/bin/krb5-config; then
26 K5CONFIG=$dir/bin/krb5-config
27 elif test -f "/usr/kerberos/bin/krb5-config"; then
28 K5CONFIG="/usr/kerberos/bin/krb5-config"
29 elif test -f "/usr/lib/mit/bin/krb5-config"; then
30 K5CONFIG="/usr/lib/mit/bin/krb5-config"
31 fi
32 if test "$K5CONFIG" != ""; then
33 KRBCFLAGS=`$K5CONFIG --cflags`
34 KRBLIBS=`$K5CONFIG --libs`
35 K5VERS=`$K5CONFIG --version | head -n 1 | awk '{split($(4),v,"."); if (v@<:@"3"@:>@ == "") v@<:@"3"@:>@ = "0"; print v@<:@"1"@:>@v@<:@"2"@:>@v@<:@"3"@:>@ }'`
36 AC_DEFINE_UNQUOTED(KRB5_VERSION, $K5VERS, [Define this as the Kerberos version number])
37 if test -f $dir/include/gssapi/gssapi_krb5.h -a \
38 \( -f $dir/lib/libgssapi_krb5.a -o \
39 -f $dir/lib64/libgssapi_krb5.a -o \
40 -f $dir/lib64/libgssapi_krb5.so -o \
41 -f $dir/lib/libgssapi_krb5.so \) ; then
42 AC_DEFINE(HAVE_KRB5, 1, [Define this if you have MIT Kerberos libraries])
43 KRBDIR="$dir"
44 dnl If we are using MIT K5 1.3.1 and before, we *MUST* use the
45 dnl private function (gss_krb5_ccache_name) to get correct
46 dnl behavior of changing the ccache used by gssapi.
47 dnl Starting in 1.3.2, we *DO NOT* want to use
48 dnl gss_krb5_ccache_name, instead we want to set KRB5CCNAME
49 dnl to get gssapi to use a different ccache
50 if test $K5VERS -le 131; then
51 AC_DEFINE(USE_GSS_KRB5_CCACHE_NAME, 1, [Define this if the private function, gss_krb5_cache_name, must be used to tell the Kerberos library which credentials cache to use. Otherwise, this is done by setting the KRB5CCNAME environment variable])
52 fi
53 gssapi_lib=gssapi_krb5
54 break
55 dnl The following ugly hack brought on by the split installation
56 dnl of Heimdal Kerberos on SuSe
57 elif test \( -f $dir/include/heim_err.h -o\
58 -f $dir/include/heimdal/heim_err.h \) -a \
59 -f $dir/lib/libroken.a; then
60 AC_DEFINE(HAVE_HEIMDAL, 1, [Define this if you have Heimdal Kerberos libraries])
61 KRBDIR="$dir"
62 gssapi_lib=gssapi
63 break
64 fi
65 fi
66 done
67 dnl We didn't find a usable Kerberos environment
68 if test "x$KRBDIR" = "x"; then
69 if test "x$krb5_with" = "x"; then
70 AC_MSG_ERROR(Kerberos v5 with GSS support not found: consider --disable-gss or --with-krb5=)
71 else
72 AC_MSG_ERROR(Kerberos v5 with GSS support not found at $krb5_with)
73 fi
74 fi
75 AC_MSG_RESULT($KRBDIR)
76
77 dnl Check if -rpath=$(KRBDIR)/lib is needed
78 echo "The current KRBDIR is $KRBDIR"
79 if test "$KRBDIR/lib" = "/lib" -o "$KRBDIR/lib" = "/usr/lib" \
80 -o "$KRBDIR/lib" = "//lib" -o "$KRBDIR/lib" = "/usr//lib" ; then
81 KRBLDFLAGS="";
82 elif /sbin/ldconfig -p | grep > /dev/null "=> $KRBDIR/lib/"; then
83 KRBLDFLAGS="";
84 else
85 KRBLDFLAGS="-Wl,-rpath=$KRBDIR/lib"
86 fi
87
88 dnl Now check for functions within gssapi library
89 AC_CHECK_LIB($gssapi_lib, gss_krb5_export_lucid_sec_context,
90 AC_DEFINE(HAVE_LUCID_CONTEXT_SUPPORT, 1, [Define this if the Kerberos GSS library supports gss_krb5_export_lucid_sec_context]), ,$KRBLIBS)
91 AC_CHECK_LIB($gssapi_lib, gss_krb5_set_allowable_enctypes,
92 AC_DEFINE(HAVE_SET_ALLOWABLE_ENCTYPES, 1, [Define this if the Kerberos GSS library supports gss_krb5_set_allowable_enctypes]), ,$KRBLIBS)
93 AC_CHECK_LIB($gssapi_lib, gss_krb5_ccache_name,
94 AC_DEFINE(HAVE_GSS_KRB5_CCACHE_NAME, 1, [Define this if the Kerberos GSS library supports gss_krb5_ccache_name]), ,$KRBLIBS)
95
96 dnl Check for newer error message facility
97 AC_CHECK_LIB($gssapi_lib, krb5_get_error_message,
98 AC_DEFINE(HAVE_KRB5_GET_ERROR_MESSAGE, 1, [Define this if the function krb5_get_error_message is available]), ,$KRBLIBS)
99
100 dnl Check for function to specify addressless tickets
101 AC_CHECK_LIB($gssapi_lib, krb5_get_init_creds_opt_set_addressless,
102 AC_DEFINE(HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ADDRESSLESS, 1, [Define this if the function krb5_get_init_creds_opt_set_addressless is available]), ,$KRBLIBS)
103
104 dnl If they specified a directory and it didn't work, give them a warning
105 if test "x$krb5_with" != "x" -a "$krb5_with" != "$KRBDIR"; then
106 AC_MSG_WARN(Using $KRBDIR instead of requested value of $krb5_with for Kerberos!)
107 fi
108
109 AC_SUBST([KRBDIR])
110 AC_SUBST([KRBLIBS])
111 AC_SUBST([KRBCFLAGS])
112 AC_SUBST([KRBLDFLAGS])
113 AC_SUBST([K5VERS])
114
115])
1160
=== removed directory '.pc/18-osd_login-sbindir.patch'
=== removed directory '.pc/18-osd_login-sbindir.patch/utils'
=== removed directory '.pc/18-osd_login-sbindir.patch/utils/osd_login'
=== removed file '.pc/18-osd_login-sbindir.patch/utils/osd_login/Makefile.am'
--- .pc/18-osd_login-sbindir.patch/utils/osd_login/Makefile.am 2012-06-22 15:04:56 +0000
+++ .pc/18-osd_login-sbindir.patch/utils/osd_login/Makefile.am 1970-01-01 00:00:00 +0000
@@ -1,12 +0,0 @@
1## Process this file with automake to produce Makefile.in
2
3OSD_LOGIN_FILES= osd_login
4
5EXTRA_DIST= $(OSD_LOGIN_FILES)
6
7all-local: $(OSD_LOGIN_FILES)
8
9install-data-hook:
10 $(INSTALL) --mode 755 osd_login $(DESTDIR)/sbin/osd_login
11
12MAINTAINERCLEANFILES = Makefile.in
130
=== removed directory '.pc/19-iscsiadm-path.patch'
=== removed directory '.pc/19-iscsiadm-path.patch/utils'
=== removed directory '.pc/19-iscsiadm-path.patch/utils/osd_login'
=== removed file '.pc/19-iscsiadm-path.patch/utils/osd_login/osd_login'
--- .pc/19-iscsiadm-path.patch/utils/osd_login/osd_login 2012-06-22 15:04:56 +0000
+++ .pc/19-iscsiadm-path.patch/utils/osd_login/osd_login 1970-01-01 00:00:00 +0000
@@ -1,118 +0,0 @@
1#!/bin/bash
2#
3# osd_login : This script is part of the autologin feature
4# mandated by the pnfs-objects standard.
5# It is called from objlayoutdriver.ko in the kernel.
6
7# Copyright (C) 2012, Sachin Bhamare <sbhamare@panasas.com>
8# Copyright (C) 2012, Boaz Harrosh <bharrosh@panasas.com>
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License version 2 as
12# published by the Free Software Foundation.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22# MA 02110-1301 USA
23
24umask 022
25
26PATH="/sbin:/usr/sbin:/bin:/usr/bin"
27
28iscsiadm=/sbin/iscsiadm
29
30PARENT_PID=$BASHPID
31WATCHDOG_TIMEOUT=15
32
33protocol=""
34portal=""
35uri=""
36osdname=""
37systemid=""
38
39usage()
40{
41 echo "Usage: $0 -u <URI> -o <OSDNAME> -s <SYSTEMID>"
42 echo "Options:"
43 echo "-u target uri e.g. iscsi://<ip>:<port>"
44 echo "-o osdname of the target OSD"
45 echo "-s systemid of the target OSD"
46}
47
48parse_cmdline()
49{
50 argc=$#
51 if [ $# -lt 3 ]; then
52 usage
53 exit 1
54 fi
55
56 # parse the input arguments
57 while getopts "u:o:s:" options; do
58 case $options in
59 u ) uri=$OPTARG;;
60 o ) osdname=$OPTARG;;
61 s ) systemid=$OPTARG;;
62 \? ) usage
63 exit 1;;
64 * ) usage
65 exit 1;;
66 esac
67 done
68
69 echo "-u : $uri"
70 echo "-o : $osdname"
71 echo "-s : $systemid"
72
73 protocol=`echo $uri | awk -F ':' '{print $1}'`
74 portal=`echo $uri | awk -F '//' '{print $2}'`
75}
76
77watchdog()
78{
79 timeout=$1
80 portal=$2
81
82 sleep $timeout
83 if kill -9 $PARENT_PID; then
84 echo "watchdog : Timed out (>$timeout seconds) while login into $portal" | logger -t "osd_login"
85 fi
86 echo "watchdog: exiting .."
87 exit 2
88}
89
90login_iscsi_osd()
91{
92 echo "login into: $1"
93 if ! $iscsiadm -m discovery -o nonpersistent -t sendtargets -p $1 --login; then
94 echo "$iscsiadm -m discovery -t sendtargets -p $1 --login returned error $? !"
95 sleep 1;
96 fi
97}
98
99echo "============= osd_login ========="
100echo "progname : $0"
101parse_cmdline "$@"
102echo "protocol: $protocol"
103echo "portal: $portal"
104
105watchdog $WATCHDOG_TIMEOUT $portal &
106watchdog_pid=$!
107
108case $protocol in
109iscsi)
110 login_iscsi_osd $portal |& logger -t "osd_login"
111 ;;
112*)
113 echo "Error: protocol $protocol not supported !" | logger -t "osd_login"
114 ;;
115esac
116
117kill -9 $watchdog_pid
118exit 0
1190
=== removed file '.pc/applied-patches'
--- .pc/applied-patches 2012-06-22 15:04:56 +0000
+++ .pc/applied-patches 1970-01-01 00:00:00 +0000
@@ -1,8 +0,0 @@
101-sm-notify-in-sbin.patch
202-524255-manpages.patch
303-handle-mtab-symlink.patch
411-532048-reduce-verbosity.patch
516-mount.nfs.man-update-distinction-between-fstype.patch
617-multiarch-kerberos-paths.patch
718-osd_login-sbindir.patch
819-iscsiadm-path.patch
90
=== modified file 'aclocal/kerberos5.m4'
--- aclocal/kerberos5.m4 2012-06-22 15:04:56 +0000
+++ aclocal/kerberos5.m4 2012-08-05 05:01:18 +0000
@@ -29,7 +29,6 @@
29 elif test -f "/usr/lib/mit/bin/krb5-config"; then29 elif test -f "/usr/lib/mit/bin/krb5-config"; then
30 K5CONFIG="/usr/lib/mit/bin/krb5-config"30 K5CONFIG="/usr/lib/mit/bin/krb5-config"
31 fi31 fi
32 MULTIARCH=`dpkg-architecture -qDEB_HOST_MULTIARCH 2>/dev/null || true`
33 if test "$K5CONFIG" != ""; then32 if test "$K5CONFIG" != ""; then
34 KRBCFLAGS=`$K5CONFIG --cflags`33 KRBCFLAGS=`$K5CONFIG --cflags`
35 KRBLIBS=`$K5CONFIG --libs`34 KRBLIBS=`$K5CONFIG --libs`
@@ -39,7 +38,6 @@
39 \( -f $dir/lib/libgssapi_krb5.a -o \38 \( -f $dir/lib/libgssapi_krb5.a -o \
40 -f $dir/lib64/libgssapi_krb5.a -o \39 -f $dir/lib64/libgssapi_krb5.a -o \
41 -f $dir/lib64/libgssapi_krb5.so -o \40 -f $dir/lib64/libgssapi_krb5.so -o \
42 -f $dir/lib/$MULTIARCH/libgssapi_krb5.so -o \
43 -f $dir/lib/libgssapi_krb5.so \) ; then41 -f $dir/lib/libgssapi_krb5.so \) ; then
44 AC_DEFINE(HAVE_KRB5, 1, [Define this if you have MIT Kerberos libraries])42 AC_DEFINE(HAVE_KRB5, 1, [Define this if you have MIT Kerberos libraries])
45 KRBDIR="$dir"43 KRBDIR="$dir"
4644
=== modified file 'debian/changelog'
--- debian/changelog 2012-06-22 18:25:32 +0000
+++ debian/changelog 2012-08-05 05:01:18 +0000
@@ -1,3 +1,30 @@
1nfs-utils (1:1.2.6-3ubuntu1) quantal; urgency=low
2
3 * Merge from Debian unstable. Remaining changes:
4 - debian/nfs-common.{statd,statd-mounting,gssd,idmapd}.upstart,
5 debian/control, debian/nfs-common.{preinst,postinst,prerm,postrm},
6 debian/rules: drop nfs-common init script in favor of upstart jobs,
7 and build-depend on debhelper (>= 7.3.15ubuntu3) for correct upstart
8 init handling.
9 - Depend on rpcbind (>= 0.2.0-6ubuntu1) for upstart support.
10 - debian/nfs-kernel-server.postinst: don't call "invoke-rc.d nfs-common"
11 in the postinst, this is redundant anyway and the nfs-common init script
12 is gone now.
13 - nfs-kernel-server.init: Unmount nfsd fs when init script stops
14 - Allow issuing options to rpc.nfsd
15 - debian/nfs-common.defaults: always start idmapd automatically; drop
16 the configuration option.
17 - Move /var/lib/nfs/rpc_pipefs to /run/rpc_pipefs. This does not belong
18 in /var/lib.
19
20 -- Logan Rosen <logatronico@gmail.com> Sun, 05 Aug 2012 00:56:05 -0400
21
22nfs-utils (1:1.2.6-3) unstable; urgency=low
23
24 * Iterate through exports.d to look for expors (Closes: #676604).
25
26 -- Luk Claes <luk@zomers.be> Tue, 10 Jul 2012 19:38:22 +0200
27
1nfs-utils (1:1.2.6-2ubuntu1) quantal; urgency=low28nfs-utils (1:1.2.6-2ubuntu1) quantal; urgency=low
229
3 * Merge from Debian unstable, remaining changes:30 * Merge from Debian unstable, remaining changes:
431
=== modified file 'debian/nfs-kernel-server.init'
--- debian/nfs-kernel-server.init 2012-06-22 15:04:56 +0000
+++ debian/nfs-kernel-server.init 2012-08-05 05:01:18 +0000
@@ -61,7 +61,13 @@
61# See how we were called.61# See how we were called.
62case "$1" in62case "$1" in
63 start)63 start)
64 if [ -f /etc/exports ] && grep -q '^[[:space:]]*[^#]*/' /etc/exports64 export_files="/etc/exports"
65 for file in /etc/exports.d/*.exports ; do
66 if [ -f "$file" ]; then
67 export_files="$export_files $file"
68 fi
69 done
70 if [ -f /etc/exports ] && grep -q '^[[:space:]]*[^#]*/' $export_files
65 then71 then
66 do_modprobe nfsd72 do_modprobe nfsd
6773
6874
=== modified file 'utils/exportfs/nfsd.man'
--- utils/exportfs/nfsd.man 2012-05-25 20:41:58 +0000
+++ utils/exportfs/nfsd.man 2012-08-05 05:01:18 +0000
@@ -196,7 +196,6 @@
196find out what number correspond to what tracing.196find out what number correspond to what tracing.
197197
198.SH SEE ALSO198.SH SEE ALSO
199.BR nfsd (8),
200.BR rpc.nfsd (8),199.BR rpc.nfsd (8),
201.BR exports (5),200.BR exports (5),
202.BR nfsstat (8),201.BR nfsstat (8),
203202
=== modified file 'utils/gssd/gss_util.c'
--- utils/gssd/gss_util.c 2011-07-09 16:28:32 +0000
+++ utils/gssd/gss_util.c 2012-08-05 05:01:18 +0000
@@ -126,7 +126,7 @@
126 "gss_display_status called from %s\n", m);126 "gss_display_status called from %s\n", m);
127 break;127 break;
128 } else {128 } else {
129 printerr(2, "ERROR: GSS-API: (%s) error in %s(): %s\n",129 printerr(0, "ERROR: GSS-API: (%s) error in %s(): %s\n",
130 typestr, m, (char *)msg.value);130 typestr, m, (char *)msg.value);
131 }131 }
132132
133133
=== modified file 'utils/gssd/gssd_proc.c'
--- utils/gssd/gssd_proc.c 2012-05-25 20:41:58 +0000
+++ utils/gssd/gssd_proc.c 2012-08-05 05:01:18 +0000
@@ -676,7 +676,7 @@
676 unsigned int timeout = 0;676 unsigned int timeout = 0;
677 int zero = 0;677 int zero = 0;
678678
679 printerr(2, "doing error downcall\n");679 printerr(1, "doing error downcall\n");
680680
681 if (WRITE_BYTES(&p, end, uid)) goto out_err;681 if (WRITE_BYTES(&p, end, uid)) goto out_err;
682 if (WRITE_BYTES(&p, end, timeout)) goto out_err;682 if (WRITE_BYTES(&p, end, timeout)) goto out_err;
@@ -953,7 +953,7 @@
953 int create_resp = -1;953 int create_resp = -1;
954 int err, downcall_err = -EACCES;954 int err, downcall_err = -EACCES;
955955
956 printerr(2, "handling krb5 upcall (%s)\n", clp->dirname);956 printerr(1, "handling krb5 upcall (%s)\n", clp->dirname);
957957
958 if (tgtname) {958 if (tgtname) {
959 if (clp->servicename) {959 if (clp->servicename) {
@@ -1071,7 +1071,7 @@
1071 }1071 }
10721072
1073 if (!authgss_get_private_data(auth, &pd)) {1073 if (!authgss_get_private_data(auth, &pd)) {
1074 printerr(2, "WARNING: Failed to obtain authentication "1074 printerr(1, "WARNING: Failed to obtain authentication "
1075 "data for user with uid %d for server %s\n",1075 "data for user with uid %d for server %s\n",
1076 uid, clp->servername);1076 uid, clp->servername);
1077 goto out_return_error;1077 goto out_return_error;
10781078
=== modified file 'utils/mount/fstab.c'
--- utils/mount/fstab.c 2011-10-02 18:29:53 +0000
+++ utils/mount/fstab.c 2012-08-05 05:01:18 +0000
@@ -57,7 +57,7 @@
57 return var_mtab_does_not_exist;57 return var_mtab_does_not_exist;
58}58}
5959
60int60static int
61mtab_is_a_symlink(void) {61mtab_is_a_symlink(void) {
62 get_mtab_info();62 get_mtab_info();
63 return var_mtab_is_a_symlink;63 return var_mtab_is_a_symlink;
6464
=== modified file 'utils/mount/fstab.h'
--- utils/mount/fstab.h 2011-10-02 18:29:53 +0000
+++ utils/mount/fstab.h 2012-08-05 05:01:18 +0000
@@ -7,7 +7,6 @@
7#define _PATH_FSTAB "/etc/fstab"7#define _PATH_FSTAB "/etc/fstab"
8#endif8#endif
99
10int mtab_is_a_symlink(void);
11int mtab_is_writable(void);10int mtab_is_writable(void);
12int mtab_does_not_exist(void);11int mtab_does_not_exist(void);
13void reset_mtab_info(void);12void reset_mtab_info(void);
1413
=== modified file 'utils/mount/mount.c'
--- utils/mount/mount.c 2011-07-09 16:28:32 +0000
+++ utils/mount/mount.c 2012-08-05 05:01:18 +0000
@@ -203,13 +203,6 @@
203 int flags;203 int flags;
204 mntFILE *mfp;204 mntFILE *mfp;
205205
206 /* Avoid writing if the mtab is a symlink to /proc/mounts, since
207 that would create a file /proc/mounts in case the proc filesystem
208 is not mounted, and the fchmod below would also fail. */
209 if (mtab_is_a_symlink()) {
210 return EX_SUCCESS;
211 }
212
213 lock_mtab();206 lock_mtab();
214207
215 mfp = nfs_setmntent (MOUNTED, "a+");208 mfp = nfs_setmntent (MOUNTED, "a+");
216209
=== modified file 'utils/mount/mount.nfs.man'
--- utils/mount/mount.nfs.man 2011-03-16 23:10:15 +0000
+++ utils/mount/mount.nfs.man 2012-08-05 05:01:18 +0000
@@ -15,20 +15,16 @@
15.BR mount (8)15.BR mount (8)
16command for mounting NFS shares. This subcommand, however, can also be used as a standalone command with limited functionality.16command for mounting NFS shares. This subcommand, however, can also be used as a standalone command with limited functionality.
1717
18.BR mount.nfs4
19is used for mounting NFSv4 file system, while
20.BR mount.nfs
21is used to mount NFS file systems versions 3 or 2.
18.I remotetarget 22.I remotetarget
19is a server share usually in the form of 23is a server share usually in the form of
20.BR servername:/path/to/share.24.BR servername:/path/to/share.
21.I dir 25.I dir
22is the directory on which the file system is to be mounted.26is the directory on which the file system is to be mounted.
2327
24Under Linux 2.6.32 and later kernel versions,
25.BR mount.nfs
26can mount all NFS file system versions. Under earlier Linux kernel versions,
27.BR mount.nfs4
28must be used for mounting NFSv4 file systems while
29.BR mount.nfs
30must be used for NFSv3 and v2.
31
32.SH OPTIONS28.SH OPTIONS
33.TP29.TP
34.BI "\-r"30.BI "\-r"
3531
=== modified file 'utils/nfsd/nfsd.man'
--- utils/nfsd/nfsd.man 2012-05-25 20:41:58 +0000
+++ utils/nfsd/nfsd.man 2012-08-05 05:01:18 +0000
@@ -94,7 +94,6 @@
94database.94database.
9595
96.SH SEE ALSO96.SH SEE ALSO
97.BR nfsd (7),
98.BR rpc.mountd (8),97.BR rpc.mountd (8),
99.BR exports (5),98.BR exports (5),
100.BR exportfs (8),99.BR exportfs (8),
101100
=== modified file 'utils/osd_login/Makefile.am'
--- utils/osd_login/Makefile.am 2012-05-25 20:41:58 +0000
+++ utils/osd_login/Makefile.am 2012-08-05 05:01:18 +0000
@@ -1,9 +1,12 @@
1## Process this file with automake to produce Makefile.in1## Process this file with automake to produce Makefile.in
22
3# These binaries go in /sbin (not /usr/sbin), and that cannot be3OSD_LOGIN_FILES= osd_login
4# overridden at config time.4
5sbindir = /sbin5EXTRA_DIST= $(OSD_LOGIN_FILES)
66
7sbin_SCRIPTS = osd_login7all-local: $(OSD_LOGIN_FILES)
8
9install-data-hook:
10 $(INSTALL) --mode 755 osd_login $(DESTDIR)/sbin/osd_login
811
9MAINTAINERCLEANFILES = Makefile.in12MAINTAINERCLEANFILES = Makefile.in
1013
=== modified file 'utils/osd_login/osd_login'
--- utils/osd_login/osd_login 2012-05-25 20:41:58 +0000
+++ utils/osd_login/osd_login 2012-08-05 05:01:18 +0000
@@ -25,6 +25,8 @@
2525
26PATH="/sbin:/usr/sbin:/bin:/usr/bin"26PATH="/sbin:/usr/sbin:/bin:/usr/bin"
2727
28iscsiadm=/sbin/iscsiadm
29
28PARENT_PID=$BASHPID30PARENT_PID=$BASHPID
29WATCHDOG_TIMEOUT=1531WATCHDOG_TIMEOUT=15
3032
@@ -88,8 +90,8 @@
88login_iscsi_osd()90login_iscsi_osd()
89{91{
90 echo "login into: $1"92 echo "login into: $1"
91 if ! iscsiadm -m discovery -o nonpersistent -t sendtargets -p $1 --login; then93 if ! $iscsiadm -m discovery -o nonpersistent -t sendtargets -p $1 --login; then
92 echo "iscsiadm -m discovery -t sendtargets -p $1 --login returned error $? !"94 echo "$iscsiadm -m discovery -t sendtargets -p $1 --login returned error $? !"
93 sleep 1;95 sleep 1;
94 fi96 fi
95}97}
9698
=== modified file 'utils/statd/statd.c'
--- utils/statd/statd.c 2010-04-06 16:11:22 +0000
+++ utils/statd/statd.c 2012-08-05 05:01:18 +0000
@@ -190,7 +190,7 @@
190 char *av[6];190 char *av[6];
191 int ac = 0;191 int ac = 0;
192192
193 av[ac++] = "/sbin/sm-notify";193 av[ac++] = "/usr/sbin/sm-notify";
194 if (run_mode & MODE_NODAEMON)194 if (run_mode & MODE_NODAEMON)
195 av[ac++] = "-d";195 av[ac++] = "-d";
196 if (outport) {196 if (outport) {

Subscribers

People subscribed via source and target branches

to all changes: