00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024 #undef DBGC_CLASS
00025 #define DBGC_CLASS DBGC_DMAPI
00026
00027 #ifndef USE_DMAPI
00028
00029 int dmapi_init_session(void) { return -1; }
00030 uint32 dmapi_file_flags(const char * const path) { return 0; }
00031 BOOL dmapi_have_session(void) { return False; }
00032
00033 #else
00034
00035 #ifdef HAVE_XFS_DMAPI_H
00036 #include <xfs/dmapi.h>
00037 #elif defined(HAVE_SYS_DMI_H)
00038 #include <sys/dmi.h>
00039 #elif defined(HAVE_SYS_JFSDMAPI_H)
00040 #include <sys/jfsdmapi.h>
00041 #elif defined(HAVE_SYS_DMAPI_H)
00042 #include <sys/dmapi.h>
00043 #elif defined(HAVE_DMAPI_H)
00044 #include <dmapi.h>
00045 #endif
00046
00047 #define DMAPI_SESSION_NAME "samba"
00048 #define DMAPI_TRACE 10
00049
00050 static dm_sessid_t dmapi_session = DM_NO_SESSION;
00051
00052
00053
00054
00055
00056 static int init_dmapi_service(void)
00057 {
00058 static pid_t lastpid;
00059
00060 pid_t mypid;
00061
00062 mypid = sys_getpid();
00063 if (mypid != lastpid) {
00064 char *version;
00065
00066 lastpid = mypid;
00067 if (dm_init_service(&version) < 0) {
00068 return -1;
00069 }
00070
00071 DEBUG(0, ("Initializing DMAPI: %s\n", version));
00072 }
00073
00074 return 0;
00075 }
00076
00077 BOOL dmapi_have_session(void)
00078 {
00079 return dmapi_session != DM_NO_SESSION;
00080 }
00081
00082 static dm_sessid_t *realloc_session_list(dm_sessid_t * sessions, int count)
00083 {
00084 dm_sessid_t *nsessions;
00085
00086 nsessions = TALLOC_REALLOC_ARRAY(NULL, sessions, dm_sessid_t, count);
00087 if (nsessions == NULL) {
00088 TALLOC_FREE(sessions);
00089 return NULL;
00090 }
00091
00092 return nsessions;
00093 }
00094
00095
00096
00097
00098
00099 int dmapi_init_session(void)
00100 {
00101 char buf[DM_SESSION_INFO_LEN];
00102 size_t buflen;
00103
00104 uint nsessions = 10;
00105 dm_sessid_t *sessions = NULL;
00106
00107 int i, err;
00108
00109
00110
00111
00112 SMB_WARN(getuid() == 0, "dmapi_init_session must be called as root");
00113
00114 dmapi_session = DM_NO_SESSION;
00115 if (init_dmapi_service() < 0) {
00116 return -1;
00117 }
00118
00119 retry:
00120
00121 if ((sessions = realloc_session_list(sessions, nsessions)) == NULL) {
00122 return -1;
00123 }
00124
00125 err = dm_getall_sessions(nsessions, sessions, &nsessions);
00126 if (err < 0) {
00127 if (errno == E2BIG) {
00128 nsessions *= 2;
00129 goto retry;
00130 }
00131
00132 DEBUGADD(DMAPI_TRACE,
00133 ("failed to retrieve DMAPI sessions: %s\n",
00134 strerror(errno)));
00135 TALLOC_FREE(sessions);
00136 return -1;
00137 }
00138
00139 for (i = 0; i < nsessions; ++i) {
00140 err = dm_query_session(sessions[i], sizeof(buf), buf, &buflen);
00141 buf[sizeof(buf) - 1] = '\0';
00142 if (err == 0 && strcmp(DMAPI_SESSION_NAME, buf) == 0) {
00143 dmapi_session = sessions[i];
00144 DEBUGADD(DMAPI_TRACE,
00145 ("attached to existing DMAPI session "
00146 "named '%s'\n", buf));
00147 break;
00148 }
00149 }
00150
00151 TALLOC_FREE(sessions);
00152
00153
00154 if (dmapi_session == DM_NO_SESSION) {
00155 err = dm_create_session(DM_NO_SESSION, DMAPI_SESSION_NAME,
00156 &dmapi_session);
00157 if (err < 0) {
00158 DEBUGADD(DMAPI_TRACE,
00159 ("failed to create new DMAPI session: %s\n",
00160 strerror(errno)));
00161 dmapi_session = DM_NO_SESSION;
00162 return -1;
00163 }
00164
00165 DEBUGADD(DMAPI_TRACE,
00166 ("created new DMAPI session named '%s'\n",
00167 DMAPI_SESSION_NAME));
00168 }
00169
00170
00171
00172
00173
00174
00175
00176 return 0;
00177 }
00178
00179
00180
00181
00182 static int reattach_dmapi_session(void)
00183 {
00184 char buf[DM_SESSION_INFO_LEN];
00185 size_t buflen;
00186
00187 if (dmapi_session != DM_NO_SESSION ) {
00188 become_root();
00189
00190
00191
00192
00193 if (init_dmapi_service() < 0) {
00194 dmapi_session = DM_NO_SESSION;
00195 unbecome_root();
00196 return -1;
00197 }
00198
00199 if (dm_query_session(dmapi_session, sizeof(buf),
00200 buf, &buflen) < 0) {
00201
00202 dmapi_session = DM_NO_SESSION;
00203 unbecome_root();
00204 return -1;
00205 }
00206
00207 set_effective_capability(DMAPI_ACCESS_CAPABILITY);
00208
00209 DEBUG(DMAPI_TRACE, ("reattached DMAPI session\n"));
00210 unbecome_root();
00211 }
00212
00213 return 0;
00214 }
00215
00216 uint32 dmapi_file_flags(const char * const path)
00217 {
00218 static int attached = 0;
00219
00220 int err;
00221 dm_eventset_t events = {0};
00222 uint nevents;
00223
00224 void *dm_handle;
00225 size_t dm_handle_len;
00226
00227 uint32 flags = 0;
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 if (dmapi_have_session() && !attached) {
00239 attached++;
00240 if (reattach_dmapi_session() < 0) {
00241 return 0;
00242 }
00243 }
00244
00245
00246
00247
00248 #ifndef HAVE_POSIX_CAPABILITIES
00249 become_root();
00250 #endif
00251
00252 err = dm_path_to_handle(CONST_DISCARD(char *, path),
00253 &dm_handle, &dm_handle_len);
00254 if (err < 0) {
00255 DEBUG(DMAPI_TRACE, ("dm_path_to_handle(%s): %s\n",
00256 path, strerror(errno)));
00257
00258 if (errno != EPERM) {
00259 goto done;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269 set_effective_capability(DMAPI_ACCESS_CAPABILITY);
00270
00271 err = dm_path_to_handle(CONST_DISCARD(char *, path),
00272 &dm_handle, &dm_handle_len);
00273 if (err < 0) {
00274 DEBUG(DMAPI_TRACE,
00275 ("retrying dm_path_to_handle(%s): %s\n",
00276 path, strerror(errno)));
00277 goto done;
00278 }
00279 }
00280
00281 err = dm_get_eventlist(dmapi_session, dm_handle, dm_handle_len,
00282 DM_NO_TOKEN, DM_EVENT_MAX, &events, &nevents);
00283 if (err < 0) {
00284 DEBUG(DMAPI_TRACE, ("dm_get_eventlist(%s): %s\n",
00285 path, strerror(errno)));
00286 dm_handle_free(dm_handle, dm_handle_len);
00287 goto done;
00288 }
00289
00290
00291
00292
00293
00294 DEBUG(DMAPI_TRACE, ("DMAPI event list for %s is %#llx\n",
00295 path, events));
00296 if (DMEV_ISSET(DM_EVENT_READ, events)) {
00297 flags = FILE_ATTRIBUTE_OFFLINE;
00298 }
00299
00300 dm_handle_free(dm_handle, dm_handle_len);
00301
00302 if (flags & FILE_ATTRIBUTE_OFFLINE) {
00303 DEBUG(DMAPI_TRACE, ("%s is OFFLINE\n", path));
00304 }
00305
00306 done:
00307
00308 #ifndef HAVE_POSIX_CAPABILITIES
00309 unbecome_root();
00310 #endif
00311
00312 return flags;
00313 }
00314
00315 #endif