00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "cf.defs.h"
00034 #include "cf.extern.h"
00035
00036
00037
00038 void CheckForHoles(sstat,ip)
00039
00040
00041
00042
00043 struct stat *sstat;
00044 struct Image *ip;
00045
00046 {
00047 #ifndef IRIX
00048 if (sstat->st_size > sstat->st_blocks * DEV_BSIZE)
00049 #else
00050 # ifdef HAVE_ST_BLOCKS
00051 if (sstat->st_size > sstat->st_blocks * DEV_BSIZE)
00052 # else
00053 if (sstat->st_size > ST_NBLOCKS((*sstat)) * DEV_BSIZE)
00054 # endif
00055 #endif
00056 {
00057 ip->makeholes = 1;
00058 }
00059
00060 ip->makeholes = 0;
00061 }
00062
00063
00064
00065 int CopyRegDisk(source,new,ip)
00066
00067 char *source, *new;
00068 struct Image *ip;
00069
00070 { int sd, dd, buf_size;
00071 char *buf, *cp;
00072 int n_read, *intp;
00073 long n_read_total = 0;
00074 int last_write_made_hole = 0;
00075
00076 if ((sd = open(source,O_RDONLY|O_BINARY)) == -1)
00077 {
00078 snprintf(OUTPUT,bufsize,"Can't copy %s!\n",source);
00079 CfLog(cfinform,OUTPUT,"open");
00080 unlink(new);
00081 return false;
00082 }
00083
00084 unlink(new);
00085
00086 if ((dd = open(new,O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0600)) == -1)
00087 {
00088 snprintf(OUTPUT,bufsize,"Copy %s:%s security - failed attempt to exploit a race? (Not copied)\n",ip->server,new);
00089 CfLog(cfinform,OUTPUT,"open");
00090 close(sd);
00091 unlink(new);
00092 return false;
00093 }
00094
00095 buf_size = ST_BLKSIZE(dstat);
00096 buf = (char *) malloc(buf_size + sizeof(int));
00097
00098 while (true)
00099 {
00100 if ((n_read = read (sd, buf, buf_size)) == -1)
00101 {
00102 if (errno == EINTR)
00103 {
00104 continue;
00105 }
00106
00107 close(sd);
00108 close(dd);
00109 free(buf);
00110 return false;
00111 }
00112
00113 if (n_read == 0)
00114 {
00115 break;
00116 }
00117
00118 n_read_total += n_read;
00119
00120 intp = 0;
00121
00122 if (ip->makeholes)
00123 {
00124 buf[n_read] = 1;
00125
00126
00127
00128 intp = (int *) buf;
00129
00130 while (*intp++ == 0)
00131 {
00132 }
00133
00134
00135
00136 cp = (char *) (intp - 1);
00137
00138 while (*cp++ == 0)
00139 {
00140 }
00141
00142
00143
00144
00145 if (cp > buf + n_read)
00146 {
00147
00148 if (lseek (dd, (off_t) n_read, SEEK_CUR) < 0L)
00149 {
00150 snprintf(OUTPUT,bufsize,"Copy failed (no space?) while doing %s to %s\n",source,new);
00151 CfLog(cferror,OUTPUT,"lseek");
00152 free(buf);
00153 unlink(new);
00154 close(dd);
00155 close(sd);
00156 return false;
00157 }
00158 last_write_made_hole = 1;
00159 }
00160 else
00161 {
00162
00163 intp = 0;
00164 }
00165 }
00166
00167 if (intp == 0)
00168 {
00169 if (cf_full_write (dd, buf, n_read) < 0)
00170 {
00171 snprintf(OUTPUT,bufsize*2,"Copy failed (no space?) while doing %s to %s\n",source,new);
00172 CfLog(cferror,OUTPUT,"");
00173 close(sd);
00174 close(dd);
00175 free(buf);
00176 unlink(new);
00177 return false;
00178 }
00179 last_write_made_hole = 0;
00180 }
00181 }
00182
00183
00184
00185
00186
00187 if (last_write_made_hole)
00188 {
00189
00190
00191 if (cf_full_write (dd, "", 1) < 0 || ftruncate (dd, n_read_total) < 0)
00192 {
00193 CfLog(cferror,"cfengine: full_write or ftruncate error in CopyReg\n","write");
00194 free(buf);
00195 unlink(new);
00196 close(sd);
00197 close(dd);
00198 return false;
00199 }
00200 }
00201
00202 close(sd);
00203 close(dd);
00204
00205 free(buf);
00206 return true;
00207 }
00208
00209
00210
00211 int EmbeddedWrite(new,dd,buf,ip,towrite,last_write_made_hole,n_read)
00212
00213 int dd, towrite,*last_write_made_hole,n_read;
00214 char *new,*buf;
00215 struct Image *ip;
00216
00217 { int *intp;
00218 char *cp;
00219
00220 intp = 0;
00221
00222 if (ip->makeholes)
00223 {
00224 buf[n_read] = 1;
00225
00226
00227 intp = (int *) buf;
00228
00229 while (*intp++ == 0)
00230 {
00231 }
00232
00233
00234
00235 cp = (char *) (intp - 1);
00236
00237 while (*cp++ == 0)
00238 {
00239 }
00240
00241
00242
00243
00244 if (cp > buf + n_read)
00245 {
00246
00247 if (lseek (dd,(off_t)n_read,SEEK_CUR) < 0L)
00248 {
00249 snprintf(OUTPUT,bufsize,"lseek in EmbeddedWrite, dest=%s\n", new);
00250 CfLog(cferror,OUTPUT,"lseek");
00251 return false;
00252 }
00253 *last_write_made_hole = 1;
00254 }
00255 else
00256 {
00257
00258 intp = 0;
00259 }
00260 }
00261
00262 if (intp == 0)
00263 {
00264 if (cf_full_write (dd,buf,towrite) < 0)
00265 {
00266 snprintf(OUTPUT,bufsize*2,"Local disk write(%.256s) failed\n",new);
00267 CfLog(cferror,OUTPUT,"write");
00268 CONN->error = true;
00269 return false;
00270 }
00271
00272 *last_write_made_hole = 0;
00273 }
00274
00275 return true;
00276 }