📄 selfcheck.c
字号:
pw_fd_env = "dummy_PASSWD_FD"; } checkpid = pipespawn(SAMBA_CLIENT, STDERR_PIPE|PASSWD_PIPE, &nullfd, &nullfd, &checkerr, pw_fd_env, &passwdfd, "smbclient", device, *user_and_password ? "-U" : skip_argument, *user_and_password ? user_and_password : skip_argument, "-E", domain ? "-W" : skip_argument, domain ? domain : skip_argument,#if SAMBA_VERSION >= 2 subdir ? "-D" : skip_argument, subdir ? subdir : skip_argument,#endif "-c", "quit", NULL); amfree(domain); aclose(nullfd); /*@ignore@*/ if ((pwtext_len > 0) && fullwrite(passwdfd, pwtext, (size_t)pwtext_len) < 0) { err = vstrallocf(_("password write failed: %s: %s"), amdevice, strerror(errno)); aclose(passwdfd); goto common_exit; } /*@end@*/ memset(user_and_password, '\0', (size_t)lpass); amfree(user_and_password); aclose(passwdfd); ferr = fdopen(checkerr, "r"); if (!ferr) { g_printf(_("ERROR [Can't fdopen: %s]\n"), strerror(errno)); error(_("Can't fdopen: %s"), strerror(errno)); /*NOTREACHED*/ } sep = ""; errdos = 0; for(sep = ""; (line = agets(ferr)) != NULL; free(line)) { if (line[0] == '\0') continue; strappend(extra_info, sep); strappend(extra_info, line); sep = ": "; if(strstr(line, "ERRDOS") != NULL) { errdos = 1; } } afclose(ferr); checkerr = -1; rc = 0; sep = ""; while ((wpid = wait(&retstat)) != -1) { if (!WIFEXITED(retstat) || WEXITSTATUS(retstat) != 0) { char *exitstr = str_exit_status("smbclient", retstat); err = newvstralloc(err, err, sep, exitstr); sep = "\n"; amfree(exitstr); rc = 1; } } if (errdos != 0 || rc != 0) { if (extra_info) { err = newvstrallocf(err, _("samba access error: %s: %s %s"), amdevice, extra_info, err); amfree(extra_info); } else { err = newvstrallocf(err, _("samba access error: %s: %s"), amdevice, err); } }#else err = vstrallocf(_("This client is not configured for samba: %s"), qdisk);#endif goto common_exit; } amode = F_OK; amfree(device); device = amname_to_dirname(amdevice); } else if (strcmp(myprogram, "DUMP") == 0) { if(amdevice[0] == '/' && amdevice[1] == '/') { err = vstrallocf( _("The DUMP program cannot handle samba shares, use GNUTAR: %s"), qdisk); goto common_exit; }#ifdef VDUMP /* { */#ifdef DUMP /* { */ if (strcmp(amname_to_fstype(amdevice), "advfs") == 0)#else /* }{ */ if (1)#endif /* } */ { amfree(device); device = amname_to_dirname(amdevice); amode = F_OK; } else#endif /* } */ { amfree(device); device = amname_to_devname(amdevice);#ifdef USE_RUNDUMP amode = F_OK;#else amode = R_OK;#endif } } else { /* program_is_backup_api==1 */ pid_t backup_api_pid; int property_pipe[2]; backup_support_option_t *bsu; bsu = backup_support_option(program, g_options, disk, amdevice); if (pipe(property_pipe) < 0) { err = vstrallocf(_("pipe failed: %s"), strerror(errno)); goto common_exit; } fflush(stdout);fflush(stderr); switch (backup_api_pid = fork()) { case -1: err = vstrallocf(_("fork failed: %s"), strerror(errno)); goto common_exit; case 0: /* child */ { char *argvchild[14]; char *cmd = vstralloc(DUMPER_DIR, "/", program, NULL); int j=0; argvchild[j++] = program; argvchild[j++] = "selfcheck"; if (bsu->message_line == 1) { argvchild[j++] = "--message"; argvchild[j++] = "line"; } if (g_options->config != NULL && bsu->config == 1) { argvchild[j++] = "--config"; argvchild[j++] = g_options->config; } if (g_options->hostname != NULL && bsu->host == 1) { argvchild[j++] = "--host"; argvchild[j++] = g_options->hostname; } if (disk != NULL && bsu->disk == 1) { argvchild[j++] = "--disk"; argvchild[j++] = disk; } argvchild[j++] = "--device"; argvchild[j++] = amdevice; if(options && options->createindex && bsu->index_line == 1) { argvchild[j++] = "--index"; argvchild[j++] = "line"; } if (!options->no_record && bsu->record == 1) { argvchild[j++] = "--record"; } argvchild[j++] = NULL; dup2(property_pipe[0], 0); aclose(property_pipe[1]); safe_fd(-1, 0); execve(cmd,argvchild,safe_env()); g_printf(_("ERROR [Can't execute %s: %s]\n"), cmd, strerror(errno)); exit(127); } default: /* parent */ { int status; aclose(property_pipe[0]); toolin = fdopen(property_pipe[1],"w"); if (!toolin) { err = vstrallocf(_("Can't fdopen: %s"), strerror(errno)); goto common_exit; } output_tool_property(toolin, options); fflush(toolin); fclose(toolin); if (waitpid(backup_api_pid, &status, 0) < 0) { if (!WIFEXITED(status)) { err = vstrallocf(_("Tool exited with signal %d"), WTERMSIG(status)); } else if (WEXITSTATUS(status) != 0) { err = vstrallocf(_("Tool exited with status %d"), WEXITSTATUS(status)); } else { err = vstrallocf(_("waitpid returned negative value")); } goto common_exit; } } } amfree(bsu); fflush(stdout);fflush(stderr); amfree(device); amfree(qamdevice); amfree(qdisk); return; } qdevice = quote_string(device); dbprintf(_("device %s\n"), qdevice); /* skip accessability test if this is an AFS entry */ if(strncmp_const(device, "afs:") != 0) {#ifdef CHECK_FOR_ACCESS_WITH_OPEN access_result = open(device, O_RDONLY); access_type = "open";#else access_result = access(device, amode); access_type = "access";#endif if(access_result == -1) { err = vstrallocf(_("Could not access %s (%s): %s"), qdevice, qdisk, strerror(errno)); }#ifdef CHECK_FOR_ACCESS_WITH_OPEN aclose(access_result);#endif }common_exit: amfree(share); amfree(subdir); if(user_and_password) { memset(user_and_password, '\0', (size_t)lpass); amfree(user_and_password); } amfree(domain); if(err) { g_printf(_("ERROR [%s]\n"), err); dbprintf(_("%s\n"), err); amfree(err); } else { g_printf("OK %s\n", qdisk); dbprintf(_("disk %s OK\n"), qdisk); g_printf("OK %s\n", qamdevice); dbprintf(_("amdevice %s OK\n"), qamdevice); g_printf("OK %s\n", qdevice); dbprintf(_("device %s OK\n"), qdevice); } if(extra_info) { dbprintf(_("extra info: %s\n"), extra_info); amfree(extra_info); } amfree(qdisk); amfree(qdevice); amfree(qamdevice); amfree(device); /* XXX perhaps do something with level: read dumpdates and sanity check */}static voidcheck_overall(void){ char *cmd; struct stat buf; int testfd; char *gnutar_list_dir; int need_amandates = 0; if( need_runtar ) { cmd = vstralloc(amlibexecdir, "/", "runtar", versionsuffix(), NULL); check_file(cmd,X_OK); check_suid(cmd); amfree(cmd); } if( need_rundump ) { cmd = vstralloc(amlibexecdir, "/", "rundump", versionsuffix(), NULL); check_file(cmd,X_OK); check_suid(cmd); amfree(cmd); } if( need_dump ) {#ifdef DUMP check_file(DUMP, X_OK);#else g_printf(_("ERROR [DUMP program not available]\n"));#endif } if( need_restore ) {#ifdef RESTORE check_file(RESTORE, X_OK);#else g_printf(_("ERROR [RESTORE program not available]\n"));#endif } if ( need_vdump ) {#ifdef VDUMP check_file(VDUMP, X_OK);#else g_printf(_("ERROR [VDUMP program not available]\n"));#endif } if ( need_vrestore ) {#ifdef VRESTORE check_file(VRESTORE, X_OK);#else g_printf(_("ERROR [VRESTORE program not available]\n"));#endif } if( need_xfsdump ) {#ifdef XFSDUMP check_file(XFSDUMP, F_OK);#else g_printf(_("ERROR [XFSDUMP program not available]\n"));#endif } if( need_xfsrestore ) {#ifdef XFSRESTORE check_file(XFSRESTORE, X_OK);#else g_printf(_("ERROR [XFSRESTORE program not available]\n"));#endif } if( need_vxdump ) {#ifdef VXDUMP check_file(VXDUMP, X_OK);#else g_printf(_("ERROR [VXDUMP program not available]\n"));#endif } if( need_vxrestore ) {#ifdef VXRESTORE check_file(VXRESTORE, X_OK);#else g_printf(_("ERROR [VXRESTORE program not available]\n"));#endif } if( need_gnutar ) {#ifdef GNUTAR check_file(GNUTAR, X_OK);#else g_printf(_("ERROR [GNUTAR program not available]\n"));#endif need_amandates = 1; gnutar_list_dir = getconf_str(CNF_GNUTAR_LIST_DIR); if (strlen(gnutar_list_dir) == 0) gnutar_list_dir = NULL; if (gnutar_list_dir) check_dir(gnutar_list_dir, R_OK|W_OK); } if (need_amandates) { char *amandates_file; amandates_file = getconf_str(CNF_AMANDATES); check_file(amandates_file, R_OK|W_OK); } if( need_calcsize ) { char *cmd; cmd = vstralloc(amlibexecdir, "/", "calcsize", versionsuffix(), NULL); check_file(cmd, X_OK); amfree(cmd); } if( need_samba ) {#ifdef SAMBA_CLIENT check_file(SAMBA_CLIENT, X_OK);#else g_printf(_("ERROR [SMBCLIENT program not available]\n"));#endif testfd = open("/etc/amandapass", R_OK); if (testfd >= 0) { if(fstat(testfd, &buf) == 0) { if ((buf.st_mode & 0x7) != 0) { g_printf(_("ERROR [/etc/amandapass is world readable!]\n")); } else { g_printf(_("OK [/etc/amandapass is readable, but not by all]\n")); } } else { g_printf(_("OK [unable to stat /etc/amandapass: %s]\n"), strerror(errno)); } aclose(testfd); } else { g_printf(_("ERROR [unable to open /etc/amandapass: %s]\n"), strerror(errno)); } } if (need_compress_path ) check_file(COMPRESS_PATH, X_OK); if (need_dump || need_xfsdump ) { if (check_file_exist("/etc/dumpdates")) { check_file("/etc/dumpdates",#ifdef USE_RUNDUMP F_OK#else R_OK|W_OK#endif ); } else {#ifndef USE_RUNDUMP if (access("/etc", R_OK|W_OK) == -1) { g_printf(_("ERROR [dump will not be able to create the /etc/dumpdates file: %s]\n"), strerror(errno)); }#endif } } if (need_vdump) { if (check_file_exist("/etc/vdumpdates")) { check_file("/etc/vdumpdates", F_OK); } } check_access("/dev/null", R_OK|W_OK); check_space(AMANDA_TMPDIR, (off_t)64); /* for amandad i/o */#ifdef AMANDA_DBGDIR check_space(AMANDA_DBGDIR, (off_t)64); /* for amandad i/o */#endif check_space("/etc", (off_t)64); /* for /etc/dumpdates writing */}static voidcheck_space( char * dir, off_t kbytes){ struct fs_usage fsusage; char *quoted = quote_string(dir); intmax_t kb_avail; if(get_fs_usage(dir, NULL, &fsusage) == -1) { g_printf(_("ERROR [cannot get filesystem usage for %s: %s]\n"), quoted, strerror(errno)); amfree(quoted); return; } /* do the division first to avoid potential integer overflow */ kb_avail = fsusage.fsu_bavail / 1024 * fsusage.fsu_blocksize; if (fsusage.fsu_bavail_top_bit_set || fsusage.fsu_bavail == 0) { g_printf(_("ERROR [dir %s needs %lldKB, has nothing available.]\n"), quoted, (long long)kbytes); } else if (kb_avail < kbytes) { g_printf(_("ERROR [dir %s needs %lldKB, only has %lldKB available.]\n"), quoted, (long long)kbytes, (long long)kb_avail); } else { g_printf(_("OK %s has more than %lldKB available.\n"), quoted, (long long)kbytes); } amfree(quoted);}static voidcheck_access( char * filename, int mode){ char *noun, *adjective; char *quoted = quote_string(filename); if(mode == F_OK) noun = "find", adjective = "exists"; else if((mode & X_OK) == X_OK) noun = "execute", adjective = "executable"; else if((mode & (W_OK|R_OK)) == (W_OK|R_OK)) noun = "read/write", adjective = "read/writable"; else noun = "access", adjective = "accessible"; if(access(filename, mode) == -1) g_printf(_("ERROR [can not %s %s: %s]\n"), noun, quoted, strerror(errno)); else g_printf(_("OK %s %s\n"), quoted, adjective); amfree(quoted);}static intcheck_file_exist( char *filename){ struct stat stat_buf; if (stat(filename, &stat_buf) != 0) { if(errno == ENOENT) { return 0; } } return 1;}static voidcheck_file( char * filename, int mode){ struct stat stat_buf; char *quoted; if(!stat(filename, &stat_buf)) { if(!S_ISREG(stat_buf.st_mode)) { quoted = quote_string(filename); g_printf(_("ERROR [%s is not a file]\n"), quoted); amfree(quoted); } } check_access(filename, mode);}static voidcheck_dir( char * dirname, int mode){ struct stat stat_buf; char *quoted; char *dir; if(!stat(dirname, &stat_buf)) { if(!S_ISDIR(stat_buf.st_mode)) { quoted = quote_string(dirname); g_printf(_("ERROR [%s is not a directory]\n"), quoted); amfree(quoted); } } dir = stralloc2(dirname, "/."); check_access(dir, mode); amfree(dir);}static voidcheck_suid( char * filename){#ifndef SINGLE_USERID struct stat stat_buf; char *quoted = quote_string(filename); if(!stat(filename, &stat_buf)) { if(stat_buf.st_uid != 0 ) { g_printf(_("ERROR [%s is not owned by root]\n"), quoted); } if((stat_buf.st_mode & S_ISUID) != S_ISUID) { g_printf(_("ERROR [%s is not SUID root]\n"), quoted); } } else { g_printf(_("ERROR [can not stat %s]\n"), quoted); } amfree(quoted);#else (void)filename; /* Quiet unused parameter warning */#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -