今回はSambaを取り上げます。Sambaは、Unix系マシンをWindowsファイル共有サーバーにするためのソフトウェアとして有名です。市販のNAS(ネットワーク接続ストレージ)の多くも、LinuxとSambaの組み合わせでその機能を実現しています。ここでは、昨年2009年に発見・修正された問題を取り上げてみましょう。
サンプルコード
Sambaでは、種々のサーバープログラムと共に、サーバーに接続するためのクライアントプログラムも提供しています。今回は、そのクライアントプログラムのソースコードに含まれているcmd_get()という関数に注目しましょう。それほど長い関数ではありませんが、他の部分で定義されている関数をいろいろ呼び出しているので、それらのプロトタイプ宣言とコメント部分を一緒に並べてあります。
/* Get us the current top of the talloc stack. */ TALLOC_CTX *talloc_tos(void); /* strdup with a talloc */ char *talloc_strdup(const void *t, const char *p); /* Get the next token from a string, return false if none found. */ bool next_token_talloc(TALLOC_CTX *ctx, const char **ptr, char **pp_buff, const char *sep); /* print intenal strings in the "display charset" */ int d_printf(const char *format, ...); /* Realloc s to append the formatted result of fmt and return s, which may have moved. Good for gradually accumulating output into a string buffer. */ char *talloc_asprintf_append(char *s, const char *fmt, ...); /* Reduce a file name, removing .. elements. */ char *clean_name(TALLOC_CTX *ctx, const char *s); /* Get a file from rname to lname */ static int do_get(const char *rname, const char *lname_in, bool reget); /**************************************************************************** Get a file. ****************************************************************************/ static int cmd_get(void) { TALLOC_CTX *ctx = talloc_tos(); char *lname = NULL; char *rname = NULL; char *fname = NULL; rname = talloc_strdup(ctx, client_get_cur_dir()); if (!rname) { return 1; } if (!next_token_talloc(ctx, &cmd_ptr,&fname,NULL)) { d_printf("get <filename> [localname]\n"); return 1; } rname = talloc_asprintf_append(rname, fname); if (!rname) { return 1; } rname = clean_name(ctx, rname); if (!rname) { return 1; } next_token_talloc(ctx, &cmd_ptr,&lname,NULL); if (!lname) { lname = fname; } return do_get(rname, lname, false); }