openssh.patch.sftplogging 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. Index: servconf.c
  2. --- servconf.c.orig 2004-08-13 13:30:24 +0200
  3. +++ servconf.c 2004-08-17 19:57:16 +0200
  4. @@ -103,6 +103,15 @@
  5. options->authorized_keys_file2 = NULL;
  6. options->num_accept_env = 0;
  7. + options->log_sftp = LOG_SFTP_NOT_SET;
  8. + options->sftp_log_facility = SYSLOG_FACILITY_NOT_SET;
  9. + options->sftp_log_level = SYSLOG_LEVEL_NOT_SET;
  10. +
  11. + memset(options->sftp_umask, 0, SFTP_UMASK_LENGTH);
  12. +
  13. + options->sftp_permit_chmod = SFTP_PERMIT_NOT_SET;
  14. + options->sftp_permit_chown = SFTP_PERMIT_NOT_SET;
  15. +
  16. /* Needs to be accessable in many places */
  17. use_privsep = -1;
  18. }
  19. @@ -231,6 +240,24 @@
  20. if (options->authorized_keys_file == NULL)
  21. options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
  22. + /* Turn sftp-server logging off by default */
  23. + if (options->log_sftp == LOG_SFTP_NOT_SET)
  24. + options->log_sftp = LOG_SFTP_NO;
  25. + if (options->sftp_log_facility == SYSLOG_FACILITY_NOT_SET)
  26. + options->sftp_log_facility = SYSLOG_FACILITY_AUTH;
  27. + if (options->sftp_log_level == SYSLOG_LEVEL_NOT_SET)
  28. + options->sftp_log_level = SYSLOG_LEVEL_INFO;
  29. +
  30. + /* Don't set sftp-server umask */
  31. + if (!options->sftp_umask)
  32. + memset(options->sftp_umask, 0, SFTP_UMASK_LENGTH);
  33. +
  34. + /* allow sftp client to issue chmod, chown / chgrp commands */
  35. + if (options->sftp_permit_chmod == SFTP_PERMIT_NOT_SET)
  36. + options->sftp_permit_chmod = SFTP_PERMIT_YES;
  37. + if (options->sftp_permit_chown == SFTP_PERMIT_NOT_SET)
  38. + options->sftp_permit_chown = SFTP_PERMIT_YES;
  39. +
  40. /* Turn privilege separation on by default */
  41. if (use_privsep == -1)
  42. use_privsep = 1;
  43. @@ -272,6 +299,9 @@
  44. sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
  45. sGssAuthentication, sGssCleanupCreds, sAcceptEnv,
  46. sUsePrivilegeSeparation,
  47. + sLogSftp, sSftpLogFacility, sSftpLogLevel,
  48. + sSftpUmask,
  49. + sSftpPermitChown, sSftpPermitChmod,
  50. sDeprecated, sUnsupported
  51. } ServerOpCodes;
  52. @@ -281,6 +311,12 @@
  53. ServerOpCodes opcode;
  54. } keywords[] = {
  55. /* Portable-specific options */
  56. + { "logsftp", sLogSftp},
  57. + { "sftplogfacility", sSftpLogFacility},
  58. + { "sftploglevel", sSftpLogLevel},
  59. + { "sftpumask", sSftpUmask},
  60. + { "sftppermitchmod", sSftpPermitChmod},
  61. + { "sftppermitchown", sSftpPermitChown},
  62. #ifdef USE_PAM
  63. { "usepam", sUsePAM },
  64. #else
  65. @@ -437,6 +473,8 @@
  66. char *cp, **charptr, *arg, *p;
  67. int *intptr, value, i, n;
  68. ServerOpCodes opcode;
  69. + unsigned int umaskvalue = 0;
  70. + char *umaskptr;
  71. cp = line;
  72. arg = strdelim(&cp);
  73. @@ -881,6 +919,58 @@
  74. case sBanner:
  75. charptr = &options->banner;
  76. goto parse_filename;
  77. +
  78. + case sLogSftp:
  79. + intptr = &options->log_sftp;
  80. + goto parse_flag;
  81. +
  82. + case sSftpLogFacility:
  83. + intptr = (int *) &options->sftp_log_facility;
  84. + arg = strdelim(&cp);
  85. + value = log_facility_number(arg);
  86. + if (value == SYSLOG_FACILITY_NOT_SET)
  87. + fatal("%.200s line %d: unsupported log facility '%s'",
  88. + filename, linenum, arg ? arg : "<NONE>");
  89. + if (*intptr == -1)
  90. + *intptr = (SyslogFacility) value;
  91. + break;
  92. +
  93. + case sSftpLogLevel:
  94. + intptr = (int *) &options->sftp_log_level;
  95. + arg = strdelim(&cp);
  96. + value = log_level_number(arg);
  97. + if (value == SYSLOG_LEVEL_NOT_SET)
  98. + fatal("%.200s line %d: unsupported log level '%s'",
  99. + filename, linenum, arg ? arg : "<NONE>");
  100. + if (*intptr == -1)
  101. + *intptr = (LogLevel) value;
  102. + break;
  103. +
  104. + case sSftpUmask:
  105. + arg = strdelim(&cp);
  106. + umaskptr = arg;
  107. + while (*arg && *arg >= '0' && *arg <= '9')
  108. + umaskvalue = umaskvalue * 8 + *arg++ - '0';
  109. + if (*arg || umaskvalue > 0777)
  110. + fatal("%s line %d: bad value for umask",
  111. + filename, linenum);
  112. + else {
  113. + while (*umaskptr && *umaskptr == '0')
  114. + *umaskptr++;
  115. + strncpy(options->sftp_umask, umaskptr,
  116. + SFTP_UMASK_LENGTH);
  117. + }
  118. +
  119. + break;
  120. +
  121. + case sSftpPermitChmod:
  122. + intptr = &options->sftp_permit_chmod;
  123. + goto parse_flag;
  124. +
  125. + case sSftpPermitChown:
  126. + intptr = &options->sftp_permit_chown;
  127. + goto parse_flag;
  128. +
  129. /*
  130. * These options can contain %X options expanded at
  131. * connect time, so that you can specify paths like:
  132. Index: servconf.h
  133. --- servconf.h.orig 2004-06-25 05:33:20 +0200
  134. +++ servconf.h 2004-08-17 19:55:16 +0200
  135. @@ -35,6 +35,19 @@
  136. #define PERMIT_NO_PASSWD 2
  137. #define PERMIT_YES 3
  138. +/* sftp-server logging */
  139. +#define LOG_SFTP_NOT_SET -1
  140. +#define LOG_SFTP_NO 0
  141. +#define LOG_SFTP_YES 1
  142. +
  143. +/* sftp-server umask control */
  144. +#define SFTP_UMASK_LENGTH 5
  145. +
  146. +/* sftp-server client priviledge */
  147. +#define SFTP_PERMIT_NOT_SET -1
  148. +#define SFTP_PERMIT_NO 0
  149. +#define SFTP_PERMIT_YES 1
  150. +
  151. #define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */
  152. typedef struct {
  153. @@ -133,6 +146,13 @@
  154. char *authorized_keys_file; /* File containing public keys */
  155. char *authorized_keys_file2;
  156. int use_pam; /* Enable auth via PAM */
  157. + int log_sftp; /* perform sftp-server logging */
  158. + SyslogFacility sftp_log_facility; /* Facility for sftp subsystem logging. */
  159. + LogLevel sftp_log_level; /* Level for sftp subsystem logging. */
  160. + char sftp_umask[SFTP_UMASK_LENGTH]; /* Sftp Umask */
  161. + int sftp_permit_chmod;
  162. + int sftp_permit_chown;
  163. +
  164. } ServerOptions;
  165. void initialize_server_options(ServerOptions *);
  166. Index: session.c
  167. --- session.c.orig 2004-08-12 14:40:25 +0200
  168. +++ session.c 2004-08-17 19:54:21 +0200
  169. @@ -112,6 +112,15 @@
  170. static int is_child = 0;
  171. +/* so SFTP_LOG_FACILITY and SFTP_LOG_LEVEL can be passed through the
  172. + environment to the sftp-server subsystem. */
  173. +static const char *sysfac_to_int[] = { "0", "1", "2", "3", "4", "5", "6",
  174. + "7", "8", "9", "10", "11", "-1" };
  175. +static const char *syslevel_to_int[] = { "0", "1", "2", "3", "4", "5", "6",
  176. + "7", "-1" };
  177. +
  178. +static char *sftpumask;
  179. +
  180. /* Name and directory of socket for authentication agent forwarding. */
  181. static char *auth_sock_name = NULL;
  182. static char *auth_sock_dir = NULL;
  183. @@ -974,6 +983,7 @@
  184. env = xmalloc(envsize * sizeof(char *));
  185. env[0] = NULL;
  186. +
  187. #ifdef HAVE_CYGWIN
  188. /*
  189. * The Windows environment contains some setting which are
  190. @@ -1118,6 +1128,67 @@
  191. child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
  192. auth_sock_name);
  193. + /* LOG_SFTP */
  194. + if (options.log_sftp == -1 )
  195. + child_set_env(&env, &envsize, "LOG_SFTP", "-1");
  196. + else if (options.log_sftp == 0)
  197. + child_set_env(&env, &envsize, "LOG_SFTP", "0");
  198. + else
  199. + child_set_env(&env, &envsize, "LOG_SFTP", "1");
  200. +
  201. + /* SFTP_LOG_FACILITY */
  202. + if (options.sftp_log_facility < 0)
  203. + child_set_env(&env, &envsize, "SFTP_LOG_FACILITY",
  204. + "-1");
  205. + else
  206. + child_set_env(&env, &envsize, "SFTP_LOG_FACILITY",
  207. + sysfac_to_int[options.sftp_log_facility]);
  208. +
  209. + /* SFTP_LOG_LEVEL */
  210. + if (options.sftp_log_level < 0)
  211. + child_set_env(&env, &envsize, "SFTP_LOG_LEVEL",
  212. + "-1");
  213. + else
  214. + child_set_env(&env, &envsize, "SFTP_LOG_LEVEL",
  215. + syslevel_to_int[options.sftp_log_level]);
  216. +
  217. + /* SFTP_UMASK */
  218. +
  219. + if (options.sftp_umask[0] == '\0')
  220. + child_set_env(&env, &envsize, "SFTP_UMASK",
  221. + "" );
  222. + else {
  223. + if (!(sftpumask = calloc(SFTP_UMASK_LENGTH,1))) {
  224. +
  225. +logit("session.c: unabled to allocate memory for SftpUmask. SftpUmask control \
  226. +will be turned off.");
  227. +
  228. + child_set_env(&env, &envsize, "SFTP_UMASK",
  229. + "" );
  230. + } else {
  231. + strncpy(sftpumask, options.sftp_umask,
  232. + SFTP_UMASK_LENGTH);
  233. + child_set_env(&env, &envsize, "SFTP_UMASK",
  234. + sftpumask );
  235. + }
  236. + }
  237. +
  238. + /* SFTP_PERMIT_CHMOD */
  239. + if (options.sftp_permit_chmod == -1 )
  240. + child_set_env(&env, &envsize, "SFTP_PERMIT_CHMOD", "-1");
  241. + else if (options.sftp_permit_chmod == 0)
  242. + child_set_env(&env, &envsize, "SFTP_PERMIT_CHMOD", "0");
  243. + else
  244. + child_set_env(&env, &envsize, "SFTP_PERMIT_CHMOD", "1");
  245. +
  246. + /* SFTP_PERMIT_CHOWN */
  247. + if (options.sftp_permit_chown == -1 )
  248. + child_set_env(&env, &envsize, "SFTP_PERMIT_CHOWN", "-1");
  249. + else if (options.sftp_permit_chown == 0)
  250. + child_set_env(&env, &envsize, "SFTP_PERMIT_CHOWN", "0");
  251. + else
  252. + child_set_env(&env, &envsize, "SFTP_PERMIT_CHOWN", "1");
  253. +
  254. /* read $HOME/.ssh/environment. */
  255. if (options.permit_user_env && !options.use_login) {
  256. snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
  257. Index: sftp-server.8
  258. --- sftp-server.8.orig 2003-10-15 07:50:43 +0200
  259. +++ sftp-server.8 2004-08-17 19:54:21 +0200
  260. @@ -41,6 +41,20 @@
  261. .Cm Subsystem
  262. option.
  263. See
  264. +.Xr sshd 8
  265. +for more information. Sftp-server transactions may be logged
  266. +using the
  267. +.Cm LogSftp ,
  268. +.Cm SftpLogFacility ,
  269. +and
  270. +.Cm SftpLogLevel
  271. +options. The administrator may exert control over the file and directory
  272. +permission and ownership, with
  273. +.Cm SftpUmask ,
  274. +.Cm SftpPermitChmod ,
  275. +and
  276. +.Cm SftpPermitChown
  277. +. See
  278. .Xr sshd_config 5
  279. for more information.
  280. .Sh SEE ALSO
  281. Index: sftp-server.c
  282. --- sftp-server.c.orig 2004-07-17 06:07:42 +0200
  283. +++ sftp-server.c 2004-08-17 19:56:22 +0200
  284. @@ -31,6 +31,13 @@
  285. #define get_string(lenp) buffer_get_string(&iqueue, lenp);
  286. #define TRACE debug
  287. +/* SFTP_UMASK */
  288. +static mode_t setumask = 0;
  289. +
  290. +static int permit_chmod = 1;
  291. +static int permit_chown = 1;
  292. +static int permit_logging = 0;
  293. +
  294. extern char *__progname;
  295. /* input and output queue */
  296. @@ -381,6 +388,14 @@
  297. a = get_attrib();
  298. flags = flags_from_portable(pflags);
  299. mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
  300. +
  301. + if (setumask != 0) {
  302. + if ( permit_logging == 1 )
  303. + logit("setting file creation mode to 0666 and umask to %o", setumask);
  304. + mode = 0666;
  305. + umask(setumask);
  306. + }
  307. +
  308. TRACE("open id %u name %s flags %d mode 0%o", id, name, pflags, mode);
  309. fd = open(name, flags, mode);
  310. if (fd < 0) {
  311. @@ -394,6 +409,8 @@
  312. status = SSH2_FX_OK;
  313. }
  314. }
  315. + if ( permit_logging == 1 )
  316. + logit("open %s", name);
  317. if (status != SSH2_FX_OK)
  318. send_status(id, status);
  319. xfree(name);
  320. @@ -430,6 +447,7 @@
  321. (u_int64_t)off, len);
  322. if (len > sizeof buf) {
  323. len = sizeof buf;
  324. + if ( permit_logging == 1 )
  325. logit("read change len %d", len);
  326. }
  327. fd = handle_to_fd(handle);
  328. @@ -449,6 +467,8 @@
  329. }
  330. }
  331. }
  332. + if ( permit_logging == 1 )
  333. + logit("reading file");
  334. if (status != SSH2_FX_OK)
  335. send_status(id, status);
  336. }
  337. @@ -483,10 +503,13 @@
  338. } else if (ret == len) {
  339. status = SSH2_FX_OK;
  340. } else {
  341. + if ( permit_logging == 1 )
  342. logit("nothing at all written");
  343. }
  344. }
  345. }
  346. + if ( permit_logging == 1 )
  347. + logit("writing file");
  348. send_status(id, status);
  349. xfree(data);
  350. }
  351. @@ -579,24 +602,46 @@
  352. a = get_attrib();
  353. TRACE("setstat id %u name %s", id, name);
  354. if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
  355. +if ( permit_logging == 1 )
  356. +logit("process_setstat: truncate");
  357. ret = truncate(name, a->size);
  358. if (ret == -1)
  359. status = errno_to_portable(errno);
  360. }
  361. if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
  362. + if (permit_chmod == 1) {
  363. ret = chmod(name, a->perm & 0777);
  364. if (ret == -1)
  365. status = errno_to_portable(errno);
  366. + else
  367. + if ( permit_logging == 1 )
  368. + logit("chmod'ed %s", name);
  369. + } else {
  370. + status = SSH2_FX_PERMISSION_DENIED;
  371. + if ( permit_logging == 1 )
  372. + logit("chmod %s: operation prohibited by sftp-server configuration.", name);
  373. + }
  374. }
  375. if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
  376. +if ( permit_logging == 1 )
  377. +logit("process_setstat: utimes");
  378. ret = utimes(name, attrib_to_tv(a));
  379. if (ret == -1)
  380. status = errno_to_portable(errno);
  381. }
  382. if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
  383. + if (permit_chown == 1) {
  384. ret = chown(name, a->uid, a->gid);
  385. if (ret == -1)
  386. status = errno_to_portable(errno);
  387. + else
  388. + if ( permit_logging == 1 )
  389. + logit("chown'ed %s.", name);
  390. + } else {
  391. + status = SSH2_FX_PERMISSION_DENIED;
  392. + if ( permit_logging == 1 )
  393. + logit("chown %s: operation prohibited by sftp-server configuration.", name);
  394. + }
  395. }
  396. send_status(id, status);
  397. xfree(name);
  398. @@ -611,6 +656,9 @@
  399. int status = SSH2_FX_OK;
  400. char *name;
  401. +if ( permit_logging == 1 )
  402. +logit("process_fsetstat");
  403. +
  404. id = get_int();
  405. handle = get_handle();
  406. a = get_attrib();
  407. @@ -621,11 +669,14 @@
  408. status = SSH2_FX_FAILURE;
  409. } else {
  410. if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
  411. +if ( permit_logging == 1 )
  412. +logit("process_fsetstat: ftruncate");
  413. ret = ftruncate(fd, a->size);
  414. if (ret == -1)
  415. status = errno_to_portable(errno);
  416. }
  417. if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
  418. + if (permit_chmod == 1) {
  419. #ifdef HAVE_FCHMOD
  420. ret = fchmod(fd, a->perm & 0777);
  421. #else
  422. @@ -633,8 +684,18 @@
  423. #endif
  424. if (ret == -1)
  425. status = errno_to_portable(errno);
  426. + else
  427. + if ( permit_logging == 1 )
  428. + logit("chmod: succeeded.");
  429. + } else {
  430. + status = SSH2_FX_PERMISSION_DENIED;
  431. + if ( permit_logging == 1 )
  432. + logit("chmod: operation prohibited by sftp-server configuration.");
  433. + }
  434. }
  435. if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
  436. +if ( permit_logging == 1 )
  437. +logit("process_fsetstat: utimes");
  438. #ifdef HAVE_FUTIMES
  439. ret = futimes(fd, attrib_to_tv(a));
  440. #else
  441. @@ -644,6 +705,7 @@
  442. status = errno_to_portable(errno);
  443. }
  444. if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
  445. + if (permit_chown == 1) {
  446. #ifdef HAVE_FCHOWN
  447. ret = fchown(fd, a->uid, a->gid);
  448. #else
  449. @@ -651,6 +713,14 @@
  450. #endif
  451. if (ret == -1)
  452. status = errno_to_portable(errno);
  453. + else
  454. + if ( permit_logging == 1 )
  455. + logit("chown: succeeded");
  456. + } else {
  457. + status = SSH2_FX_PERMISSION_DENIED;
  458. + if ( permit_logging == 1 )
  459. + logit("chown: operation prohibited by sftp-server configuration.");
  460. + }
  461. }
  462. }
  463. send_status(id, status);
  464. @@ -680,6 +750,8 @@
  465. }
  466. }
  467. + if ( permit_logging == 1 )
  468. + logit("opendir %s", path);
  469. if (status != SSH2_FX_OK)
  470. send_status(id, status);
  471. xfree(path);
  472. @@ -753,6 +825,8 @@
  473. TRACE("remove id %u name %s", id, name);
  474. ret = unlink(name);
  475. status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
  476. + if ( permit_logging == 1 )
  477. + logit("remove file %s", name);
  478. send_status(id, status);
  479. xfree(name);
  480. }
  481. @@ -770,9 +844,19 @@
  482. a = get_attrib();
  483. mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ?
  484. a->perm & 0777 : 0777;
  485. +
  486. + if (setumask != 0) {
  487. + if ( permit_logging == 1 )
  488. + logit("setting directory creation mode to 0777 and umask to %o.", setumask);
  489. + mode = 0777;
  490. + umask(setumask);
  491. + }
  492. +
  493. TRACE("mkdir id %u name %s mode 0%o", id, name, mode);
  494. ret = mkdir(name, mode);
  495. status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
  496. + if ( permit_logging == 1 )
  497. + logit("mkdir %s", name);
  498. send_status(id, status);
  499. xfree(name);
  500. }
  501. @@ -789,6 +873,8 @@
  502. TRACE("rmdir id %u name %s", id, name);
  503. ret = rmdir(name);
  504. status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
  505. + if ( permit_logging == 1 )
  506. + logit("rmdir %s", name);
  507. send_status(id, status);
  508. xfree(name);
  509. }
  510. @@ -815,6 +901,8 @@
  511. s.name = s.long_name = resolvedname;
  512. send_names(id, 1, &s);
  513. }
  514. + if ( permit_logging == 1 )
  515. + logit("realpath %s", path);
  516. xfree(path);
  517. }
  518. @@ -870,6 +958,8 @@
  519. status = SSH2_FX_OK;
  520. }
  521. send_status(id, status);
  522. + if ( permit_logging == 1 )
  523. + logit("rename old %s new %s", oldpath, newpath);
  524. xfree(oldpath);
  525. xfree(newpath);
  526. }
  527. @@ -895,6 +985,8 @@
  528. s.name = s.long_name = buf;
  529. send_names(id, 1, &s);
  530. }
  531. + if ( permit_logging == 1 )
  532. + logit("readlink %s", path);
  533. xfree(path);
  534. }
  535. @@ -913,6 +1005,8 @@
  536. ret = symlink(oldpath, newpath);
  537. status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
  538. send_status(id, status);
  539. + if ( permit_logging == 1 )
  540. + logit("symlink old %s new %s", oldpath, newpath);
  541. xfree(oldpath);
  542. xfree(newpath);
  543. }
  544. @@ -1034,6 +1128,8 @@
  545. {
  546. fd_set *rset, *wset;
  547. int in, out, max;
  548. + unsigned int val = 0;
  549. + char *umask_env;
  550. ssize_t len, olen, set_size;
  551. /* XXX should use getopt */
  552. @@ -1041,6 +1137,16 @@
  553. __progname = ssh_get_progname(av[0]);
  554. handle_init();
  555. + /* Transaction logging */
  556. +
  557. + if (atoi(getenv("LOG_SFTP")) == 1)
  558. + {
  559. + permit_logging = 1;
  560. + log_init("sftp-server", atoi(getenv("SFTP_LOG_LEVEL")),
  561. + atoi(getenv("SFTP_LOG_FACILITY")), 0);
  562. + };
  563. +
  564. +
  565. #ifdef DEBUG_SFTP_SERVER
  566. log_init("sftp-server", SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 0);
  567. #endif
  568. @@ -1048,6 +1154,39 @@
  569. in = dup(STDIN_FILENO);
  570. out = dup(STDOUT_FILENO);
  571. + if ( permit_logging == 1 )
  572. + logit("Starting sftp-server logging for user %s.", getenv("USER"));
  573. +
  574. + /* Umask control */
  575. +
  576. + umask_env = getenv("SFTP_UMASK");
  577. + while (*umask_env && *umask_env >= '0' && *umask_env <= '9')
  578. + val = val * 8 + *umask_env++ - '0';
  579. +
  580. + if (*umask_env || val > 0777 || val == 0) {
  581. + if ( permit_logging == 1 )
  582. + logit("bad value %o for SFTP_UMASK, turning umask control off.", val);
  583. + setumask = 0;
  584. + } else {
  585. + if ( permit_logging == 1 )
  586. + logit("umask control is on.");
  587. + setumask = val;
  588. + };
  589. +
  590. +
  591. + /* Sensitive client commands */
  592. +
  593. + if (atoi(getenv("SFTP_PERMIT_CHMOD")) != 1) {
  594. + permit_chmod = 0;
  595. + if ( permit_logging == 1 )
  596. + logit("client is not permitted to chmod.");
  597. + };
  598. + if (atoi(getenv("SFTP_PERMIT_CHOWN")) != 1) {
  599. + permit_chown = 0;
  600. + if ( permit_logging == 1 )
  601. + logit("client is not permitted to chown.");
  602. + };
  603. +
  604. #ifdef HAVE_CYGWIN
  605. setmode(in, O_BINARY);
  606. setmode(out, O_BINARY);
  607. @@ -1087,6 +1226,8 @@
  608. len = read(in, buf, sizeof buf);
  609. if (len == 0) {
  610. debug("read eof");
  611. + if ( permit_logging == 1 )
  612. + logit("sftp-server finished.");
  613. exit(0);
  614. } else if (len < 0) {
  615. error("read error");
  616. Index: sshd_config.5
  617. --- sshd_config.5.orig 2004-06-30 14:39:34 +0200
  618. +++ sshd_config.5 2004-08-17 19:54:21 +0200
  619. @@ -407,6 +407,10 @@
  620. DEBUG and DEBUG1 are equivalent.
  621. DEBUG2 and DEBUG3 each specify higher levels of debugging output.
  622. Logging with a DEBUG level violates the privacy of users and is not recommended.
  623. +.It Cm LogSftp
  624. +Specifies whether to perform logging of
  625. +.Nm sftp-server
  626. +subsystem transactions. Must be "yes" or "no." The default value is "no."
  627. .It Cm MACs
  628. Specifies the available MAC (message authentication code) algorithms.
  629. The MAC algorithm is used in protocol version 2
  630. @@ -567,6 +571,37 @@
  631. .It Cm ServerKeyBits
  632. Defines the number of bits in the ephemeral protocol version 1 server key.
  633. The minimum value is 512, and the default is 768.
  634. +.It Cm SftpLogFacility
  635. +Gives the facility code that is used when logging
  636. +.Nm sftp-server .
  637. +transactions. The possible values are: DAEMON, USER, AUTH, LOCAL0,
  638. +LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
  639. +The default is AUTH.
  640. +.It Cm SftpLogLevel
  641. +Gives the verbosity level that is used when logging messages from
  642. +.Nm sftp-server .
  643. +The possible values are:
  644. +QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
  645. +The default is INFO. DEBUG and DEBUG1 are equivalent. DEBUG2
  646. +and DEBUG3 each specify higher levels of debugging output.
  647. +Logging with a DEBUG level violates the privacy of users
  648. +and is not recommended.
  649. +.It Cm SftpPermitChmod
  650. +Specifies whether the sftp-server allows the sftp client to execute chmod
  651. +commands on the server. The default is yes.
  652. +.It Cm SftpPermitChown
  653. +Specifies whether the sftp-server allows the sftp client to execute chown
  654. +or chgrp commands on the server. Turning this value on means that the client
  655. +is allowed to execute both chown and chgrp commands. Turning it off means that
  656. +the client is prohibited from executing either chown or chgrp.
  657. + The default is yes.
  658. +.It Cm SftpUmask
  659. +Specifies an optional umask for
  660. +.Nm sftp-server
  661. +subsystem transactions. If a umask is given, this umask will override all system,
  662. +environment or sftp client permission modes. If
  663. +no umask or an invalid umask is given, file creation mode defaults to the permission
  664. +mode specified by the sftp client. The default is for no umask.
  665. .It Cm StrictModes
  666. Specifies whether
  667. .Nm sshd
  668. Index: sshd_config
  669. --- sshd_config.orig 2004-05-24 02:36:24 +0200
  670. +++ sshd_config 2004-08-17 19:54:21 +0200
  671. @@ -101,3 +101,14 @@
  672. # override default of no subsystems
  673. Subsystem sftp /usr/libexec/sftp-server
  674. +
  675. +# sftp-server logging
  676. +#LogSftp no
  677. +#SftpLogFacility AUTH
  678. +#SftpLogLevel INFO
  679. +
  680. +# sftp-server umask control
  681. +#SftpUmask
  682. +
  683. +#SftpPermitChmod yes
  684. +#SftpPermitChown yes