static void do_setrattr(char *name, uint16 attr, int set) { uint16 oldattr; if (!cli_getatr(cli, name, &oldattr, NULL, NULL)) return; if (set == ATTRSET) { attr |= oldattr; } else { attr = oldattr & ~attr; } if (!cli_setatr(cli, name, attr, 0)) { DEBUG(1,("setatr failed: %s\n", cli_errstr(cli))); } }
/***************************************************** a wrapper for utime and utimes *******************************************************/ static int smbw_settime(const char *fname, time_t t) { struct smbw_server *srv; fstring server, share; pstring path; uint16 mode; if (!fname) { errno = EINVAL; return -1; } smbw_init(); smbw_busy++; /* work out what server they are after */ smbw_parse_path(fname, server, share, path); /* get a connection to the server */ srv = smbw_server(server, share); if (!srv) { /* smbw_server sets errno */ goto failed; } if (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) { errno = smbw_errno(&srv->cli); goto failed; } if (!cli_setatr(&srv->cli, path, mode, t)) { /* some servers always refuse directory changes */ if (!(mode & aDIR)) { errno = smbw_errno(&srv->cli); goto failed; } } smbw_busy--; return 0; failed: smbw_busy--; return -1; }
/***************************************************** try to do a QPATHINFO and if that fails then do a getatr this is needed because win95 sometimes refuses the qpathinfo *******************************************************/ BOOL smbw_getatr(struct smbw_server *srv, char *path, uint16 *mode, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time, SMB_INO_T *ino) { DEBUG(4,("sending qpathinfo\n")); if (!srv->no_pathinfo2 && cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL, size, mode, ino)) return True; /* if this is NT then don't bother with the getatr */ if (srv->cli.capabilities & CAP_NT_SMBS) return False; if (cli_getatr(&srv->cli, path, mode, size, m_time)) { a_time = c_time = m_time; srv->no_pathinfo2 = True; return True; } return False; }
/***************************************************** a wrapper for chown() *******************************************************/ int smbw_chown(const char *fname, uid_t owner, gid_t group) { struct smbw_server *srv; fstring server, share; pstring path; uint16 mode; if (!fname) { errno = EINVAL; return -1; } smbw_init(); smbw_busy++; /* work out what server they are after */ smbw_parse_path(fname, server, share, path); /* get a connection to the server */ srv = smbw_server(server, share); if (!srv) { /* smbw_server sets errno */ goto failed; } if (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) { errno = smbw_errno(&srv->cli); goto failed; } /* assume success */ smbw_busy--; return 0; failed: smbw_busy--; return -1; }
/* * Get info from an SMB server on a file. Use a qpathinfo call first * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo */ bool SMBC_getatr(SMBCCTX * context, SMBCSRV *srv, const char *path, uint16_t *mode, off_t *size, struct timespec *create_time_ts, struct timespec *access_time_ts, struct timespec *write_time_ts, struct timespec *change_time_ts, SMB_INO_T *ino) { char *fixedpath = NULL; char *targetpath = NULL; struct cli_state *targetcli = NULL; time_t write_time; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return False; } /* path fixup for . and .. */ if (strequal(path, ".") || strequal(path, "..")) { fixedpath = talloc_strdup(frame, "\\"); if (!fixedpath) { errno = ENOMEM; TALLOC_FREE(frame); return False; } } else { fixedpath = talloc_strdup(frame, path); if (!fixedpath) { errno = ENOMEM; TALLOC_FREE(frame); return False; } trim_string(fixedpath, NULL, "\\.."); trim_string(fixedpath, NULL, "\\."); } DEBUG(4,("SMBC_getatr: sending qpathinfo\n")); status = cli_resolve_path(frame, "", context->internal->auth_info, srv->cli, fixedpath, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { d_printf("Couldn't resolve %s\n", path); errno = ENOENT; TALLOC_FREE(frame); return False; } if (!srv->no_pathinfo2 && NT_STATUS_IS_OK(cli_qpathinfo2(targetcli, targetpath, create_time_ts, access_time_ts, write_time_ts, change_time_ts, size, mode, ino))) { TALLOC_FREE(frame); return True; } srv->no_pathinfo2 = True; if (!srv->no_pathinfo3 && NT_STATUS_IS_OK(cli_qpathinfo3(targetcli, targetpath, create_time_ts, access_time_ts, write_time_ts, change_time_ts, size, mode, ino))) { TALLOC_FREE(frame); return True; } srv->no_pathinfo3 = True; /* if this is NT then don't bother with the getatr */ if (smb1cli_conn_capabilities(targetcli->conn) & CAP_NT_SMBS) { goto all_failed; } if (NT_STATUS_IS_OK(cli_getatr(targetcli, targetpath, mode, size, &write_time))) { struct timespec w_time_ts; w_time_ts = convert_time_t_to_timespec(write_time); if (write_time_ts != NULL) { *write_time_ts = w_time_ts; } if (create_time_ts != NULL) { *create_time_ts = w_time_ts; } if (access_time_ts != NULL) { *access_time_ts = w_time_ts; } if (change_time_ts != NULL) { *change_time_ts = w_time_ts; } if (ino) { *ino = 0; } TALLOC_FREE(frame); return True; } all_failed: srv->no_pathinfo2 = False; srv->no_pathinfo3 = False; errno = EPERM; TALLOC_FREE(frame); return False; }