From c624a704be96488f0aee27930cbd4c8d99df464b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 9 Jul 2009 22:03:52 +0200 Subject: Make escape_ldap_string take a talloc context --- source3/include/proto.h | 2 +- source3/lib/ldap_escape.c | 25 +++++++++++++---------- source3/lib/smbldap_util.c | 12 +++++------ source3/libads/ldap_user.c | 6 +++--- source3/passdb/pdb_ldap.c | 45 ++++++++++++++++++++--------------------- source3/utils/net_ads.c | 10 ++++----- source3/winbindd/winbindd_ads.c | 6 +++--- 7 files changed, 54 insertions(+), 52 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index f887b4e796..c0f4dc10d8 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -554,7 +554,7 @@ void init_ldap_debugging(void); /* The following definitions come from lib/ldap_escape.c */ -char *escape_ldap_string_alloc(const char *s); +char *escape_ldap_string(TALLOC_CTX *mem_ctx, const char *s); char *escape_rdn_val_string_alloc(const char *s); /* The following definitions come from lib/module.c */ diff --git a/source3/lib/ldap_escape.c b/source3/lib/ldap_escape.c index d101bc5ecd..a731cb9864 100644 --- a/source3/lib/ldap_escape.c +++ b/source3/lib/ldap_escape.c @@ -32,10 +32,10 @@ * and to be free()ed by the caller. **/ -char *escape_ldap_string_alloc(const char *s) +char *escape_ldap_string(TALLOC_CTX *mem_ctx, const char *s) { size_t len = strlen(s)+1; - char *output = (char *)SMB_MALLOC(len); + char *output = talloc_array(mem_ctx, char, len); const char *sub; int i = 0; char *p = output; @@ -43,7 +43,7 @@ char *escape_ldap_string_alloc(const char *s) if (output == NULL) { return NULL; } - + while (*s) { switch (*s) @@ -64,14 +64,17 @@ char *escape_ldap_string_alloc(const char *s) sub = NULL; break; } - + if (sub) { + char *tmp; len = len + 3; - output = (char *)SMB_REALLOC(output, len); - if (!output) { + tmp = talloc_realloc(mem_ctx, output, char, len); + if (tmp == NULL) { + TALLOC_FREE(output); return NULL; } - + output = tmp; + p = &output[i]; strncpy (p, sub, 3); p += 3; @@ -84,7 +87,7 @@ char *escape_ldap_string_alloc(const char *s) } s++; } - + *p = '\0'; return output; } @@ -101,7 +104,7 @@ char *escape_rdn_val_string_alloc(const char *s) } p = output; - + while (*s) { switch (*s) @@ -122,10 +125,10 @@ char *escape_rdn_val_string_alloc(const char *s) *p = *s; p++; } - + s++; } - + *p = '\0'; /* resize the string to the actual final size */ diff --git a/source3/lib/smbldap_util.c b/source3/lib/smbldap_util.c index 66aef6ba66..478a3d24ca 100644 --- a/source3/lib/smbldap_util.c +++ b/source3/lib/smbldap_util.c @@ -126,7 +126,7 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state, char *escape_domain_name; /* escape for filter */ - escape_domain_name = escape_ldap_string_alloc(domain_name); + escape_domain_name = escape_ldap_string(talloc_tos(), domain_name); if (!escape_domain_name) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; @@ -135,11 +135,11 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state, if (asprintf(&filter, "(&(%s=%s)(objectclass=%s))", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), escape_domain_name, LDAP_OBJ_DOMINFO) < 0) { - SAFE_FREE(escape_domain_name); + TALLOC_FREE(escape_domain_name); return NT_STATUS_NO_MEMORY; } - SAFE_FREE(escape_domain_name); + TALLOC_FREE(escape_domain_name); attr_list = get_attr_list(NULL, dominfo_attr_list ); rc = smbldap_search_suffix(ldap_state, filter, attr_list, &result); @@ -258,7 +258,7 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, int count; char *escape_domain_name; - escape_domain_name = escape_ldap_string_alloc(domain_name); + escape_domain_name = escape_ldap_string(talloc_tos(), domain_name); if (!escape_domain_name) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; @@ -268,11 +268,11 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, LDAP_OBJ_DOMINFO, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), escape_domain_name) < 0) { - SAFE_FREE(escape_domain_name); + TALLOC_FREE(escape_domain_name); return NT_STATUS_NO_MEMORY; } - SAFE_FREE(escape_domain_name); + TALLOC_FREE(escape_domain_name); DEBUG(2, ("smbldap_search_domain_info: Searching for:[%s]\n", filter)); diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index eecd9045e5..69dc05335e 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -30,18 +30,18 @@ ADS_STATUS status; char *ldap_exp; const char *attrs[] = {"*", NULL}; - char *escaped_user = escape_ldap_string_alloc(user); + char *escaped_user = escape_ldap_string(talloc_tos(), user); if (!escaped_user) { return ADS_ERROR(LDAP_NO_MEMORY); } if (asprintf(&ldap_exp, "(samAccountName=%s)", escaped_user) == -1) { - SAFE_FREE(escaped_user); + TALLOC_FREE(escaped_user); return ADS_ERROR(LDAP_NO_MEMORY); } status = ads_search(ads, res, ldap_exp, attrs); SAFE_FREE(ldap_exp); - SAFE_FREE(escaped_user); + TALLOC_FREE(escaped_user); return status; } diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 3579325769..173298561f 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -336,7 +336,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, const char **attr) { char *filter = NULL; - char *escape_user = escape_ldap_string_alloc(user); + char *escape_user = escape_ldap_string(talloc_tos(), user); int ret = -1; if (!escape_user) { @@ -350,7 +350,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, filter = talloc_asprintf(talloc_tos(), "(&%s%s)", "(uid=%u)", get_objclass_filter(ldap_state->schema_ver)); if (!filter) { - SAFE_FREE(escape_user); + TALLOC_FREE(escape_user); return LDAP_NO_MEMORY; } /* @@ -360,7 +360,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, filter = talloc_all_string_sub(talloc_tos(), filter, "%u", escape_user); - SAFE_FREE(escape_user); + TALLOC_FREE(escape_user); if (!filter) { return LDAP_NO_MEMORY; } @@ -2120,18 +2120,18 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s /* does the entry already exist but without a samba attributes? we need to return the samba attributes here */ - escape_user = escape_ldap_string_alloc( username ); + escape_user = escape_ldap_string(talloc_tos(), username); filter = talloc_strdup(attr_list, "(uid=%u)"); if (!filter) { status = NT_STATUS_NO_MEMORY; goto fn_exit; } filter = talloc_all_string_sub(attr_list, filter, "%u", escape_user); + TALLOC_FREE(escape_user); if (!filter) { status = NT_STATUS_NO_MEMORY; goto fn_exit; } - SAFE_FREE(escape_user); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr_list, &result); @@ -2278,7 +2278,6 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s fn_exit: TALLOC_FREE(ctx); - SAFE_FREE(escape_user); if (result) { ldap_msgfree(result); } @@ -2528,7 +2527,7 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, const char *name) { char *filter = NULL; - char *escape_name = escape_ldap_string_alloc(name); + char *escape_name = escape_ldap_string(talloc_tos(), name); NTSTATUS status; if (!escape_name) { @@ -2540,11 +2539,11 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN), escape_name) < 0) { - SAFE_FREE(escape_name); + TALLOC_FREE(escape_name); return NT_STATUS_NO_MEMORY; } - SAFE_FREE(escape_name); + TALLOC_FREE(escape_name); status = ldapsam_getgroup(methods, filter, map); SAFE_FREE(filter); return status; @@ -2665,20 +2664,19 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, for (memberuid = values; *memberuid != NULL; memberuid += 1) { char *escape_memberuid; - escape_memberuid = escape_ldap_string_alloc(*memberuid); + escape_memberuid = escape_ldap_string(talloc_tos(), + *memberuid); if (escape_memberuid == NULL) { ret = NT_STATUS_NO_MEMORY; goto done; } filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid); + TALLOC_FREE(escape_memberuid); if (filter == NULL) { - SAFE_FREE(escape_memberuid); ret = NT_STATUS_NO_MEMORY; goto done; } - - SAFE_FREE(escape_memberuid); } filter = talloc_asprintf_append_buffer(filter, "))"); @@ -2812,7 +2810,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, return NT_STATUS_INVALID_PARAMETER; } - escape_name = escape_ldap_string_alloc(pdb_get_username(user)); + escape_name = escape_ldap_string(talloc_tos(), pdb_get_username(user)); if (escape_name == NULL) return NT_STATUS_NO_MEMORY; @@ -2950,7 +2948,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, done: - SAFE_FREE(escape_name); + TALLOC_FREE(escape_name); return ret; } @@ -4185,14 +4183,14 @@ static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username) goto done; } - escaped = escape_ldap_string_alloc(username); + escaped = escape_ldap_string(talloc_tos(), username); if (escaped == NULL) goto done; result = talloc_string_sub(mem_ctx, filter, "%u", username); done: SAFE_FREE(filter); - SAFE_FREE(escaped); + TALLOC_FREE(escaped); return result; } @@ -4994,10 +4992,10 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, is_machine = True; } - username = escape_ldap_string_alloc(name); + username = escape_ldap_string(talloc_tos(), name); filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass=%s))", username, LDAP_OBJ_POSIXACCOUNT); - SAFE_FREE(username); + TALLOC_FREE(username); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); if (rc != LDAP_SUCCESS) { @@ -5270,10 +5268,10 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods, gid_t gid = -1; int rc; - groupname = escape_ldap_string_alloc(name); + groupname = escape_ldap_string(talloc_tos(), name); filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))", groupname, LDAP_OBJ_POSIXGROUP); - SAFE_FREE(groupname); + TALLOC_FREE(groupname); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); if (rc != LDAP_SUCCESS) { @@ -5702,7 +5700,8 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods, return NT_STATUS_NO_MEMORY; } - escape_username = escape_ldap_string_alloc(pdb_get_username(sampass)); + escape_username = escape_ldap_string(talloc_tos(), + pdb_get_username(sampass)); if (escape_username== NULL) { return NT_STATUS_NO_MEMORY; } @@ -5715,7 +5714,7 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods, LDAP_OBJ_POSIXACCOUNT, LDAP_OBJ_SAMBASAMACCOUNT); - SAFE_FREE(escape_username); + TALLOC_FREE(escape_username); if (filter == NULL) { return NT_STATUS_NO_MEMORY; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index d82715eb45..f746fc6bd5 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -521,7 +521,7 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv) return net_ads_user_usage(c, argc, argv); } - escaped_user = escape_ldap_string_alloc(argv[0]); + escaped_user = escape_ldap_string(talloc_tos(), argv[0]); if (!escaped_user) { d_fprintf(stderr, "ads_user_info: failed to escape user %s\n", argv[0]); @@ -529,12 +529,12 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv) } if (!ADS_ERR_OK(ads_startup(c, false, &ads))) { - SAFE_FREE(escaped_user); + TALLOC_FREE(escaped_user); return -1; } if (asprintf(&searchstring, "(sAMAccountName=%s)", escaped_user) == -1) { - SAFE_FREE(escaped_user); + TALLOC_FREE(escaped_user); return -1; } rc = ads_search(ads, &res, searchstring, attrs); @@ -543,7 +543,7 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv) if (!ADS_ERR_OK(rc)) { d_fprintf(stderr, "ads_search: %s\n", ads_errstr(rc)); ads_destroy(&ads); - SAFE_FREE(escaped_user); + TALLOC_FREE(escaped_user); return -1; } @@ -563,7 +563,7 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv) ads_msgfree(ads, res); ads_destroy(&ads); - SAFE_FREE(escaped_user); + TALLOC_FREE(escaped_user); return 0; } diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index 0f40419a0e..edd70667c0 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -608,7 +608,7 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain, goto done; } - if (!(escaped_dn = escape_ldap_string_alloc(user_dn))) { + if (!(escaped_dn = escape_ldap_string(talloc_tos(), user_dn))) { status = NT_STATUS_NO_MEMORY; goto done; } @@ -620,12 +620,12 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain, GROUP_TYPE_SECURITY_ENABLED); if (!ldap_exp) { DEBUG(1,("lookup_usergroups(dn=%s) asprintf failed!\n", user_dn)); - SAFE_FREE(escaped_dn); + TALLOC_FREE(escaped_dn); status = NT_STATUS_NO_MEMORY; goto done; } - SAFE_FREE(escaped_dn); + TALLOC_FREE(escaped_dn); rc = ads_search_retry(ads, &res, ldap_exp, group_attrs); -- cgit From f1fad2efe4daf95ad77db6251ad5d77fb9ef755c Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Thu, 9 Jul 2009 15:56:36 -0700 Subject: s3: Fix two arguments that broke when plumbing smb_filneame through dos_mode() --- source3/smbd/dosmode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index ca926aa33c..d3df80ad91 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -448,8 +448,8 @@ static bool get_stat_dos_flags(connection_struct *conn, if (S_ISDIR(smb_fname->st.st_ex_mode)) *dosmode |= aDIR; - *dosmode |= set_sparse_flag(smb_fname->st); - *dosmode |= set_link_read_only_flag(smb_fname->st); + *dosmode |= set_sparse_flag(&smb_fname->st); + *dosmode |= set_link_read_only_flag(&smb_fname->st); return true; } -- cgit From 12ed9ca36a4f8d2f3798f357a619389c26c9feea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2009 17:02:00 +0200 Subject: s3:smbd: fix parsing of invalid SMB2 requests. Because of 0 - 2 => 0xFFFFFFFE, we got EMSGSIZE from the tstream layer. And terminate the transport connection. Instead we should let the caller deal with the invalid parameter, when checking the body size. So the caller always gets at least a 2 byte body. metze --- source3/smbd/smb2_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 43afb1b901..204e57d860 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -1339,7 +1339,7 @@ static int smbd_smb2_request_next_vector(struct tstream_context *stream, if (invalid) { /* the caller should check this */ - body_size = 0; + body_size = 2; } if ((body_size % 2) != 0) { @@ -1376,7 +1376,7 @@ static int smbd_smb2_request_next_vector(struct tstream_context *stream, */ memcpy(body, hdr + SMB2_HDR_BODY, 2); vector[0].iov_base = body + 2; - vector[0].iov_len = req->in.vector[idx].iov_len - 2; + vector[0].iov_len = body_size - 2; vector[1] = req->in.vector[idx+1]; -- cgit From 24c8e786bcdf2d10e378b655e1df69c2533f7804 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Jul 2009 11:33:58 +0200 Subject: s3:smbd: fix parsing of SMB2 Lock requests with lock_count > 1 We should not reuse the variable 'i'. metze --- source3/smbd/smb2_lock.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'source3') diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 3ffe053481..da57181e86 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -41,7 +41,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) { const uint8_t *inhdr; const uint8_t *inbody; - int i = req->current_idx; + const int i = req->current_idx; size_t expected_body_size = 0x30; size_t body_size; uint16_t in_lock_count; @@ -50,6 +50,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) struct smbd_smb2_lock_element *in_locks; struct tevent_req *subreq; const uint8_t *lock_buffer; + uint16_t l; inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { @@ -64,7 +65,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) } in_lock_count = CVAL(inbody, 0x02); - /* 0x04 4 bytes reserved */ + /* 0x04 - 4 bytes reserved */ in_file_id_persistent = BVAL(inbody, 0x08); in_file_id_volatile = BVAL(inbody, 0x10); @@ -88,19 +89,21 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); } - i = 0; + l = 0; lock_buffer = inbody + 0x18; - in_locks[i].offset = BVAL(lock_buffer, 0x00); - in_locks[i].length = BVAL(lock_buffer, 0x08); - in_locks[i].flags = BVAL(lock_buffer, 0x10); + in_locks[l].offset = BVAL(lock_buffer, 0x00); + in_locks[l].length = BVAL(lock_buffer, 0x08); + in_locks[l].flags = IVAL(lock_buffer, 0x10); + /* 0x14 - 4 reserved bytes */ lock_buffer = (const uint8_t *)req->in.vector[i+2].iov_base; - for (i=1; i < in_lock_count; i++) { - in_locks[i].offset = BVAL(lock_buffer, 0x00); - in_locks[i].length = BVAL(lock_buffer, 0x08); - in_locks[i].flags = BVAL(lock_buffer, 0x10); + for (l=1; l < in_lock_count; l++) { + in_locks[l].offset = BVAL(lock_buffer, 0x00); + in_locks[l].length = BVAL(lock_buffer, 0x08); + in_locks[l].flags = IVAL(lock_buffer, 0x10); + /* 0x14 - 4 reserved bytes */ lock_buffer += 0x18; } -- cgit From be1e5493c5aa323681d2843f37e93a0388e95f6a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Jul 2009 11:34:14 +0200 Subject: s3:smbd: pass down the client pid to smbd_smb2_lock_send() metze --- source3/smbd/smb2_lock.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3') diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index da57181e86..06e97b97b0 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -31,6 +31,7 @@ struct smbd_smb2_lock_element { static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct smbd_smb2_request *smb2req, + uint32_t in_smbpid, uint64_t in_file_id_volatile, uint16_t in_lock_count, struct smbd_smb2_lock_element *in_locks); @@ -44,6 +45,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) const int i = req->current_idx; size_t expected_body_size = 0x30; size_t body_size; + uint32_t in_smbpid; uint16_t in_lock_count; uint64_t in_file_id_persistent; uint64_t in_file_id_volatile; @@ -64,6 +66,8 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); } + in_smbpid = IVAL(inhdr, SMB2_HDR_PID); + in_lock_count = CVAL(inbody, 0x02); /* 0x04 - 4 bytes reserved */ in_file_id_persistent = BVAL(inbody, 0x08); @@ -111,6 +115,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) subreq = smbd_smb2_lock_send(req, req->conn->smb2.event_ctx, req, + in_smbpid, in_file_id_volatile, in_lock_count, in_locks); @@ -175,6 +180,7 @@ struct smbd_smb2_lock_state { static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct smbd_smb2_request *smb2req, + uint32_t in_smbpid, uint64_t in_file_id_volatile, uint16_t in_lock_count, struct smbd_smb2_lock_element *in_locks) -- cgit From 598a9892bc4d5db2c75b218ba235fb7736b6a6e6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2009 17:24:25 +0200 Subject: s3:smbd: abstract the main locking logic from the LockingAndX parsing This prepares SMB2 Lock support. metze --- source3/smbd/reply.c | 432 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 254 insertions(+), 178 deletions(-) (limited to 'source3') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 1fd4e50ea6..4a915d6f90 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -7223,6 +7223,212 @@ uint64_t get_lock_offset(const uint8_t *data, int data_offset, return offset; } +struct smbd_lock_element { + uint32_t smbpid; + enum brl_type brltype; + uint64_t offset; + uint64_t count; +}; + +static NTSTATUS smbd_do_locking(struct smb_request *req, + files_struct *fsp, + uint8_t type, + int32_t timeout, + uint16_t num_ulocks, + struct smbd_lock_element *ulocks, + uint16_t num_locks, + struct smbd_lock_element *locks, + bool *async) +{ + connection_struct *conn = req->conn; + int i; + NTSTATUS status = NT_STATUS_OK; + + *async = false; + + /* Data now points at the beginning of the list + of smb_unlkrng structs */ + for(i = 0; i < (int)num_ulocks; i++) { + struct smbd_lock_element *e = &ulocks[i]; + + DEBUG(10,("smbd_do_locking: unlock start=%.0f, len=%.0f for " + "pid %u, file %s\n", + (double)e->offset, + (double)e->count, + (unsigned int)e->smbpid, + fsp->fsp_name)); + + if (e->brltype != UNLOCK_LOCK) { + /* this can only happen with SMB2 */ + return NT_STATUS_INVALID_PARAMETER; + } + + status = do_unlock(smbd_messaging_context(), + fsp, + e->smbpid, + e->count, + e->offset, + WINDOWS_LOCK); + + DEBUG(10, ("smbd_do_locking: unlock returned %s\n", + nt_errstr(status))); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + /* Setup the timeout in seconds. */ + + if (!lp_blocking_locks(SNUM(conn))) { + timeout = 0; + } + + /* Data now points at the beginning of the list + of smb_lkrng structs */ + + for(i = 0; i < (int)num_locks; i++) { + struct smbd_lock_element *e = &locks[i]; + + DEBUG(10,("smbd_do_locking: lock start=%.0f, len=%.0f for pid " + "%u, file %s timeout = %d\n", + (double)e->offset, + (double)e->count, + (unsigned int)e->smbpid, + fsp->fsp_name, + (int)timeout)); + + if (type & LOCKING_ANDX_CANCEL_LOCK) { + struct blocking_lock_record *blr = NULL; + + if (lp_blocking_locks(SNUM(conn))) { + + /* Schedule a message to ourselves to + remove the blocking lock record and + return the right error. */ + + blr = blocking_lock_cancel(fsp, + e->smbpid, + e->offset, + e->count, + WINDOWS_LOCK, + type, + NT_STATUS_FILE_LOCK_CONFLICT); + if (blr == NULL) { + return NT_STATUS_DOS( + ERRDOS, + ERRcancelviolation); + } + } + /* Remove a matching pending lock. */ + status = do_lock_cancel(fsp, + e->smbpid, + e->count, + e->offset, + WINDOWS_LOCK, + blr); + } else { + bool blocking_lock = timeout ? true : false; + bool defer_lock = false; + struct byte_range_lock *br_lck; + uint32_t block_smbpid; + + br_lck = do_lock(smbd_messaging_context(), + fsp, + e->smbpid, + e->count, + e->offset, + e->brltype, + WINDOWS_LOCK, + blocking_lock, + &status, + &block_smbpid, + NULL); + + if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) { + /* Windows internal resolution for blocking locks seems + to be about 200ms... Don't wait for less than that. JRA. */ + if (timeout != -1 && timeout < lp_lock_spin_time()) { + timeout = lp_lock_spin_time(); + } + defer_lock = true; + } + + /* This heuristic seems to match W2K3 very well. If a + lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT + it pretends we asked for a timeout of between 150 - 300 milliseconds as + far as I can tell. Replacement for do_lock_spin(). JRA. */ + + if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock && + NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) { + defer_lock = true; + timeout = lp_lock_spin_time(); + } + + if (br_lck && defer_lock) { + /* + * A blocking lock was requested. Package up + * this smb into a queued request and push it + * onto the blocking lock queue. + */ + if(push_blocking_lock_request(br_lck, + req, + fsp, + timeout, + i, + e->smbpid, + e->brltype, + WINDOWS_LOCK, + e->offset, + e->count, + block_smbpid)) { + TALLOC_FREE(br_lck); + *async = true; + return NT_STATUS_OK; + } + } + + TALLOC_FREE(br_lck); + } + + if (!NT_STATUS_IS_OK(status)) { + break; + } + } + + /* If any of the above locks failed, then we must unlock + all of the previous locks (X/Open spec). */ + + if (num_locks != 0 && !NT_STATUS_IS_OK(status)) { + + if (type & LOCKING_ANDX_CANCEL_LOCK) { + i = -1; /* we want to skip the for loop */ + } + + /* + * Ensure we don't do a remove on the lock that just failed, + * as under POSIX rules, if we have a lock already there, we + * will delete it (and we shouldn't) ..... + */ + for(i--; i >= 0; i--) { + struct smbd_lock_element *e = &locks[i]; + + do_unlock(smbd_messaging_context(), + fsp, + e->smbpid, + e->count, + e->offset, + WINDOWS_LOCK); + } + return status; + } + + DEBUG(3, ("smbd_do_locking: fnum=%d type=%d num_locks=%d num_ulocks=%d\n", + fsp->fnum, (unsigned int)type, num_locks, num_ulocks)); + + return NT_STATUS_OK; +} + /**************************************************************************** Reply to a lockingX request. ****************************************************************************/ @@ -7235,14 +7441,15 @@ void reply_lockingX(struct smb_request *req) unsigned char oplocklevel; uint16 num_ulocks; uint16 num_locks; - uint64_t count = 0, offset = 0; - uint32 lock_pid; int32 lock_timeout; int i; const uint8_t *data; bool large_file_format; bool err; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + struct smbd_lock_element *ulocks; + struct smbd_lock_element *locks; + bool async = false; START_PROFILE(SMBlockingX); @@ -7355,12 +7562,27 @@ void reply_lockingX(struct smb_request *req) return; } + ulocks = talloc_array(req, struct smbd_lock_element, num_ulocks); + if (ulocks == NULL) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + END_PROFILE(SMBlockingX); + return; + } + + locks = talloc_array(req, struct smbd_lock_element, num_locks); + if (locks == NULL) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + END_PROFILE(SMBlockingX); + return; + } + /* Data now points at the beginning of the list of smb_unlkrng structs */ for(i = 0; i < (int)num_ulocks; i++) { - lock_pid = get_lock_pid( data, i, large_file_format); - count = get_lock_count( data, i, large_file_format); - offset = get_lock_offset( data, i, large_file_format, &err); + ulocks[i].smbpid = get_lock_pid(data, i, large_file_format); + ulocks[i].count = get_lock_count(data, i, large_file_format); + ulocks[i].offset = get_lock_offset(data, i, large_file_format, &err); + ulocks[i].brltype = UNLOCK_LOCK; /* * There is no error code marked "stupid client bug".... :-). @@ -7370,32 +7592,6 @@ void reply_lockingX(struct smb_request *req) reply_doserror(req, ERRDOS, ERRnoaccess); return; } - - DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for " - "pid %u, file %s\n", (double)offset, (double)count, - (unsigned int)lock_pid, fsp->fsp_name )); - - status = do_unlock(smbd_messaging_context(), - fsp, - lock_pid, - count, - offset, - WINDOWS_LOCK); - - DEBUG(10, ("reply_lockingX: unlock returned %s\n", - nt_errstr(status))); - - if (NT_STATUS_V(status)) { - END_PROFILE(SMBlockingX); - reply_nterror(req, status); - return; - } - } - - /* Setup the timeout in seconds. */ - - if (!lp_blocking_locks(SNUM(conn))) { - lock_timeout = 0; } /* Now do any requested locks */ @@ -7405,11 +7601,23 @@ void reply_lockingX(struct smb_request *req) of smb_lkrng structs */ for(i = 0; i < (int)num_locks; i++) { - enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ? - READ_LOCK:WRITE_LOCK); - lock_pid = get_lock_pid( data, i, large_file_format); - count = get_lock_count( data, i, large_file_format); - offset = get_lock_offset( data, i, large_file_format, &err); + locks[i].smbpid = get_lock_pid(data, i, large_file_format); + locks[i].count = get_lock_count(data, i, large_file_format); + locks[i].offset = get_lock_offset(data, i, large_file_format, &err); + + if (locktype & LOCKING_ANDX_SHARED_LOCK) { + if (locktype & LOCKING_ANDX_CANCEL_LOCK) { + locks[i].brltype = PENDING_READ_LOCK; + } else { + locks[i].brltype = READ_LOCK; + } + } else { + if (locktype & LOCKING_ANDX_CANCEL_LOCK) { + locks[i].brltype = PENDING_WRITE_LOCK; + } else { + locks[i].brltype = WRITE_LOCK; + } + } /* * There is no error code marked "stupid client bug".... :-). @@ -7419,154 +7627,22 @@ void reply_lockingX(struct smb_request *req) reply_doserror(req, ERRDOS, ERRnoaccess); return; } - - DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid " - "%u, file %s timeout = %d\n", (double)offset, - (double)count, (unsigned int)lock_pid, - fsp->fsp_name, (int)lock_timeout )); - - if (locktype & LOCKING_ANDX_CANCEL_LOCK) { - struct blocking_lock_record *blr = NULL; - - if (lp_blocking_locks(SNUM(conn))) { - - /* Schedule a message to ourselves to - remove the blocking lock record and - return the right error. */ - - blr = blocking_lock_cancel(fsp, - lock_pid, - offset, - count, - WINDOWS_LOCK, - locktype, - NT_STATUS_FILE_LOCK_CONFLICT); - if (blr == NULL) { - END_PROFILE(SMBlockingX); - reply_nterror( - req, - NT_STATUS_DOS( - ERRDOS, - ERRcancelviolation)); - return; - } - } - /* Remove a matching pending lock. */ - status = do_lock_cancel(fsp, - lock_pid, - count, - offset, - WINDOWS_LOCK, - blr); - } else { - bool blocking_lock = lock_timeout ? True : False; - bool defer_lock = False; - struct byte_range_lock *br_lck; - uint32 block_smbpid; - - br_lck = do_lock(smbd_messaging_context(), - fsp, - lock_pid, - count, - offset, - lock_type, - WINDOWS_LOCK, - blocking_lock, - &status, - &block_smbpid, - NULL); - - if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) { - /* Windows internal resolution for blocking locks seems - to be about 200ms... Don't wait for less than that. JRA. */ - if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) { - lock_timeout = lp_lock_spin_time(); - } - defer_lock = True; - } - - /* This heuristic seems to match W2K3 very well. If a - lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT - it pretends we asked for a timeout of between 150 - 300 milliseconds as - far as I can tell. Replacement for do_lock_spin(). JRA. */ - - if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock && - NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) { - defer_lock = True; - lock_timeout = lp_lock_spin_time(); - } - - if (br_lck && defer_lock) { - /* - * A blocking lock was requested. Package up - * this smb into a queued request and push it - * onto the blocking lock queue. - */ - if(push_blocking_lock_request(br_lck, - req, - fsp, - lock_timeout, - i, - lock_pid, - lock_type, - WINDOWS_LOCK, - offset, - count, - block_smbpid)) { - TALLOC_FREE(br_lck); - END_PROFILE(SMBlockingX); - return; - } - } - - TALLOC_FREE(br_lck); - } - - if (NT_STATUS_V(status)) { - break; - } } - /* If any of the above locks failed, then we must unlock - all of the previous locks (X/Open spec). */ - if (num_locks != 0 && !NT_STATUS_IS_OK(status)) { - - if (locktype & LOCKING_ANDX_CANCEL_LOCK) { - i = -1; /* we want to skip the for loop */ - } - - /* - * Ensure we don't do a remove on the lock that just failed, - * as under POSIX rules, if we have a lock already there, we - * will delete it (and we shouldn't) ..... - */ - for(i--; i >= 0; i--) { - lock_pid = get_lock_pid( data, i, large_file_format); - count = get_lock_count( data, i, large_file_format); - offset = get_lock_offset( data, i, large_file_format, - &err); - - /* - * There is no error code marked "stupid client - * bug".... :-). - */ - if(err) { - END_PROFILE(SMBlockingX); - reply_doserror(req, ERRDOS, ERRnoaccess); - return; - } - - do_unlock(smbd_messaging_context(), - fsp, - lock_pid, - count, - offset, - WINDOWS_LOCK); - } + status = smbd_do_locking(req, fsp, + locktype, lock_timeout, + num_ulocks, ulocks, + num_locks, locks, + &async); + if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBlockingX); reply_nterror(req, status); return; } + if (async) { + END_PROFILE(SMBlockingX); + return; + } reply_outbuf(req, 2, 0); -- cgit From 8d534d45a5d21967e2d9bca1ac34a55f1518fe42 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2009 18:09:16 +0200 Subject: s3:smbd: make smbd_do_locking() non static metze --- source3/smbd/globals.h | 17 +++++++++++++++++ source3/smbd/reply.c | 25 +++++++++---------------- 2 files changed, 26 insertions(+), 16 deletions(-) (limited to 'source3') diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 3d195c84f0..8163213dd0 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -168,6 +168,23 @@ NTSTATUS smb2_signing_check_pdu(DATA_BLOB session_key, const struct iovec *vector, int count); +struct smbd_lock_element { + uint32_t smbpid; + enum brl_type brltype; + uint64_t offset; + uint64_t count; +}; + +NTSTATUS smbd_do_locking(struct smb_request *req, + files_struct *fsp, + uint8_t type, + int32_t timeout, + uint16_t num_ulocks, + struct smbd_lock_element *ulocks, + uint16_t num_locks, + struct smbd_lock_element *locks, + bool *async); + void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn, const char *reason, const char *location); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 4a915d6f90..98ee83ea83 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -7223,22 +7223,15 @@ uint64_t get_lock_offset(const uint8_t *data, int data_offset, return offset; } -struct smbd_lock_element { - uint32_t smbpid; - enum brl_type brltype; - uint64_t offset; - uint64_t count; -}; - -static NTSTATUS smbd_do_locking(struct smb_request *req, - files_struct *fsp, - uint8_t type, - int32_t timeout, - uint16_t num_ulocks, - struct smbd_lock_element *ulocks, - uint16_t num_locks, - struct smbd_lock_element *locks, - bool *async) +NTSTATUS smbd_do_locking(struct smb_request *req, + files_struct *fsp, + uint8_t type, + int32_t timeout, + uint16_t num_ulocks, + struct smbd_lock_element *ulocks, + uint16_t num_locks, + struct smbd_lock_element *locks, + bool *async) { connection_struct *conn = req->conn; int i; -- cgit From 67c7b7f90bd1bad265e892bb00abf649b22345b6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2009 13:13:32 +0200 Subject: s3:smbd: add support for SMB2 Lock metze --- source3/smbd/smb2_lock.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 151 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 06e97b97b0..325c789320 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -190,6 +190,13 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, struct smb_request *smbreq; connection_struct *conn = smb2req->tcon->compat_conn; files_struct *fsp; + int32_t timeout = -1; + uint8_t type = 0; + bool isunlock = false; + uint16_t i; + struct smbd_lock_element *locks; + NTSTATUS status; + bool async = false; req = tevent_req_create(mem_ctx, &state, struct smbd_smb2_lock_state); @@ -220,7 +227,150 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED); + locks = talloc_array(state, struct smbd_lock_element, in_lock_count); + if (locks == NULL) { + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); + return tevent_req_post(req, ev); + } + + switch (in_locks[0].flags) { + case SMB2_LOCK_FLAG_SHARED: + case SMB2_LOCK_FLAG_EXCLUSIVE: + if (in_lock_count > 1) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + timeout = -1; + break; + + case SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY: + case SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY: + timeout = 0; + break; + + case SMB2_LOCK_FLAG_UNLOCK: + /* only the first lock gives the UNLOCK bit - see + MS-SMB2 3.3.5.14 */ + isunlock = true; + timeout = 0; + break; + + default: + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + for (i=0; i 0) { + tevent_req_nterror(req, + NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + if (isunlock) { + tevent_req_nterror(req, + NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + break; + + case SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY: + case SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY: + if (isunlock) { + tevent_req_nterror(req, + NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + break; + + case SMB2_LOCK_FLAG_UNLOCK: + if (!isunlock) { + tevent_req_nterror(req, + NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + break; + + default: + if (isunlock) { + /* + * is the first element was a UNLOCK + * we need to deferr the error response + * to the backend, because we need to process + * all unlock elements before + */ + invalid = true; + break; + } + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + locks[i].smbpid = in_smbpid; + locks[i].offset = in_locks[i].offset; + locks[i].count = in_locks[i].length; + + if (in_locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE) { + locks[i].brltype = WRITE_LOCK; + } else if (in_locks[i].flags & SMB2_LOCK_FLAG_SHARED) { + locks[i].brltype = READ_LOCK; + } else if (invalid) { + /* + * this is an invalid UNLOCK element + * and the backend needs to test for + * brltype != UNLOCK_LOCK and return + * NT_STATUS_INVALID_PARAMER + */ + locks[i].brltype = READ_LOCK; + } else { + locks[i].brltype = UNLOCK_LOCK; + } + + max_count = UINT64_MAX - locks[i].offset; + if (locks[i].count > max_count) { + tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_RANGE); + return tevent_req_post(req, ev); + } + } + + if (isunlock) { + status = smbd_do_locking(smbreq, fsp, + 0, + timeout, + in_lock_count, + locks, + 0, + NULL, + &async); + } else { + status = smbd_do_locking(smbreq, fsp, + 0, + timeout, + 0, + NULL, + in_lock_count, + locks, + &async); + } + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { + status = NT_STATUS_LOCK_NOT_GRANTED; + } + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + + if (async) { + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return tevent_req_post(req, ev); + } + + tevent_req_done(req); return tevent_req_post(req, ev); } -- cgit From 0a0bff353e3cd8287166c7ed907a50a8599b0e03 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Jul 2009 17:29:22 +0200 Subject: Fix our base64 implementation for blobs of length 4.... The additional length check bit us exactly at 4, removing it. The torture test survives valgrind up to 2000 bytes :-) --- source3/lib/util_str.c | 2 +- source3/script/tests/test_smbtorture_s3.sh | 1 + source3/torture/torture.c | 34 ++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index cdd7d0a300..0aff9439e9 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -1932,7 +1932,7 @@ char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data) result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */ SMB_ASSERT(result != NULL); - while (len-- && out_cnt < (data.length * 2) - 5) { + while (len--) { int c = (unsigned char) *(data.data++); bits += c; char_count++; diff --git a/source3/script/tests/test_smbtorture_s3.sh b/source3/script/tests/test_smbtorture_s3.sh index c577ed18d4..4301081cec 100755 --- a/source3/script/tests/test_smbtorture_s3.sh +++ b/source3/script/tests/test_smbtorture_s3.sh @@ -29,6 +29,7 @@ tests="$tests DIR DIR1 TCON TCONDEV RW1 RW2 RW3" tests="$tests OPEN XCOPY RENAME DELETE PROPERTIES W2K" tests="$tests TCON2 IOCTL CHKPATH FDSESS LOCAL-SUBSTITUTE CHAIN1" tests="$tests GETADDRINFO POSIX UID-REGRESSION-TEST SHORTNAME-TEST" +tests="$tests LOCAL-BASE64" skipped1="RANDOMIPC NEGNOWAIT NBENCH ERRMAPEXTRACT TRANS2SCAN NTTRANSSCAN" skipped2="DENY1 DENY2 OPENATTR CASETABLE EATEST" diff --git a/source3/torture/torture.c b/source3/torture/torture.c index aa7e83bcc8..15083ef90d 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -5749,6 +5749,39 @@ static bool run_local_substitute(int dummy) return ok; } +static bool run_local_base64(int dummy) +{ + int i; + bool ret = true; + + for (i=1; i<2000; i++) { + DATA_BLOB blob1, blob2; + char *b64; + + blob1.data = talloc_array(talloc_tos(), uint8_t, i); + blob1.length = i; + generate_random_buffer(blob1.data, blob1.length); + + b64 = base64_encode_data_blob(talloc_tos(), blob1); + if (b64 == NULL) { + d_fprintf(stderr, "base64_encode_data_blob failed " + "for %d bytes\n", i); + ret = false; + } + blob2 = base64_decode_data_blob(b64); + TALLOC_FREE(b64); + + if (data_blob_cmp(&blob1, &blob2)) { + d_fprintf(stderr, "data_blob_cmp failed for %d " + "bytes\n", i); + ret = false; + } + TALLOC_FREE(blob1.data); + data_blob_free(&blob2); + } + return ret; +} + static bool run_local_gencache(int dummy) { char *val; @@ -6487,6 +6520,7 @@ static struct { { "STREAMERROR", run_streamerror }, { "LOCAL-SUBSTITUTE", run_local_substitute, 0}, { "LOCAL-GENCACHE", run_local_gencache, 0}, + { "LOCAL-BASE64", run_local_base64, 0}, { "LOCAL-RBTREE", run_local_rbtree, 0}, { "LOCAL-MEMCACHE", run_local_memcache, 0}, { "LOCAL-STREAM-NAME", run_local_stream_name, 0}, -- cgit From 3969f65aaa1c0e5d3158f089a2fe496af6dd60b0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Jul 2009 17:36:18 +0200 Subject: Fix&Run local-gencache --- source3/script/tests/test_smbtorture_s3.sh | 2 +- source3/torture/torture.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'source3') diff --git a/source3/script/tests/test_smbtorture_s3.sh b/source3/script/tests/test_smbtorture_s3.sh index 4301081cec..2894d7e90a 100755 --- a/source3/script/tests/test_smbtorture_s3.sh +++ b/source3/script/tests/test_smbtorture_s3.sh @@ -29,7 +29,7 @@ tests="$tests DIR DIR1 TCON TCONDEV RW1 RW2 RW3" tests="$tests OPEN XCOPY RENAME DELETE PROPERTIES W2K" tests="$tests TCON2 IOCTL CHKPATH FDSESS LOCAL-SUBSTITUTE CHAIN1" tests="$tests GETADDRINFO POSIX UID-REGRESSION-TEST SHORTNAME-TEST" -tests="$tests LOCAL-BASE64" +tests="$tests LOCAL-BASE64 LOCAL-GENCACHE" skipped1="RANDOMIPC NEGNOWAIT NBENCH ERRMAPEXTRACT TRANS2SCAN NTTRANSSCAN" skipped2="DENY1 DENY2 OPENATTR CASETABLE EATEST" diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 15083ef90d..8e38093e33 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -5829,15 +5829,13 @@ static bool run_local_gencache(int dummy) } blob = data_blob_string_const_null("bar"); - tm = time(NULL); + tm = time(NULL) + 60; if (!gencache_set_data_blob("foo", &blob, tm)) { d_printf("%s: gencache_set_data_blob() failed\n", __location__); return False; } - data_blob_free(&blob); - if (!gencache_get_data_blob("foo", &blob, NULL)) { d_printf("%s: gencache_get_data_blob() failed\n", __location__); return False; -- cgit From 4e516fb19146399546bd9cd249ee3adb60c07e16 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 12:03:51 -0700 Subject: s3 smb2: Remove unused variable --- source3/smbd/smb2_lock.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3') diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 325c789320..121b4eb24d 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -191,7 +191,6 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, connection_struct *conn = smb2req->tcon->compat_conn; files_struct *fsp; int32_t timeout = -1; - uint8_t type = 0; bool isunlock = false; uint16_t i; struct smbd_lock_element *locks; -- cgit From d8556bbf1394439d0880983c7dff67dd8dda66b0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 5 Jul 2009 14:39:16 +0200 Subject: Quieten events and tldap debug messages --- source3/lib/events.c | 2 +- source3/passdb/pdb_ads.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/lib/events.c b/source3/lib/events.c index 08debb4252..7a06ad0829 100644 --- a/source3/lib/events.c +++ b/source3/lib/events.c @@ -286,7 +286,7 @@ static void s3_event_debug(void *context, enum tevent_debug_level level, samba_level = 2; break; case TEVENT_DEBUG_TRACE: - samba_level = 10; + samba_level = 11; break; }; diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c index eec63728ca..82bc1677f0 100644 --- a/source3/passdb/pdb_ads.c +++ b/source3/passdb/pdb_ads.c @@ -2111,7 +2111,7 @@ static void s3_tldap_debug(void *context, enum tldap_debug_level level, samba_level = 2; break; case TLDAP_DEBUG_TRACE: - samba_level = 10; + samba_level = 11; break; }; -- cgit From afc6f607d5c8ba995b55464525edc8bf8f7a040c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 9 Jul 2009 15:58:10 +0200 Subject: Return 0 domains from enum_trusteddoms --- source3/passdb/pdb_ads.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c index 82bc1677f0..ddfeb8ed80 100644 --- a/source3/passdb/pdb_ads.c +++ b/source3/passdb/pdb_ads.c @@ -2022,7 +2022,9 @@ static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m, uint32 *num_domains, struct trustdom_info ***domains) { - return NT_STATUS_NOT_IMPLEMENTED; + *num_domains = 0; + *domains = NULL; + return NT_STATUS_OK; } static void pdb_ads_init_methods(struct pdb_methods *m) -- cgit From 361aa19e69d4176dd8c30f485cc637cd33308d62 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Jul 2009 15:50:40 -0700 Subject: Add hash values to the xattr ACLS to determine when an underlying POSIX ACL is changed out from under us. Passes RAW-ACL test up to "invalid owner" problem when trying to create a file owned by Everyone. Now needs porting to modules/vfs_acl_tdb.c Jeremy. --- source3/modules/vfs_acl_xattr.c | 213 +++++++++++++++++++++++++++++----------- 1 file changed, 158 insertions(+), 55 deletions(-) (limited to 'source3') diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index 66bf21c4f7..eb6653bcd1 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -27,13 +27,45 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS +static NTSTATUS create_acl_blob(const struct security_descriptor *psd, + DATA_BLOB *pblob, + uint8_t hash[16]); + +#define HASH_SECURITY_INFO (OWNER_SECURITY_INFORMATION | \ + GROUP_SECURITY_INFORMATION | \ + DACL_SECURITY_INFORMATION | \ + SACL_SECURITY_INFORMATION) + +/******************************************************************* + Hash a security descriptor. +*******************************************************************/ + +static NTSTATUS hash_sd(struct security_descriptor *psd, + uint8_t hash[16]) +{ + DATA_BLOB blob; + struct MD5Context tctx; + NTSTATUS status; + + memset(hash, '\0', 16); + status = create_acl_blob(psd, &blob, hash); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + MD5Init(&tctx); + MD5Update(&tctx, blob.data, blob.length); + MD5Final(hash, &tctx); + return NT_STATUS_OK; +} + /******************************************************************* Parse out a struct security_descriptor from a DATA_BLOB. *******************************************************************/ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, uint32 security_info, - struct security_descriptor **ppdesc) + struct security_descriptor **ppdesc, + uint8_t hash[16]) { TALLOC_CTX *ctx = talloc_tos(); struct xattr_NTACL xacl; @@ -64,6 +96,7 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, ? xacl.info.sd_hs->sd->dacl : NULL, &sd_size); + memcpy(hash, xacl.info.sd_hs->hash, 16); TALLOC_FREE(xacl.info.sd); return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; @@ -131,7 +164,9 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, Create a DATA_BLOB from a security descriptor. *******************************************************************/ -static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob) +static NTSTATUS create_acl_blob(const struct security_descriptor *psd, + DATA_BLOB *pblob, + uint8_t hash[16]) { struct xattr_NTACL xacl; struct security_descriptor_hash sd_hs; @@ -144,7 +179,7 @@ static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB xacl.version = 2; xacl.info.sd_hs = &sd_hs; xacl.info.sd_hs->sd = CONST_DISCARD(struct security_descriptor *, psd); - memset(&xacl.info.sd_hs->hash[0], '\0', 16); + memcpy(&xacl.info.sd_hs->hash[0], hash, 16); ndr_err = ndr_push_struct_blob( pblob, ctx, NULL, &xacl, @@ -242,9 +277,11 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, uint32 security_info, struct security_descriptor **ppdesc) { - TALLOC_CTX *ctx = talloc_tos(); DATA_BLOB blob; NTSTATUS status; + uint8_t hash[16]; + uint8_t hash_tmp[16]; + struct security_descriptor *pdesc_next = NULL; if (fsp && name == NULL) { name = fsp->fsp_name; @@ -252,19 +289,74 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, DEBUG(10, ("get_nt_acl_xattr_internal: name=%s\n", name)); - status = get_acl_blob(ctx, handle, fsp, name, &blob); + status = get_acl_blob(talloc_tos(), handle, fsp, name, &blob); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("get_acl_blob returned %s\n", nt_errstr(status))); return status; } - status = parse_acl_blob(&blob, security_info, ppdesc); + status = parse_acl_blob(&blob, security_info, ppdesc, &hash[0]); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("parse_acl_blob returned %s\n", nt_errstr(status))); return status; } + /* If there was no stored hash, don't check. */ + memset(&hash_tmp[0], '\0', 16); + if (memcmp(&hash[0], &hash_tmp[0], 16) == 0) { + /* No hash, goto return blob sd. */ + goto out; + } + + /* Get the full underlying sd, then hash. */ + if (fsp) { + status = SMB_VFS_NEXT_FGET_NT_ACL(handle, + fsp, + HASH_SECURITY_INFO, + &pdesc_next); + } else { + status = SMB_VFS_NEXT_GET_NT_ACL(handle, + name, + HASH_SECURITY_INFO, + &pdesc_next); + } + + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + status = hash_sd(pdesc_next, hash_tmp); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + if (memcmp(&hash[0], &hash_tmp[0], 16) == 0) { + TALLOC_FREE(pdesc_next); + /* Hash matches, return blob sd. */ + goto out; + } + + /* Hash doesn't match, return underlying sd. */ + + if (!(security_info & OWNER_SECURITY_INFORMATION)) { + pdesc_next->owner_sid = NULL; + } + if (!(security_info & GROUP_SECURITY_INFORMATION)) { + pdesc_next->group_sid = NULL; + } + if (!(security_info & DACL_SECURITY_INFORMATION)) { + pdesc_next->dacl = NULL; + } + if (!(security_info & SACL_SECURITY_INFORMATION)) { + pdesc_next->sacl = NULL; + } + + TALLOC_FREE(*ppdesc); + *ppdesc = pdesc_next; + + out: + TALLOC_FREE(blob.data); return status; } @@ -324,9 +416,11 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, NTSTATUS status; struct security_descriptor *parent_desc = NULL; struct security_descriptor *psd = NULL; + struct security_descriptor *pdesc_next = NULL; DATA_BLOB blob; size_t size; char *parent_name; + uint8_t hash[16]; if (!parent_dirname(ctx, fname, &parent_name, NULL)) { return NT_STATUS_NO_MEMORY; @@ -382,11 +476,9 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { if (fsp && fsp->posix_open) { - ret = vfs_lstat_smb_fname(handle->conn, fname, - &sbuf); + ret = vfs_lstat_smb_fname(handle->conn,fname, &sbuf); } else { - ret = vfs_stat_smb_fname(handle->conn, fname, - &sbuf); + ret = vfs_stat_smb_fname(handle->conn,fname, &sbuf); } } if (ret == -1) { @@ -403,7 +495,28 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, } } - status = create_acl_blob(psd, &blob); + /* Object exists. Read the current SD to get the hash. */ + if (fsp) { + status = SMB_VFS_NEXT_FGET_NT_ACL(handle, + fsp, + HASH_SECURITY_INFO, + &pdesc_next); + } else { + status = SMB_VFS_NEXT_GET_NT_ACL(handle, + fname, + HASH_SECURITY_INFO, + &pdesc_next); + } + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = hash_sd(pdesc_next, hash); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = create_acl_blob(psd, &blob, hash); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -430,6 +543,13 @@ static int open_acl_xattr(vfs_handle_struct *handle, char *fname = NULL; NTSTATUS status; + if (fsp->base_fsp) { + /* Stream open. Base filename open already did the ACL check. */ + DEBUG(10,("open_acl_xattr: stream open on %s\n", + smb_fname_str_dbg(smb_fname) )); + return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode); + } + status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); if (!NT_STATUS_IS_OK(status)) { @@ -497,23 +617,8 @@ static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t m static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, struct security_descriptor **ppdesc) { - NTSTATUS status = get_nt_acl_xattr_internal(handle, fsp, + return get_nt_acl_xattr_internal(handle, fsp, NULL, security_info, ppdesc); - if (NT_STATUS_IS_OK(status)) { - if (DEBUGLEVEL >= 10) { - DEBUG(10,("fget_nt_acl_xattr: returning xattr sd for file %s\n", - fsp->fsp_name)); - NDR_PRINT_DEBUG(security_descriptor, *ppdesc); - } - return NT_STATUS_OK; - } - - DEBUG(10,("fget_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n", - fsp->fsp_name, - nt_errstr(status) )); - - return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, - security_info, ppdesc); } /********************************************************************* @@ -523,23 +628,8 @@ static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle, const char *name, uint32 security_info, struct security_descriptor **ppdesc) { - NTSTATUS status = get_nt_acl_xattr_internal(handle, NULL, + return get_nt_acl_xattr_internal(handle, NULL, name, security_info, ppdesc); - if (NT_STATUS_IS_OK(status)) { - if (DEBUGLEVEL >= 10) { - DEBUG(10,("get_nt_acl_xattr: returning xattr sd for file %s\n", - name)); - NDR_PRINT_DEBUG(security_descriptor, *ppdesc); - } - return NT_STATUS_OK; - } - - DEBUG(10,("get_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n", - name, - nt_errstr(status) )); - - return SMB_VFS_NEXT_GET_NT_ACL(handle, name, - security_info, ppdesc); } /********************************************************************* @@ -551,6 +641,8 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, { NTSTATUS status; DATA_BLOB blob; + struct security_descriptor *pdesc_next = NULL; + uint8_t hash[16]; if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n", @@ -559,11 +651,6 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, CONST_DISCARD(struct security_descriptor *,psd)); } - status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - /* Ensure owner and group are set. */ if (!psd->owner_sid || !psd->group_sid) { int ret; @@ -576,13 +663,9 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, } if (fsp->is_directory || fsp->fh->fd == -1) { if (fsp->posix_open) { - ret = vfs_lstat_smb_fname(fsp->conn, - fsp->fsp_name, - &sbuf); + ret = vfs_lstat_smb_fname(fsp->conn,fsp->fsp_name, &sbuf); } else { - ret = vfs_stat_smb_fname(fsp->conn, - fsp->fsp_name, - &sbuf); + ret = vfs_stat_smb_fname(fsp->conn,fsp->fsp_name, &sbuf); } } else { ret = SMB_VFS_FSTAT(fsp, &sbuf); @@ -600,6 +683,26 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, psd = nc_psd; } + status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* Get the full underlying sd, then hash. */ + status = SMB_VFS_NEXT_FGET_NT_ACL(handle, + fsp, + HASH_SECURITY_INFO, + &pdesc_next); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = hash_sd(pdesc_next, hash); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + #if 0 if ((security_info_sent & DACL_SECURITY_INFORMATION) && psd->dacl != NULL && @@ -624,7 +727,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, NDR_PRINT_DEBUG(security_descriptor, CONST_DISCARD(struct security_descriptor *,psd)); } - create_acl_blob(psd, &blob); + create_acl_blob(psd, &blob, hash); store_acl_blob_fsp(handle, fsp, &blob); return NT_STATUS_OK; -- cgit From 2000421c592b672898f85758638be74d8485da1e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Jul 2009 18:23:00 -0700 Subject: Remove reply_unixerror() - no longer needed. Should make Metze's refactoring a lot easier. Jeremy. --- source3/include/proto.h | 2 -- source3/include/smb_macros.h | 1 - source3/smbd/error.c | 30 ------------------ source3/smbd/fileio.c | 1 + source3/smbd/pipes.c | 23 +++++++++++--- source3/smbd/reply.c | 72 ++++++++++++++++++++++++++------------------ source3/smbd/trans2.c | 37 +++++++++++------------ 7 files changed, 79 insertions(+), 87 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index c0f4dc10d8..27b5f45eb0 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6260,8 +6260,6 @@ void reply_dos_error(struct smb_request *req, uint8 eclass, uint32 ecode, void reply_both_error(struct smb_request *req, uint8 eclass, uint32 ecode, NTSTATUS status, int line, const char *file); void reply_openerror(struct smb_request *req, NTSTATUS status); -void reply_unix_error(struct smb_request *req, uint8 defclass, uint32 defcode, - NTSTATUS defstatus, int line, const char *file); /* The following definitions come from smbd/fake_file.c */ diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index 7528883c2d..10ee78b394 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -115,7 +115,6 @@ #define reply_force_nterror(req,status) reply_force_nt_error(req,status,__LINE__,__FILE__) #define reply_doserror(req,eclass,ecode) reply_dos_error(req,eclass,ecode,__LINE__,__FILE__) #define reply_botherror(req,status,eclass,ecode) reply_both_error(req,eclass,ecode,status,__LINE__,__FILE__) -#define reply_unixerror(req,defclass,deferror) reply_unix_error(req,defclass,deferror,NT_STATUS_OK,__LINE__,__FILE__) #if 0 /* defined in IDL */ diff --git a/source3/smbd/error.c b/source3/smbd/error.c index ce22f86414..874efa2a0b 100644 --- a/source3/smbd/error.c +++ b/source3/smbd/error.c @@ -136,33 +136,3 @@ void reply_openerror(struct smb_request *req, NTSTATUS status) reply_nterror(req, status); } } - -void reply_unix_error(struct smb_request *req, uint8 defclass, uint32 defcode, - NTSTATUS defstatus, int line, const char *file) -{ - int eclass=defclass; - int ecode=defcode; - NTSTATUS ntstatus = defstatus; - int i=0; - - TALLOC_FREE(req->outbuf); - reply_outbuf(req, 0, 0); - - if (errno != 0) { - DEBUG(3,("unix_error_packet: error string = %s\n", - strerror(errno))); - - while (unix_dos_nt_errmap[i].dos_class != 0) { - if (unix_dos_nt_errmap[i].unix_error == errno) { - eclass = unix_dos_nt_errmap[i].dos_class; - ecode = unix_dos_nt_errmap[i].dos_code; - ntstatus = unix_dos_nt_errmap[i].nt_error; - break; - } - i++; - } - } - - error_packet_set((char *)req->outbuf, eclass, ecode, ntstatus, - line, file); -} diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 0c13b845df..60cef09b3b 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -57,6 +57,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) /* you can't read from print files */ if (fsp->print_file) { + errno = EBADF; return -1; } diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 7ae7435646..799568d0d5 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -203,8 +203,14 @@ static void pipe_write_done(struct tevent_req *subreq) status = np_write_recv(subreq, &nwritten); TALLOC_FREE(subreq); - if ((nwritten == 0 && state->numtowrite != 0) || (nwritten < 0)) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + if (nwritten < 0) { + reply_nterror(req, status); + goto send; + } + + /* Looks bogus to me now. Needs to be removed ? JRA. */ + if ((nwritten == 0 && state->numtowrite != 0)) { + reply_doserror(req, ERRDOS, ERRnoaccess); goto send; } @@ -283,7 +289,7 @@ void reply_pipe_write_and_X(struct smb_request *req) DEBUG(0,("reply_pipe_write_and_X: start of message " "set and not enough data sent.(%u)\n", (unsigned int)state->numtowrite )); - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -313,8 +319,15 @@ static void pipe_write_andx_done(struct tevent_req *subreq) status = np_write_recv(subreq, &nwritten); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status) || (nwritten != state->numtowrite)) { - reply_unixerror(req, ERRDOS,ERRnoaccess); + + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + goto done; + } + + /* Looks bogus to me now. Is this error message correct ? JRA. */ + if (nwritten != state->numtowrite) { + reply_doserror(req, ERRDOS,ERRnoaccess); goto done; } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 98ee83ea83..e35c5bc6d6 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1106,7 +1106,7 @@ void reply_getatr(struct smb_request *req) DEBUG(3,("reply_getatr: stat of %s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req, ERRDOS,ERRbadfile); + reply_nterror(req, map_nt_error_from_unix(errno)); goto out; } @@ -1220,7 +1220,7 @@ void reply_setatr(struct smb_request *req) ft.mtime = convert_time_t_to_timespec(mtime); status = smb_set_file_time(conn, NULL, smb_fname, &ft, true); if (!NT_STATUS_IS_OK(status)) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, status); goto out; } @@ -1232,7 +1232,7 @@ void reply_setatr(struct smb_request *req) if (file_set_dosmode(conn, smb_fname, mode, NULL, false) != 0) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); goto out; } } @@ -1258,7 +1258,7 @@ void reply_dskattr(struct smb_request *req) START_PROFILE(SMBdskattr); if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_unixerror(req, ERRHRD, ERRgeneral); + reply_nterror(req, map_nt_error_from_unix(errno)); END_PROFILE(SMBdskattr); return; } @@ -2271,7 +2271,7 @@ void reply_ctemp(struct smb_request *req) tmpfd = mkstemp(smb_fname->base_name); if (tmpfd == -1) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); goto out; } @@ -3269,7 +3269,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", nread = read_file(fsp,data,startpos,numtoread); if (nread < 0) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); END_PROFILE(SMBlockread); return; } @@ -3363,7 +3363,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", nread = read_file(fsp,data,startpos,numtoread); if (nread < 0) { - reply_unixerror(req, ERRDOS,ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); goto strict_unlock; } @@ -3425,9 +3425,10 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, SMB_STRUCT_STAT sbuf; ssize_t nread = -1; struct lock_struct lock; + int saved_errno = 0; if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } @@ -3565,11 +3566,12 @@ nosendfile_read: reply_outbuf(req, 12, smb_maxcnt); nread = read_file(fsp, smb_buf(req->outbuf), startpos, smb_maxcnt); + saved_errno = errno; SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); if (nread < 0) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(saved_errno)); return; } @@ -3810,7 +3812,7 @@ void reply_writebraw(struct smb_request *req) (int)nwritten, (int)write_through)); if (nwritten < (ssize_t)numtowrite) { - reply_unixerror(req, ERRHRD, ERRdiskfull); + reply_doserror(req, ERRHRD, ERRdiskfull); error_to_writebrawerr(req); goto strict_unlock; } @@ -3879,7 +3881,7 @@ void reply_writebraw(struct smb_request *req) nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite); if (nwritten == -1) { TALLOC_FREE(buf); - reply_unixerror(req, ERRHRD, ERRdiskfull); + reply_nterror(req, map_nt_error_from_unix(errno)); error_to_writebrawerr(req); goto strict_unlock; } @@ -3958,6 +3960,7 @@ void reply_writeunlock(struct smb_request *req) NTSTATUS status = NT_STATUS_OK; files_struct *fsp; struct lock_struct lock; + int saved_errno = 0; START_PROFILE(SMBwriteunlock); @@ -4003,6 +4006,7 @@ void reply_writeunlock(struct smb_request *req) nwritten = 0; } else { nwritten = write_file(req,fsp,data,startpos,numtowrite); + saved_errno = errno; } status = sync_file(conn, fsp, False /* write through */); @@ -4013,8 +4017,13 @@ void reply_writeunlock(struct smb_request *req) goto strict_unlock; } - if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) { - reply_unixerror(req, ERRHRD, ERRdiskfull); + if(nwritten < 0) { + reply_nterror(req, map_nt_error_from_unix(saved_errno)); + goto strict_unlock; + } + + if((nwritten < numtowrite) && (numtowrite != 0)) { + reply_doserror(req, ERRHRD, ERRdiskfull); goto strict_unlock; } @@ -4065,6 +4074,7 @@ void reply_write(struct smb_request *req) files_struct *fsp; struct lock_struct lock; NTSTATUS status; + int saved_errno = 0; START_PROFILE(SMBwrite); @@ -4141,8 +4151,13 @@ void reply_write(struct smb_request *req) goto strict_unlock; } - if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { - reply_unixerror(req, ERRHRD, ERRdiskfull); + if(nwritten < 0) { + reply_nterror(req, map_nt_error_from_unix(saved_errno)); + goto strict_unlock; + } + + if((nwritten == 0) && (numtowrite != 0)) { + reply_doserror(req, ERRHRD, ERRdiskfull); goto strict_unlock; } @@ -4389,8 +4404,13 @@ void reply_write_and_X(struct smb_request *req) nwritten = write_file(req,fsp,data,startpos,numtowrite); } - if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { - reply_unixerror(req, ERRHRD, ERRdiskfull); + if(nwritten < 0) { + reply_nterror(req, map_nt_error_from_unix(errno)); + goto strict_unlock; + } + + if((nwritten == 0) && (numtowrite != 0)) { + reply_doserror(req, ERRHRD, ERRdiskfull); goto strict_unlock; } @@ -4484,8 +4504,8 @@ void reply_lseek(struct smb_request *req) SMB_STRUCT_STAT sbuf; if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) { - reply_unixerror(req, ERRDOS, - ERRnoaccess); + reply_nterror(req, + map_nt_error_from_unix(errno)); END_PROFILE(SMBlseek); return; } @@ -4497,7 +4517,7 @@ void reply_lseek(struct smb_request *req) } if(res == -1) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); END_PROFILE(SMBlseek); return; } @@ -5197,7 +5217,7 @@ void reply_printwrite(struct smb_request *req) data = (const char *)req->buf + 3; if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) { - reply_unixerror(req, ERRHRD, ERRdiskfull); + reply_nterror(req, map_nt_error_from_unix(errno)); END_PROFILE(SMBsplwr); return; } @@ -6756,7 +6776,6 @@ void reply_copy(struct smb_request *req) const char *p; int count=0; int error = ERRnoaccess; - int err = 0; int tid2; int ofun; int flags; @@ -7059,13 +7078,6 @@ void reply_copy(struct smb_request *req) } if (count == 0) { - if(err) { - /* Error on close... */ - errno = err; - reply_unixerror(req, ERRHRD, ERRgeneral); - goto out; - } - reply_doserror(req, ERRDOS, error); goto out; } @@ -7833,7 +7845,7 @@ void reply_getattrE(struct smb_request *req) /* Do an fstat on this file */ if(fsp_stat(fsp, &sbuf)) { - reply_unixerror(req, ERRDOS, ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); END_PROFILE(SMBgetattrE); return; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 4bf27863bd..6a18f0f710 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2697,7 +2697,7 @@ static void call_trans2qfsinfo(connection_struct *conn, uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 18; if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_unixerror(req, ERRHRD, ERRgeneral); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } @@ -2818,7 +2818,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 24; if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_unixerror(req, ERRHRD, ERRgeneral); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } block_size = lp_block_size(snum); @@ -2851,7 +2851,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 32; if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_unixerror(req, ERRHRD, ERRgeneral); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } block_size = lp_block_size(snum); @@ -3992,7 +3992,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, "(%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req,ERRDOS,ERRbadpath); + reply_nterror(req,map_nt_error_from_unix(errno)); return; } } else if (SMB_VFS_STAT(conn, smb_fname)) { @@ -4000,7 +4000,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, "SMB_VFS_STAT of %s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req, ERRDOS, ERRbadpath); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } @@ -4017,7 +4017,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { DEBUG(3, ("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); - reply_unixerror(req, ERRDOS, ERRbadfid); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } pos = fsp->fh->position_information; @@ -4090,8 +4090,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn, "(%s)\n", smb_fname_str_dbg(smb_fname_base), strerror(errno))); + reply_nterror(req,map_nt_error_from_unix(errno)); TALLOC_FREE(smb_fname_base); - reply_unixerror(req,ERRDOS,ERRbadpath); return; } } else { @@ -4101,8 +4101,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn, "(%s)\n", smb_fname_str_dbg(smb_fname_base), strerror(errno))); + reply_nterror(req,map_nt_error_from_unix(errno)); TALLOC_FREE(smb_fname_base); - reply_unixerror(req,ERRDOS,ERRbadpath); return; } } @@ -4124,7 +4124,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, "SMB_VFS_LSTAT of %s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req, ERRDOS, ERRbadpath); + reply_nterror(req,map_nt_error_from_unix(errno)); return; } @@ -4139,7 +4139,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, "SMB_VFS_STAT of %s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req, ERRDOS, ERRbadpath); + reply_nterror(req,map_nt_error_from_unix(errno)); return; } } @@ -4700,19 +4700,18 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n")); #ifdef S_ISLNK if(!S_ISLNK(sbuf.st_ex_mode)) { - reply_unixerror(req, ERRSRV, + reply_doserror(req, ERRSRV, ERRbadlink); return; } #else - reply_unixerror(req, ERRDOS, ERRbadlink); + reply_doserror(req, ERRDOS, ERRbadlink); return; #endif len = SMB_VFS_READLINK(conn,fullpathname, buffer, PATH_MAX); if (len == -1) { - reply_unixerror(req, ERRDOS, - ERRnoaccess); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } buffer[len] = 0; @@ -6934,7 +6933,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, "(%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req,ERRDOS,ERRbadpath); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } } else { @@ -6943,7 +6942,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, "fileinfo of %s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req,ERRDOS,ERRbadpath); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } } @@ -6962,7 +6961,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, max_data_bytes); return; } else { - reply_unixerror(req, ERRDOS, ERRbadpath); + reply_doserror(req, ERRDOS, ERRbadpath); return; } } else { @@ -6977,7 +6976,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, DEBUG(3,("call_trans2setfilepathinfo: fstat " "of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); - reply_unixerror(req, ERRDOS, ERRbadfid); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } } @@ -7027,7 +7026,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, "%s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); - reply_unixerror(req, ERRDOS, ERRbadpath); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } } -- cgit From 20bc933c5b2f420f3588adf811a66aa886a1b41e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2009 18:51:59 +0200 Subject: s3:smbd: add missing return after reply_nterror() metze --- source3/smbd/trans2.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 6a18f0f710..b7591c4bbb 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4455,6 +4455,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd reply_nterror( req, NT_STATUS_NO_MEMORY); + return; } len = srvstr_push(dstart, req->flags2, pdata+4, mangled_name, -- cgit From 8422e032339f624e6322a4a6a4938b1d84b347a0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2009 19:04:58 +0200 Subject: s3:smbd: split out smbd_do_qfilepathinfo() from call_trans2qfilepathinfo() This prepares SMB2 GetInfo. metze --- source3/smbd/trans2.c | 1751 +++++++++++++++++++++++++------------------------ 1 file changed, 898 insertions(+), 853 deletions(-) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index b7591c4bbb..c9e7e4bbfb 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3878,951 +3878,1014 @@ static void call_trans2qpipeinfo(connection_struct *conn, return; } -/**************************************************************************** - Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by - file name or file id). -****************************************************************************/ - -static void call_trans2qfilepathinfo(connection_struct *conn, - struct smb_request *req, - unsigned int tran_call, - char **pparams, int total_params, - char **ppdata, int total_data, - unsigned int max_data_bytes) +static NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + files_struct *fsp, + const struct smb_filename *smb_fname, + bool delete_pending, + struct timespec write_time_ts, + bool ms_dfs_link, + struct ea_list *ea_list, + int lock_data_count, + char *lock_data, + uint16_t flags2, + unsigned int max_data_bytes, + char **ppdata, + unsigned int *pdata_size) { - char *params = *pparams; char *pdata = *ppdata; char *dstart, *dend; - uint16 info_level; - int mode=0; - int nlink; - SMB_OFF_T file_size=0; - uint64_t allocation_size=0; - unsigned int data_size = 0; - unsigned int param_size = 2; + unsigned int data_size; + struct timespec create_time_ts, mtime_ts, atime_ts; + time_t create_time, mtime, atime; SMB_STRUCT_STAT sbuf; - char *dos_fname = NULL; - char *fname = NULL; - struct smb_filename *smb_fname = NULL; - char *fullpathname; - char *base_name; char *p; - SMB_OFF_T pos = 0; - bool delete_pending = False; - int len; - time_t create_time, mtime, atime; - struct timespec create_time_ts, mtime_ts, atime_ts; - struct timespec write_time_ts; - files_struct *fsp = NULL; - struct file_id fileid; - struct ea_list *ea_list = NULL; - char *lock_data = NULL; - bool ms_dfs_link = false; - TALLOC_CTX *ctx = talloc_tos(); - NTSTATUS status = NT_STATUS_OK; + char *fname; + char *base_name; + char *dos_fname; + int mode; + int nlink; + NTSTATUS status; + uint64_t file_size = 0; + uint64_t pos = 0; + uint64_t allocation_size = 0; - if (!params) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + sbuf = smb_fname->st; + + if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { + return NT_STATUS_INVALID_LEVEL; } - ZERO_STRUCT(write_time_ts); + status = get_full_smb_filename(mem_ctx, smb_fname, &fname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - if (tran_call == TRANSACT2_QFILEINFO) { - if (total_params < 4) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; - } + DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n", + fname, fsp ? fsp->fnum : -1, info_level, max_data_bytes)); - if (IS_IPC(conn)) { - call_trans2qpipeinfo(conn, req, tran_call, - pparams, total_params, - ppdata, total_data, - max_data_bytes); - return; - } + if (ms_dfs_link) { + mode = dos_mode_msdfs(conn, smb_fname); + } else { + mode = dos_mode(conn, smb_fname); + } + if (!mode) + mode = FILE_ATTRIBUTE_NORMAL; - fsp = file_fsp(req, SVAL(params,0)); - info_level = SVAL(params,2); + nlink = sbuf.st_ex_nlink; - DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level)); + if (nlink && (mode&aDIR)) { + nlink = 1; + } - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; - } + if ((nlink > 0) && delete_pending) { + nlink -= 1; + } - /* Initial check for valid fsp ptr. */ - if (!check_fsp_open(conn, req, fsp)) { - return; - } + data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN; + *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); + if (*ppdata == NULL) { + return NT_STATUS_NO_MEMORY; + } + pdata = *ppdata; + dstart = pdata; + dend = dstart + data_size - 1; - fname = talloc_strdup(talloc_tos(),fsp->fsp_name); - if (!fname) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) { + update_stat_ex_mtime(&sbuf, write_time_ts); + } + + create_time_ts = sbuf.st_ex_btime; + mtime_ts = sbuf.st_ex_mtime; + atime_ts = sbuf.st_ex_atime; + + if (lp_dos_filetime_resolution(SNUM(conn))) { + dos_filetime_timespec(&create_time_ts); + dos_filetime_timespec(&mtime_ts); + dos_filetime_timespec(&atime_ts); + } + + create_time = convert_timespec_to_time_t(create_time_ts); + mtime = convert_timespec_to_time_t(mtime_ts); + atime = convert_timespec_to_time_t(atime_ts); + + p = strrchr_m(smb_fname->base_name,'/'); + if (!p) + base_name = smb_fname->base_name; + else + base_name = p+1; + + /* NT expects the name to be in an exact form of the *full* + filename. See the trans2 torture test */ + if (ISDOT(base_name)) { + dos_fname = talloc_strdup(mem_ctx, "\\"); + if (!dos_fname) { + return NT_STATUS_NO_MEMORY; + } + } else { + dos_fname = talloc_asprintf(mem_ctx, + "\\%s", + fname); + if (!dos_fname) { + return NT_STATUS_NO_MEMORY; } + string_replace(dos_fname, '/', '\\'); + } - status = create_synthetic_smb_fname_split(talloc_tos(), fname, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - return; + allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &sbuf); + + if (!fsp) { + /* Do we have this path open ? */ + files_struct *fsp1; + struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf); + fsp1 = file_find_di_first(fileid); + if (fsp1 && fsp1->initial_allocation_size) { + allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, &sbuf); } + } - if(fsp->fake_file_handle) { - /* - * This is actually for the QUOTA_FAKE_FILE --metze - */ + if (!(mode & aDIR)) { + file_size = get_file_size_stat(&sbuf); + } - /* We know this name is ok, it's already passed the checks. */ + if (fsp && fsp->fh) { + pos = fsp->fh->position_information; + } - } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) { - /* - * This is actually a QFILEINFO on a directory - * handle (returned from an NT SMB). NT5.0 seems - * to do this call. JRA. - */ + switch (info_level) { + case SMB_INFO_STANDARD: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n")); + data_size = 22; + srv_put_dos_date2(pdata,l1_fdateCreation,create_time); + srv_put_dos_date2(pdata,l1_fdateLastAccess,atime); + srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */ + SIVAL(pdata,l1_cbFile,(uint32)file_size); + SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size); + SSVAL(pdata,l1_attrFile,mode); + break; - if (INFO_LEVEL_IS_UNIX(info_level)) { - /* Always do lstat for UNIX calls. */ - if (SMB_VFS_LSTAT(conn, smb_fname)) { - DEBUG(3,("call_trans2qfilepathinfo: " - "SMB_VFS_LSTAT of %s failed " - "(%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req,map_nt_error_from_unix(errno)); - return; - } - } else if (SMB_VFS_STAT(conn, smb_fname)) { - DEBUG(3,("call_trans2qfilepathinfo: " - "SMB_VFS_STAT of %s failed (%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req, map_nt_error_from_unix(errno)); - return; - } + case SMB_INFO_QUERY_EA_SIZE: + { + unsigned int ea_size = estimate_ea_size(conn, fsp, fname); + DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n")); + data_size = 26; + srv_put_dos_date2(pdata,0,create_time); + srv_put_dos_date2(pdata,4,atime); + srv_put_dos_date2(pdata,8,mtime); /* write time */ + SIVAL(pdata,12,(uint32)file_size); + SIVAL(pdata,16,(uint32)allocation_size); + SSVAL(pdata,20,mode); + SIVAL(pdata,22,ea_size); + break; + } - fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); - get_file_infos(fileid, &delete_pending, &write_time_ts); - } else { - /* - * Original code - this is an open file. - */ - if (!check_fsp(conn, req, fsp)) { - return; + case SMB_INFO_IS_NAME_VALID: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n")); + if (fsp) { + /* os/2 needs this ? really ?*/ + return NT_STATUS_DOS(ERRDOS, ERRbadfunc); } + /* This is only reached for qpathinfo */ + data_size = 0; + break; - if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { - DEBUG(3, ("fstat of fnum %d failed (%s)\n", - fsp->fnum, strerror(errno))); - reply_nterror(req, map_nt_error_from_unix(errno)); - return; + case SMB_INFO_QUERY_EAS_FROM_LIST: + { + size_t total_ea_len = 0; + struct ea_list *ea_file_list = NULL; + + DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n")); + + ea_file_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); + ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len); + + if (!ea_list || (total_ea_len > data_size)) { + data_size = 4; + SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */ + break; } - pos = fsp->fh->position_information; - fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); - get_file_infos(fileid, &delete_pending, &write_time_ts); - } - } else { - /* qpathinfo */ - if (total_params < 7) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list); + break; } - info_level = SVAL(params,0); + case SMB_INFO_QUERY_ALL_EAS: + { + /* We have data_size bytes to put EA's into. */ + size_t total_ea_len = 0; - DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level)); + DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n")); - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); + if (!ea_list || (total_ea_len > data_size)) { + data_size = 4; + SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */ + break; + } + + data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list); + break; } - srvstr_get_path(ctx, params, req->flags2, &fname, ¶ms[6], - total_params - 6, - STR_TERMINATE, &status); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - return; - } + case SMB_FILE_BASIC_INFORMATION: + case SMB_QUERY_FILE_BASIC_INFO: - status = filename_convert(ctx, - conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - fname, - &smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { - reply_botherror(req, - NT_STATUS_PATH_NOT_COVERED, - ERRSRV, ERRbadpath); - return; + if (info_level == SMB_QUERY_FILE_BASIC_INFO) { + DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n")); + data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */ + } else { + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n")); + data_size = 40; + SIVAL(pdata,36,0); } - reply_nterror(req, status); - return; - } + put_long_date_timespec(pdata,create_time_ts); + put_long_date_timespec(pdata+8,atime_ts); + put_long_date_timespec(pdata+16,mtime_ts); /* write time */ + put_long_date_timespec(pdata+24,mtime_ts); /* change time */ + SIVAL(pdata,32,mode); - /* If this is a stream, check if there is a delete_pending. */ - if ((conn->fs_capabilities & FILE_NAMED_STREAMS) - && is_ntfs_stream_smb_fname(smb_fname)) { - struct smb_filename *smb_fname_base = NULL; + DEBUG(5,("SMB_QFBI - ")); + DEBUG(5,("create: %s ", ctime(&create_time))); + DEBUG(5,("access: %s ", ctime(&atime))); + DEBUG(5,("write: %s ", ctime(&mtime))); + DEBUG(5,("change: %s ", ctime(&mtime))); + DEBUG(5,("mode: %x\n", mode)); + break; - /* Create an smb_filename with stream_name == NULL. */ - status = - create_synthetic_smb_fname(talloc_tos(), - smb_fname->base_name, - NULL, NULL, - &smb_fname_base); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - return; - } + case SMB_FILE_STANDARD_INFORMATION: + case SMB_QUERY_FILE_STANDARD_INFO: - if (INFO_LEVEL_IS_UNIX(info_level)) { - /* Always do lstat for UNIX calls. */ - if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) { - DEBUG(3,("call_trans2qfilepathinfo: " - "SMB_VFS_LSTAT of %s failed " - "(%s)\n", - smb_fname_str_dbg(smb_fname_base), - strerror(errno))); - reply_nterror(req,map_nt_error_from_unix(errno)); - TALLOC_FREE(smb_fname_base); - return; - } - } else { - if (SMB_VFS_STAT(conn, smb_fname_base) != 0) { - DEBUG(3,("call_trans2qfilepathinfo: " - "fileinfo of %s failed " - "(%s)\n", - smb_fname_str_dbg(smb_fname_base), - strerror(errno))); - reply_nterror(req,map_nt_error_from_unix(errno)); - TALLOC_FREE(smb_fname_base); - return; - } - } + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n")); + data_size = 24; + SOFF_T(pdata,0,allocation_size); + SOFF_T(pdata,8,file_size); + SIVAL(pdata,16,nlink); + SCVAL(pdata,20,delete_pending?1:0); + SCVAL(pdata,21,(mode&aDIR)?1:0); + SSVAL(pdata,22,0); /* Padding. */ + break; - fileid = vfs_file_id_from_sbuf(conn, - &smb_fname_base->st); - TALLOC_FREE(smb_fname_base); - get_file_infos(fileid, &delete_pending, NULL); - if (delete_pending) { - reply_nterror(req, NT_STATUS_DELETE_PENDING); - return; - } + case SMB_FILE_EA_INFORMATION: + case SMB_QUERY_FILE_EA_INFO: + { + unsigned int ea_size = estimate_ea_size(conn, fsp, fname); + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n")); + data_size = 4; + SIVAL(pdata,0,ea_size); + break; } - if (INFO_LEVEL_IS_UNIX(info_level)) { - /* Always do lstat for UNIX calls. */ - if (SMB_VFS_LSTAT(conn, smb_fname)) { - DEBUG(3,("call_trans2qfilepathinfo: " - "SMB_VFS_LSTAT of %s failed (%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req,map_nt_error_from_unix(errno)); - return; + /* Get the 8.3 name - used if NT SMB was negotiated. */ + case SMB_QUERY_FILE_ALT_NAME_INFO: + case SMB_FILE_ALTERNATE_NAME_INFORMATION: + { + int len; + char mangled_name[13]; + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n")); + if (!name_to_8_3(base_name,mangled_name, + True,conn->params)) { + return NT_STATUS_NO_MEMORY; } + len = srvstr_push(dstart, flags2, + pdata+4, mangled_name, + PTR_DIFF(dend, pdata+4), + STR_UNICODE); + data_size = 4 + len; + SIVAL(pdata,0,len); + break; + } - } else if (!VALID_STAT(smb_fname->st) && - SMB_VFS_STAT(conn, smb_fname) && - (info_level != SMB_INFO_IS_NAME_VALID)) { - ms_dfs_link = check_msdfs_link(conn, fname, - &smb_fname->st); - - if (!ms_dfs_link) { - DEBUG(3,("call_trans2qfilepathinfo: " - "SMB_VFS_STAT of %s failed (%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req,map_nt_error_from_unix(errno)); - return; - } + case SMB_QUERY_FILE_NAME_INFO: + { + int len; + /* + this must be *exactly* right for ACLs on mapped drives to work + */ + len = srvstr_push(dstart, flags2, + pdata+4, dos_fname, + PTR_DIFF(dend, pdata+4), + STR_UNICODE); + DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n")); + data_size = 4 + len; + SIVAL(pdata,0,len); + break; } - fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); - get_file_infos(fileid, &delete_pending, &write_time_ts); - if (delete_pending) { - reply_nterror(req, NT_STATUS_DELETE_PENDING); - return; + case SMB_FILE_ALLOCATION_INFORMATION: + case SMB_QUERY_FILE_ALLOCATION_INFO: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n")); + data_size = 8; + SOFF_T(pdata,0,allocation_size); + break; + + case SMB_FILE_END_OF_FILE_INFORMATION: + case SMB_QUERY_FILE_END_OF_FILEINFO: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n")); + data_size = 8; + SOFF_T(pdata,0,file_size); + break; + + case SMB_QUERY_FILE_ALL_INFO: + case SMB_FILE_ALL_INFORMATION: + { + int len; + unsigned int ea_size = estimate_ea_size(conn, fsp, fname); + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n")); + put_long_date_timespec(pdata,create_time_ts); + put_long_date_timespec(pdata+8,atime_ts); + put_long_date_timespec(pdata+16,mtime_ts); /* write time */ + put_long_date_timespec(pdata+24,mtime_ts); /* change time */ + SIVAL(pdata,32,mode); + SIVAL(pdata,36,0); /* padding. */ + pdata += 40; + SOFF_T(pdata,0,allocation_size); + SOFF_T(pdata,8,file_size); + SIVAL(pdata,16,nlink); + SCVAL(pdata,20,delete_pending); + SCVAL(pdata,21,(mode&aDIR)?1:0); + SSVAL(pdata,22,0); + pdata += 24; + SIVAL(pdata,0,ea_size); + pdata += 4; /* EA info */ + len = srvstr_push(dstart, flags2, + pdata+4, dos_fname, + PTR_DIFF(dend, pdata+4), + STR_UNICODE); + SIVAL(pdata,0,len); + pdata += 4 + len; + data_size = PTR_DIFF(pdata,(*ppdata)); + break; } - } + case SMB_FILE_INTERNAL_INFORMATION: + /* This should be an index number - looks like + dev/ino to me :-) - /* Set sbuf for use below. */ - sbuf = smb_fname->st; + I think this causes us to fail the IFSKIT + BasicFileInformationTest. -tpot */ - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; - } + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n")); + SIVAL(pdata,0,sbuf.st_ex_ino); /* FileIndexLow */ + SIVAL(pdata,4,sbuf.st_ex_dev); /* FileIndexHigh */ + data_size = 8; + break; - DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n", - fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data)); + case SMB_FILE_ACCESS_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n")); + if (fsp) { + SIVAL(pdata,0,fsp->access_mask); + } else { + /* GENERIC_EXECUTE mapping from Windows */ + SIVAL(pdata,0,0x12019F); + } + data_size = 4; + break; - p = strrchr_m(smb_fname->base_name,'/'); - if (!p) - base_name = smb_fname->base_name; - else - base_name = p+1; + case SMB_FILE_NAME_INFORMATION: + /* Pathname with leading '\'. */ + { + size_t byte_len; + byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False); + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n")); + SIVAL(pdata,0,byte_len); + data_size = 4 + byte_len; + break; + } - if (ms_dfs_link) { - mode = dos_mode_msdfs(conn, smb_fname); - } else { - mode = dos_mode(conn, smb_fname); - } - if (!mode) - mode = FILE_ATTRIBUTE_NORMAL; + case SMB_FILE_DISPOSITION_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n")); + data_size = 1; + SCVAL(pdata,0,delete_pending); + break; - nlink = sbuf.st_ex_nlink; + case SMB_FILE_POSITION_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n")); + data_size = 8; + SOFF_T(pdata,0,pos); + break; - if (nlink && (mode&aDIR)) { - nlink = 1; - } + case SMB_FILE_MODE_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n")); + SIVAL(pdata,0,mode); + data_size = 4; + break; - if ((nlink > 0) && delete_pending) { - nlink -= 1; - } + case SMB_FILE_ALIGNMENT_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n")); + SIVAL(pdata,0,0); /* No alignment needed. */ + data_size = 4; + break; + + /* + * NT4 server just returns "invalid query" to this - if we try + * to answer it then NTws gets a BSOD! (tridge). W2K seems to + * want this. JRA. + */ + /* The first statement above is false - verified using Thursby + * client against NT4 -- gcolley. + */ + case SMB_QUERY_FILE_STREAM_INFO: + case SMB_FILE_STREAM_INFORMATION: { + unsigned int num_streams; + struct stream_struct *streams; - fullpathname = fname; - if (!(mode & aDIR)) - file_size = get_file_size_stat(&sbuf); + DEBUG(10,("smbd_do_qfilepathinfo: " + "SMB_FILE_STREAM_INFORMATION\n")); - /* Pull out any data sent here before we realloc. */ - switch (info_level) { - case SMB_INFO_QUERY_EAS_FROM_LIST: - { - /* Pull any EA list from the data portion. */ - uint32 ea_size; + status = SMB_VFS_STREAMINFO( + conn, fsp, fname, talloc_tos(), + &num_streams, &streams); - if (total_data < 4) { - reply_nterror( - req, NT_STATUS_INVALID_PARAMETER); - return; + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("could not get stream info: %s\n", + nt_errstr(status))); + return status; } - ea_size = IVAL(pdata,0); - if (total_data > 0 && ea_size != total_data) { - DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \ -total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) )); - reply_nterror( - req, NT_STATUS_INVALID_PARAMETER); - return; - } + status = marshall_stream_info(num_streams, streams, + pdata, max_data_bytes, + &data_size); - if (!lp_ea_support(SNUM(conn))) { - reply_doserror(req, ERRDOS, - ERReasnotsupported); - return; + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("marshall_stream_info failed: %s\n", + nt_errstr(status))); + return status; } - /* Pull out the list of names. */ - ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4); - if (!ea_list) { - reply_nterror( - req, NT_STATUS_INVALID_PARAMETER); - return; - } + TALLOC_FREE(streams); + break; } + case SMB_QUERY_COMPRESSION_INFO: + case SMB_FILE_COMPRESSION_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n")); + SOFF_T(pdata,0,file_size); + SIVAL(pdata,8,0); /* ??? */ + SIVAL(pdata,12,0); /* ??? */ + data_size = 16; + break; - case SMB_QUERY_POSIX_LOCK: - { - if (fsp == NULL || fsp->fh->fd == -1) { - reply_nterror(req, NT_STATUS_INVALID_HANDLE); - return; - } - - if (total_data != POSIX_LOCK_DATA_SIZE) { - reply_nterror( - req, NT_STATUS_INVALID_PARAMETER); - return; - } + case SMB_FILE_NETWORK_OPEN_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n")); + put_long_date_timespec(pdata,create_time_ts); + put_long_date_timespec(pdata+8,atime_ts); + put_long_date_timespec(pdata+16,mtime_ts); /* write time */ + put_long_date_timespec(pdata+24,mtime_ts); /* change time */ + SOFF_T(pdata,32,allocation_size); + SOFF_T(pdata,40,file_size); + SIVAL(pdata,48,mode); + SIVAL(pdata,52,0); /* ??? */ + data_size = 56; + break; - /* Copy the lock range data. */ - lock_data = (char *)TALLOC_MEMDUP( - ctx, pdata, total_data); - if (!lock_data) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - } - default: + case SMB_FILE_ATTRIBUTE_TAG_INFORMATION: + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n")); + SIVAL(pdata,0,mode); + SIVAL(pdata,4,0); + data_size = 8; break; - } - *pparams = (char *)SMB_REALLOC(*pparams,2); - if (*pparams == NULL) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - params = *pparams; - SSVAL(params,0,0); - data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN; - *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); - if (*ppdata == NULL ) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - pdata = *ppdata; - dstart = pdata; - dend = dstart + data_size - 1; + /* + * CIFS UNIX Extensions. + */ - allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf); + case SMB_QUERY_FILE_UNIX_BASIC: - if (!fsp) { - /* Do we have this path open ? */ - files_struct *fsp1; - fileid = vfs_file_id_from_sbuf(conn, &sbuf); - fsp1 = file_find_di_first(fileid); - if (fsp1 && fsp1->initial_allocation_size) { - allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, &sbuf); - } - } + pdata = store_file_unix_basic(conn, pdata, fsp, &sbuf); + data_size = PTR_DIFF(pdata,(*ppdata)); - if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) { - update_stat_ex_mtime(&sbuf, write_time_ts); - } + { + int i; + DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC ")); - create_time_ts = sbuf.st_ex_btime; - mtime_ts = sbuf.st_ex_mtime; - atime_ts = sbuf.st_ex_atime; + for (i=0; i<100; i++) + DEBUG(4,("%d=%x, ",i, (*ppdata)[i])); + DEBUG(4,("\n")); + } - if (lp_dos_filetime_resolution(SNUM(conn))) { - dos_filetime_timespec(&create_time_ts); - dos_filetime_timespec(&mtime_ts); - dos_filetime_timespec(&atime_ts); - } + break; - create_time = convert_timespec_to_time_t(create_time_ts); - mtime = convert_timespec_to_time_t(mtime_ts); - atime = convert_timespec_to_time_t(atime_ts); + case SMB_QUERY_FILE_UNIX_INFO2: - /* NT expects the name to be in an exact form of the *full* - filename. See the trans2 torture test */ - if (ISDOT(base_name)) { - dos_fname = talloc_strdup(ctx, "\\"); - if (!dos_fname) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - } else { - dos_fname = talloc_asprintf(ctx, - "\\%s", - fname); - if (!dos_fname) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - string_replace(dos_fname, '/', '\\'); - } + pdata = store_file_unix_basic_info2(conn, pdata, fsp, &sbuf); + data_size = PTR_DIFF(pdata,(*ppdata)); - switch (info_level) { - case SMB_INFO_STANDARD: - DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n")); - data_size = 22; - srv_put_dos_date2(pdata,l1_fdateCreation,create_time); - srv_put_dos_date2(pdata,l1_fdateLastAccess,atime); - srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */ - SIVAL(pdata,l1_cbFile,(uint32)file_size); - SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size); - SSVAL(pdata,l1_attrFile,mode); - break; + { + int i; + DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 ")); + + for (i=0; i<100; i++) + DEBUG(4,("%d=%x, ",i, (*ppdata)[i])); + DEBUG(4,("\n")); + } - case SMB_INFO_QUERY_EA_SIZE: - { - unsigned int ea_size = estimate_ea_size(conn, fsp, fname); - DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n")); - data_size = 26; - srv_put_dos_date2(pdata,0,create_time); - srv_put_dos_date2(pdata,4,atime); - srv_put_dos_date2(pdata,8,mtime); /* write time */ - SIVAL(pdata,12,(uint32)file_size); - SIVAL(pdata,16,(uint32)allocation_size); - SSVAL(pdata,20,mode); - SIVAL(pdata,22,ea_size); break; - } - case SMB_INFO_IS_NAME_VALID: - DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n")); - if (tran_call == TRANSACT2_QFILEINFO) { - /* os/2 needs this ? really ?*/ - reply_doserror(req, ERRDOS, ERRbadfunc); - return; + case SMB_QUERY_FILE_UNIX_LINK: + { + int len; + char *buffer = TALLOC_ARRAY(mem_ctx, char, PATH_MAX+1); + + if (!buffer) { + return NT_STATUS_NO_MEMORY; + } + + DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n")); +#ifdef S_ISLNK + if(!S_ISLNK(sbuf.st_ex_mode)) { + return NT_STATUS_DOS(ERRSRV, ERRbadlink); + } +#else + return NT_STATUS_DOS(ERRDOS, ERRbadlink); +#endif + len = SMB_VFS_READLINK(conn,fname, + buffer, PATH_MAX); + if (len == -1) { + return map_nt_error_from_unix(errno); + } + buffer[len] = 0; + len = srvstr_push(dstart, flags2, + pdata, buffer, + PTR_DIFF(dend, pdata), + STR_TERMINATE); + pdata += len; + data_size = PTR_DIFF(pdata,(*ppdata)); + + break; } - data_size = 0; - param_size = 0; - break; - case SMB_INFO_QUERY_EAS_FROM_LIST: - { - size_t total_ea_len = 0; - struct ea_list *ea_file_list = NULL; +#if defined(HAVE_POSIX_ACLS) + case SMB_QUERY_POSIX_ACL: + { + SMB_ACL_T file_acl = NULL; + SMB_ACL_T def_acl = NULL; + uint16 num_file_acls = 0; + uint16 num_def_acls = 0; + + if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) { + file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp); + } else { + file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS); + } + + if (file_acl == NULL && no_acl_syscall_error(errno)) { + DEBUG(5,("smbd_do_qfilepathinfo: ACLs not implemented on filesystem containing %s\n", + fname )); + return NT_STATUS_NOT_IMPLEMENTED; + } + + if (S_ISDIR(sbuf.st_ex_mode)) { + if (fsp && fsp->is_directory) { + def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT); + } else { + def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT); + } + def_acl = free_empty_sys_acl(conn, def_acl); + } + + num_file_acls = count_acl_entries(conn, file_acl); + num_def_acls = count_acl_entries(conn, def_acl); - DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n")); + if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) { + DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n", + data_size, + (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + + SMB_POSIX_ACL_HEADER_SIZE) )); + if (file_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); + } + if (def_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); + } + return NT_STATUS_BUFFER_TOO_SMALL; + } - ea_file_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len); - ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len); + SSVAL(pdata,0,SMB_POSIX_ACL_VERSION); + SSVAL(pdata,2,num_file_acls); + SSVAL(pdata,4,num_def_acls); + if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) { + if (file_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); + } + if (def_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); + } + return NT_STATUS_INTERNAL_ERROR; + } + if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) { + if (file_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); + } + if (def_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); + } + return NT_STATUS_INTERNAL_ERROR; + } - if (!ea_list || (total_ea_len > data_size)) { - data_size = 4; - SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */ + if (file_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); + } + if (def_acl) { + SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); + } + data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE; break; } +#endif - data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list); - break; - } - case SMB_INFO_QUERY_ALL_EAS: + case SMB_QUERY_POSIX_LOCK: { - /* We have data_size bytes to put EA's into. */ - size_t total_ea_len = 0; - - DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n")); + uint64_t count; + uint64_t offset; + uint32 lock_pid; + enum brl_type lock_type; - ea_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len); - if (!ea_list || (total_ea_len > data_size)) { - data_size = 4; - SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */ - break; + if (lock_data_count != POSIX_LOCK_DATA_SIZE) { + return NT_STATUS_INVALID_PARAMETER; } - data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list); - break; - } - - case SMB_FILE_BASIC_INFORMATION: - case SMB_QUERY_FILE_BASIC_INFO: - - if (info_level == SMB_QUERY_FILE_BASIC_INFO) { - DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n")); - data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */ - } else { - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n")); - data_size = 40; - SIVAL(pdata,36,0); + switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) { + case POSIX_LOCK_TYPE_READ: + lock_type = READ_LOCK; + break; + case POSIX_LOCK_TYPE_WRITE: + lock_type = WRITE_LOCK; + break; + case POSIX_LOCK_TYPE_UNLOCK: + default: + /* There's no point in asking for an unlock... */ + return NT_STATUS_INVALID_PARAMETER; } - put_long_date_timespec(pdata,create_time_ts); - put_long_date_timespec(pdata+8,atime_ts); - put_long_date_timespec(pdata+16,mtime_ts); /* write time */ - put_long_date_timespec(pdata+24,mtime_ts); /* change time */ - SIVAL(pdata,32,mode); - DEBUG(5,("SMB_QFBI - ")); - DEBUG(5,("create: %s ", ctime(&create_time))); - DEBUG(5,("access: %s ", ctime(&atime))); - DEBUG(5,("write: %s ", ctime(&mtime))); - DEBUG(5,("change: %s ", ctime(&mtime))); - DEBUG(5,("mode: %x\n", mode)); - break; + lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET); +#if defined(HAVE_LONGLONG) + offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) | + ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET)); + count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) | + ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET)); +#else /* HAVE_LONGLONG */ + offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET); + count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET); +#endif /* HAVE_LONGLONG */ - case SMB_FILE_STANDARD_INFORMATION: - case SMB_QUERY_FILE_STANDARD_INFO: + status = query_lock(fsp, + &lock_pid, + &count, + &offset, + &lock_type, + POSIX_LOCK); - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n")); - data_size = 24; - SOFF_T(pdata,0,allocation_size); - SOFF_T(pdata,8,file_size); - SIVAL(pdata,16,nlink); - SCVAL(pdata,20,delete_pending?1:0); - SCVAL(pdata,21,(mode&aDIR)?1:0); - SSVAL(pdata,22,0); /* Padding. */ - break; + if (ERROR_WAS_LOCK_DENIED(status)) { + /* Here we need to report who has it locked... */ + data_size = POSIX_LOCK_DATA_SIZE; - case SMB_FILE_EA_INFORMATION: - case SMB_QUERY_FILE_EA_INFO: - { - unsigned int ea_size = estimate_ea_size(conn, fsp, fname); - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n")); - data_size = 4; - SIVAL(pdata,0,ea_size); - break; - } + SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type); + SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0); + SIVAL(pdata, POSIX_LOCK_PID_OFFSET, lock_pid); +#if defined(HAVE_LONGLONG) + SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF)); + SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF)); + SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF)); + SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF)); +#else /* HAVE_LONGLONG */ + SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset); + SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count); +#endif /* HAVE_LONGLONG */ - /* Get the 8.3 name - used if NT SMB was negotiated. */ - case SMB_QUERY_FILE_ALT_NAME_INFO: - case SMB_FILE_ALTERNATE_NAME_INFORMATION: - { - char mangled_name[13]; - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n")); - if (!name_to_8_3(base_name,mangled_name, - True,conn->params)) { - reply_nterror( - req, - NT_STATUS_NO_MEMORY); - return; + } else if (NT_STATUS_IS_OK(status)) { + /* For success we just return a copy of what we sent + with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */ + data_size = POSIX_LOCK_DATA_SIZE; + memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE); + SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK); + } else { + return status; } - len = srvstr_push(dstart, req->flags2, - pdata+4, mangled_name, - PTR_DIFF(dend, pdata+4), - STR_UNICODE); - data_size = 4 + len; - SIVAL(pdata,0,len); break; } - case SMB_QUERY_FILE_NAME_INFO: - /* - this must be *exactly* right for ACLs on mapped drives to work - */ - len = srvstr_push(dstart, req->flags2, - pdata+4, dos_fname, - PTR_DIFF(dend, pdata+4), - STR_UNICODE); - DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n")); - data_size = 4 + len; - SIVAL(pdata,0,len); - break; + default: + return NT_STATUS_INVALID_LEVEL; + } - case SMB_FILE_ALLOCATION_INFORMATION: - case SMB_QUERY_FILE_ALLOCATION_INFO: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n")); - data_size = 8; - SOFF_T(pdata,0,allocation_size); - break; + *pdata_size = data_size; + return NT_STATUS_OK; +} - case SMB_FILE_END_OF_FILE_INFORMATION: - case SMB_QUERY_FILE_END_OF_FILEINFO: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n")); - data_size = 8; - SOFF_T(pdata,0,file_size); - break; +/**************************************************************************** + Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by + file name or file id). +****************************************************************************/ - case SMB_QUERY_FILE_ALL_INFO: - case SMB_FILE_ALL_INFORMATION: - { - unsigned int ea_size = estimate_ea_size(conn, fsp, fname); - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n")); - put_long_date_timespec(pdata,create_time_ts); - put_long_date_timespec(pdata+8,atime_ts); - put_long_date_timespec(pdata+16,mtime_ts); /* write time */ - put_long_date_timespec(pdata+24,mtime_ts); /* change time */ - SIVAL(pdata,32,mode); - SIVAL(pdata,36,0); /* padding. */ - pdata += 40; - SOFF_T(pdata,0,allocation_size); - SOFF_T(pdata,8,file_size); - SIVAL(pdata,16,nlink); - SCVAL(pdata,20,delete_pending); - SCVAL(pdata,21,(mode&aDIR)?1:0); - SSVAL(pdata,22,0); - pdata += 24; - SIVAL(pdata,0,ea_size); - pdata += 4; /* EA info */ - len = srvstr_push(dstart, req->flags2, - pdata+4, dos_fname, - PTR_DIFF(dend, pdata+4), - STR_UNICODE); - SIVAL(pdata,0,len); - pdata += 4 + len; - data_size = PTR_DIFF(pdata,(*ppdata)); - break; - } - case SMB_FILE_INTERNAL_INFORMATION: - /* This should be an index number - looks like - dev/ino to me :-) +static void call_trans2qfilepathinfo(connection_struct *conn, + struct smb_request *req, + unsigned int tran_call, + char **pparams, int total_params, + char **ppdata, int total_data, + unsigned int max_data_bytes) +{ + char *params = *pparams; + char *pdata = *ppdata; + uint16 info_level; + unsigned int data_size = 0; + unsigned int param_size = 2; + char *fname = NULL; + struct smb_filename *smb_fname = NULL; + bool delete_pending = False; + struct timespec write_time_ts; + files_struct *fsp = NULL; + struct file_id fileid; + struct ea_list *ea_list = NULL; + int lock_data_count = 0; + char *lock_data = NULL; + bool ms_dfs_link = false; + NTSTATUS status = NT_STATUS_OK; - I think this causes us to fail the IFSKIT - BasicFileInformationTest. -tpot */ + if (!params) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n")); - SIVAL(pdata,0,sbuf.st_ex_ino); /* FileIndexLow */ - SIVAL(pdata,4,sbuf.st_ex_dev); /* FileIndexHigh */ - data_size = 8; - break; + ZERO_STRUCT(write_time_ts); + + if (tran_call == TRANSACT2_QFILEINFO) { + if (total_params < 4) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } - case SMB_FILE_ACCESS_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n")); - if (fsp) { - SIVAL(pdata,0,fsp->access_mask); - } else { - /* GENERIC_EXECUTE mapping from Windows */ - SIVAL(pdata,0,0x12019F); - } - data_size = 4; - break; + if (IS_IPC(conn)) { + call_trans2qpipeinfo(conn, req, tran_call, + pparams, total_params, + ppdata, total_data, + max_data_bytes); + return; + } - case SMB_FILE_NAME_INFORMATION: - /* Pathname with leading '\'. */ - { - size_t byte_len; - byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False); - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n")); - SIVAL(pdata,0,byte_len); - data_size = 4 + byte_len; - break; - } + fsp = file_fsp(req, SVAL(params,0)); + info_level = SVAL(params,2); - case SMB_FILE_DISPOSITION_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n")); - data_size = 1; - SCVAL(pdata,0,delete_pending); - break; + DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level)); - case SMB_FILE_POSITION_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n")); - data_size = 8; - SOFF_T(pdata,0,pos); - break; + if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { + reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return; + } - case SMB_FILE_MODE_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n")); - SIVAL(pdata,0,mode); - data_size = 4; - break; + /* Initial check for valid fsp ptr. */ + if (!check_fsp_open(conn, req, fsp)) { + return; + } - case SMB_FILE_ALIGNMENT_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n")); - SIVAL(pdata,0,0); /* No alignment needed. */ - data_size = 4; - break; + fname = talloc_strdup(talloc_tos(),fsp->fsp_name); + if (!fname) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + return; + } - /* - * NT4 server just returns "invalid query" to this - if we try - * to answer it then NTws gets a BSOD! (tridge). W2K seems to - * want this. JRA. - */ - /* The first statement above is false - verified using Thursby - * client against NT4 -- gcolley. - */ - case SMB_QUERY_FILE_STREAM_INFO: - case SMB_FILE_STREAM_INFORMATION: { - unsigned int num_streams; - struct stream_struct *streams; + status = create_synthetic_smb_fname_split(talloc_tos(), fname, + NULL, &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; + } - DEBUG(10,("call_trans2qfilepathinfo: " - "SMB_FILE_STREAM_INFORMATION\n")); + if(fsp->fake_file_handle) { + /* + * This is actually for the QUOTA_FAKE_FILE --metze + */ - status = SMB_VFS_STREAMINFO( - conn, fsp, fname, talloc_tos(), - &num_streams, &streams); + /* We know this name is ok, it's already passed the checks. */ - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("could not get stream info: %s\n", - nt_errstr(status))); - reply_nterror(req, status); + } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) { + /* + * This is actually a QFILEINFO on a directory + * handle (returned from an NT SMB). NT5.0 seems + * to do this call. JRA. + */ + + if (INFO_LEVEL_IS_UNIX(info_level)) { + /* Always do lstat for UNIX calls. */ + if (SMB_VFS_LSTAT(conn, smb_fname)) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_LSTAT of %s failed " + "(%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, + map_nt_error_from_unix(errno)); + return; + } + } else if (SMB_VFS_STAT(conn, smb_fname)) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_STAT of %s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, + map_nt_error_from_unix(errno)); return; } - status = marshall_stream_info(num_streams, streams, - pdata, max_data_bytes, - &data_size); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("marshall_stream_info failed: %s\n", - nt_errstr(status))); - reply_nterror(req, status); + fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + get_file_infos(fileid, &delete_pending, &write_time_ts); + } else { + /* + * Original code - this is an open file. + */ + if (!check_fsp(conn, req, fsp)) { return; } - TALLOC_FREE(streams); - - break; + if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + DEBUG(3, ("fstat of fnum %d failed (%s)\n", + fsp->fnum, strerror(errno))); + reply_nterror(req, + map_nt_error_from_unix(errno)); + return; + } + fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + get_file_infos(fileid, &delete_pending, &write_time_ts); } - case SMB_QUERY_COMPRESSION_INFO: - case SMB_FILE_COMPRESSION_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n")); - SOFF_T(pdata,0,file_size); - SIVAL(pdata,8,0); /* ??? */ - SIVAL(pdata,12,0); /* ??? */ - data_size = 16; - break; - case SMB_FILE_NETWORK_OPEN_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n")); - put_long_date_timespec(pdata,create_time_ts); - put_long_date_timespec(pdata+8,atime_ts); - put_long_date_timespec(pdata+16,mtime_ts); /* write time */ - put_long_date_timespec(pdata+24,mtime_ts); /* change time */ - SOFF_T(pdata,32,allocation_size); - SOFF_T(pdata,40,file_size); - SIVAL(pdata,48,mode); - SIVAL(pdata,52,0); /* ??? */ - data_size = 56; - break; - - case SMB_FILE_ATTRIBUTE_TAG_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n")); - SIVAL(pdata,0,mode); - SIVAL(pdata,4,0); - data_size = 8; - break; + } else { + /* qpathinfo */ + if (total_params < 7) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } - /* - * CIFS UNIX Extensions. - */ + info_level = SVAL(params,0); - case SMB_QUERY_FILE_UNIX_BASIC: + DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level)); - pdata = store_file_unix_basic(conn, pdata, fsp, &sbuf); - data_size = PTR_DIFF(pdata,(*ppdata)); + if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { + reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return; + } - { - int i; - DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC ")); + srvstr_get_path(req, params, req->flags2, &fname, ¶ms[6], + total_params - 6, + STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; + } - for (i=0; i<100; i++) - DEBUG(4,("%d=%x, ",i, (*ppdata)[i])); - DEBUG(4,("\n")); + status = filename_convert(req, + conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + fname, + &smb_fname, + &fname); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + return; } + reply_nterror(req, status); + return; + } - break; - - case SMB_QUERY_FILE_UNIX_INFO2: - - pdata = store_file_unix_basic_info2(conn, pdata, fsp, &sbuf); - data_size = PTR_DIFF(pdata,(*ppdata)); - - { - int i; - DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 ")); + /* If this is a stream, check if there is a delete_pending. */ + if ((conn->fs_capabilities & FILE_NAMED_STREAMS) + && is_ntfs_stream_smb_fname(smb_fname)) { + struct smb_filename *smb_fname_base = NULL; - for (i=0; i<100; i++) - DEBUG(4,("%d=%x, ",i, (*ppdata)[i])); - DEBUG(4,("\n")); + /* Create an smb_filename with stream_name == NULL. */ + status = + create_synthetic_smb_fname(talloc_tos(), + smb_fname->base_name, + NULL, NULL, + &smb_fname_base); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; } - break; - - case SMB_QUERY_FILE_UNIX_LINK: - { - char *buffer = TALLOC_ARRAY(ctx, char, PATH_MAX+1); - - if (!buffer) { - reply_nterror(req, NT_STATUS_NO_MEMORY); + if (INFO_LEVEL_IS_UNIX(info_level)) { + /* Always do lstat for UNIX calls. */ + if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_LSTAT of %s failed " + "(%s)\n", + smb_fname_str_dbg(smb_fname_base), + strerror(errno))); + TALLOC_FREE(smb_fname_base); + reply_nterror(req, + map_nt_error_from_unix(errno)); return; } - - DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n")); -#ifdef S_ISLNK - if(!S_ISLNK(sbuf.st_ex_mode)) { - reply_doserror(req, ERRSRV, - ERRbadlink); + } else { + if (SMB_VFS_STAT(conn, smb_fname_base) != 0) { + DEBUG(3,("call_trans2qfilepathinfo: " + "fileinfo of %s failed " + "(%s)\n", + smb_fname_str_dbg(smb_fname_base), + strerror(errno))); + TALLOC_FREE(smb_fname_base); + reply_nterror(req, + map_nt_error_from_unix(errno)); return; } -#else - reply_doserror(req, ERRDOS, ERRbadlink); + } + + fileid = vfs_file_id_from_sbuf(conn, + &smb_fname_base->st); + TALLOC_FREE(smb_fname_base); + get_file_infos(fileid, &delete_pending, NULL); + if (delete_pending) { + reply_nterror(req, NT_STATUS_DELETE_PENDING); return; -#endif - len = SMB_VFS_READLINK(conn,fullpathname, - buffer, PATH_MAX); - if (len == -1) { - reply_nterror(req, map_nt_error_from_unix(errno)); - return; - } - buffer[len] = 0; - len = srvstr_push(dstart, req->flags2, - pdata, buffer, - PTR_DIFF(dend, pdata), - STR_TERMINATE); - pdata += len; - data_size = PTR_DIFF(pdata,(*ppdata)); + } + } - break; + if (INFO_LEVEL_IS_UNIX(info_level)) { + /* Always do lstat for UNIX calls. */ + if (SMB_VFS_LSTAT(conn, smb_fname)) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_LSTAT of %s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, + map_nt_error_from_unix(errno)); + return; } -#if defined(HAVE_POSIX_ACLS) - case SMB_QUERY_POSIX_ACL: - { - SMB_ACL_T file_acl = NULL; - SMB_ACL_T def_acl = NULL; - uint16 num_file_acls = 0; - uint16 num_def_acls = 0; + } else if (!VALID_STAT(smb_fname->st) && + SMB_VFS_STAT(conn, smb_fname) && + (info_level != SMB_INFO_IS_NAME_VALID)) { + ms_dfs_link = check_msdfs_link(conn, fname, + &smb_fname->st); - if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) { - file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp); - } else { - file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS); - } + if (!ms_dfs_link) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_STAT of %s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, + map_nt_error_from_unix(errno)); + return; + } + } - if (file_acl == NULL && no_acl_syscall_error(errno)) { - DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n", - fname )); - reply_nterror( - req, - NT_STATUS_NOT_IMPLEMENTED); - return; - } + fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + get_file_infos(fileid, &delete_pending, &write_time_ts); + if (delete_pending) { + reply_nterror(req, NT_STATUS_DELETE_PENDING); + return; + } + } - if (S_ISDIR(sbuf.st_ex_mode)) { - if (fsp && fsp->is_directory) { - def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT); - } else { - def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT); - } - def_acl = free_empty_sys_acl(conn, def_acl); - } + DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n", + fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data)); - num_file_acls = count_acl_entries(conn, file_acl); - num_def_acls = count_acl_entries(conn, def_acl); + /* Pull out any data sent here before we realloc. */ + switch (info_level) { + case SMB_INFO_QUERY_EAS_FROM_LIST: + { + /* Pull any EA list from the data portion. */ + uint32 ea_size; - if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) { - DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n", - data_size, - (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + - SMB_POSIX_ACL_HEADER_SIZE) )); - if (file_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); - } - if (def_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); - } - reply_nterror( - req, - NT_STATUS_BUFFER_TOO_SMALL); - return; - } + if (total_data < 4) { + reply_nterror( + req, NT_STATUS_INVALID_PARAMETER); + return; + } + ea_size = IVAL(pdata,0); - SSVAL(pdata,0,SMB_POSIX_ACL_VERSION); - SSVAL(pdata,2,num_file_acls); - SSVAL(pdata,4,num_def_acls); - if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) { - if (file_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); - } - if (def_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); - } - reply_nterror( - req, NT_STATUS_INTERNAL_ERROR); - return; - } - if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) { - if (file_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); - } - if (def_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); - } - reply_nterror( - req, - NT_STATUS_INTERNAL_ERROR); - return; - } + if (total_data > 0 && ea_size != total_data) { + DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \ +total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) )); + reply_nterror( + req, NT_STATUS_INVALID_PARAMETER); + return; + } - if (file_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); - } - if (def_acl) { - SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); - } - data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE; - break; + if (!lp_ea_support(SNUM(conn))) { + reply_doserror(req, ERRDOS, + ERReasnotsupported); + return; } -#endif + /* Pull out the list of names. */ + ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4); + if (!ea_list) { + reply_nterror( + req, NT_STATUS_INVALID_PARAMETER); + return; + } + break; + } case SMB_QUERY_POSIX_LOCK: { - uint64_t count; - uint64_t offset; - uint32 lock_pid; - enum brl_type lock_type; + if (fsp == NULL || fsp->fh->fd == -1) { + reply_nterror(req, NT_STATUS_INVALID_HANDLE); + return; + } if (total_data != POSIX_LOCK_DATA_SIZE) { reply_nterror( @@ -4830,73 +4893,55 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd return; } - switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) { - case POSIX_LOCK_TYPE_READ: - lock_type = READ_LOCK; - break; - case POSIX_LOCK_TYPE_WRITE: - lock_type = WRITE_LOCK; - break; - case POSIX_LOCK_TYPE_UNLOCK: - default: - /* There's no point in asking for an unlock... */ - reply_nterror( - req, - NT_STATUS_INVALID_PARAMETER); - return; - } - - lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET); -#if defined(HAVE_LONGLONG) - offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) | - ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET)); - count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) | - ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET)); -#else /* HAVE_LONGLONG */ - offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET); - count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET); -#endif /* HAVE_LONGLONG */ - - status = query_lock(fsp, - &lock_pid, - &count, - &offset, - &lock_type, - POSIX_LOCK); - - if (ERROR_WAS_LOCK_DENIED(status)) { - /* Here we need to report who has it locked... */ - data_size = POSIX_LOCK_DATA_SIZE; - - SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type); - SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0); - SIVAL(pdata, POSIX_LOCK_PID_OFFSET, lock_pid); -#if defined(HAVE_LONGLONG) - SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF)); - SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF)); - SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF)); - SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF)); -#else /* HAVE_LONGLONG */ - SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset); - SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count); -#endif /* HAVE_LONGLONG */ - - } else if (NT_STATUS_IS_OK(status)) { - /* For success we just return a copy of what we sent - with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */ - data_size = POSIX_LOCK_DATA_SIZE; - memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE); - SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK); - } else { - reply_nterror(req, status); + /* Copy the lock range data. */ + lock_data = (char *)TALLOC_MEMDUP( + req, pdata, total_data); + if (!lock_data) { + reply_nterror(req, NT_STATUS_NO_MEMORY); return; } - break; + lock_data_count = total_data; } - default: - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + break; + } + + *pparams = (char *)SMB_REALLOC(*pparams,2); + if (*pparams == NULL) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + params = *pparams; + SSVAL(params,0,0); + + /* + * draft-leach-cifs-v1-spec-02.txt + * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path + * says: + * + * The requested information is placed in the Data portion of the + * transaction response. For the information levels greater than 0x100, + * the transaction response has 1 parameter word which should be + * ignored by the client. + * + * However Windows only follows this rule for the IS_NAME_VALID call. + */ + switch (info_level) { + case SMB_INFO_IS_NAME_VALID: + param_size = 0; + break; + } + + status = smbd_do_qfilepathinfo(conn, req, info_level, + fsp, smb_fname, + delete_pending, write_time_ts, + ms_dfs_link, ea_list, + lock_data_count, lock_data, + req->flags2, max_data_bytes, + ppdata, &data_size); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; } send_trans2_replies(conn, req, params, param_size, *ppdata, data_size, -- cgit From ee690df294aab7a738bfec1976a2f015e918db1e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 12 Jul 2009 16:37:49 +0200 Subject: s3:smbd: split calculation and mashalling of file index and access_mask metze --- source3/smbd/trans2.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index c9e7e4bbfb..757e5f5c8b 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3910,6 +3910,8 @@ static NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, uint64_t file_size = 0; uint64_t pos = 0; uint64_t allocation_size = 0; + uint64_t file_index = 0; + uint32_t access_mask = 0; sbuf = smb_fname->st; @@ -4013,6 +4015,21 @@ static NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, pos = fsp->fh->position_information; } + if (fsp) { + access_mask = fsp->access_mask; + } else { + /* GENERIC_EXECUTE mapping from Windows */ + access_mask = 0x12019F; + } + + /* This should be an index number - looks like + dev/ino to me :-) + + I think this causes us to fail the IFSKIT + BasicFileInformationTest. -tpot */ + file_index = ((sbuf.st_ex_ino) & UINT32_MAX); /* FileIndexLow */ + file_index |= ((sbuf.st_ex_dev) & UINT32_MAX) << 32; /* FileIndexHigh */ + switch (info_level) { case SMB_INFO_STANDARD: DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n")); @@ -4218,26 +4235,15 @@ static NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, break; } case SMB_FILE_INTERNAL_INFORMATION: - /* This should be an index number - looks like - dev/ino to me :-) - - I think this causes us to fail the IFSKIT - BasicFileInformationTest. -tpot */ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n")); - SIVAL(pdata,0,sbuf.st_ex_ino); /* FileIndexLow */ - SIVAL(pdata,4,sbuf.st_ex_dev); /* FileIndexHigh */ + SBVAL(pdata, 0, file_index); data_size = 8; break; case SMB_FILE_ACCESS_INFORMATION: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n")); - if (fsp) { - SIVAL(pdata,0,fsp->access_mask); - } else { - /* GENERIC_EXECUTE mapping from Windows */ - SIVAL(pdata,0,0x12019F); - } + SIVAL(pdata, 0, access_mask); data_size = 4; break; -- cgit From 0ba532e1b2dedea3c07fa55631fac0d9a5032fcf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2009 20:02:44 +0200 Subject: s3:smbd: make smbd_do_qfilepathinfo() non static for use in SMB2 metze --- source3/smbd/globals.h | 16 ++++++++++++++++ source3/smbd/trans2.c | 30 +++++++++++++++--------------- 2 files changed, 31 insertions(+), 15 deletions(-) (limited to 'source3') diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 8163213dd0..725a94a90b 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -185,6 +185,22 @@ NTSTATUS smbd_do_locking(struct smb_request *req, struct smbd_lock_element *locks, bool *async); +NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + files_struct *fsp, + const struct smb_filename *smb_fname, + bool delete_pending, + struct timespec write_time_ts, + bool ms_dfs_link, + struct ea_list *ea_list, + int lock_data_count, + char *lock_data, + uint16_t flags2, + unsigned int max_data_bytes, + char **ppdata, + unsigned int *pdata_size); + void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn, const char *reason, const char *location); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 757e5f5c8b..29abbfe3f5 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3878,21 +3878,21 @@ static void call_trans2qpipeinfo(connection_struct *conn, return; } -static NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, - TALLOC_CTX *mem_ctx, - uint16_t info_level, - files_struct *fsp, - const struct smb_filename *smb_fname, - bool delete_pending, - struct timespec write_time_ts, - bool ms_dfs_link, - struct ea_list *ea_list, - int lock_data_count, - char *lock_data, - uint16_t flags2, - unsigned int max_data_bytes, - char **ppdata, - unsigned int *pdata_size) +NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + files_struct *fsp, + const struct smb_filename *smb_fname, + bool delete_pending, + struct timespec write_time_ts, + bool ms_dfs_link, + struct ea_list *ea_list, + int lock_data_count, + char *lock_data, + uint16_t flags2, + unsigned int max_data_bytes, + char **ppdata, + unsigned int *pdata_size) { char *pdata = *ppdata; char *dstart, *dend; -- cgit From 0851d73f4dbb916b6e83d89cf2e2959c1159b7e0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 12 Jul 2009 17:06:05 +0200 Subject: s3:smbd: filter out SMB2 specific private query info levels for SMB1 metze --- source3/smbd/trans2.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 29abbfe3f5..96265861f2 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4938,6 +4938,15 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd break; } + if ((info_level & 0xFF00) == 0xFF00) { + /* + * We use levels that start with 0xFF00 + * internally to represent SMB2 specific levels + */ + reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return; + } + status = smbd_do_qfilepathinfo(conn, req, info_level, fsp, smb_fname, delete_pending, write_time_ts, -- cgit From e9865150dfd9a81fdc3a8b13b086540641fb4c2e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 12 Jul 2009 17:08:18 +0200 Subject: s3:smbd: add support for marshalling SMB2 FileAllInformation metze --- source3/smbd/trans2.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 96265861f2..f13c2f0338 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4234,6 +4234,42 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, data_size = PTR_DIFF(pdata,(*ppdata)); break; } + + case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/ + { + int len; + unsigned int ea_size = estimate_ea_size(conn, fsp, fname); + DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n")); + put_long_date_timespec(pdata+0x00,create_time_ts); + put_long_date_timespec(pdata+0x08,atime_ts); + put_long_date_timespec(pdata+0x10,mtime_ts); /* write time */ + put_long_date_timespec(pdata+0x18,mtime_ts); /* change time */ + SIVAL(pdata, 0x20, mode); + SIVAL(pdata, 0x24, 0); /* padding. */ + SBVAL(pdata, 0x28, allocation_size); + SBVAL(pdata, 0x30, file_size); + SIVAL(pdata, 0x38, nlink); + SCVAL(pdata, 0x3C, delete_pending); + SCVAL(pdata, 0x3D, (mode&aDIR)?1:0); + SSVAL(pdata, 0x3E, 0); /* padding */ + SBVAL(pdata, 0x40, file_index); + SIVAL(pdata, 0x48, ea_size); + SIVAL(pdata, 0x4C, access_mask); + SBVAL(pdata, 0x50, pos); + SIVAL(pdata, 0x58, mode); /*TODO: mode != mode fix this!!! */ + SIVAL(pdata, 0x5C, 0); /* No alignment needed. */ + + pdata += 0x60; + + len = srvstr_push(dstart, flags2, + pdata+4, dos_fname, + PTR_DIFF(dend, pdata+4), + STR_UNICODE); + SIVAL(pdata,0,len); + pdata += 4 + len; + data_size = PTR_DIFF(pdata,(*ppdata)); + break; + } case SMB_FILE_INTERNAL_INFORMATION: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n")); -- cgit From 64221bc3facde5d2e6d35516eb997d83c5f90d35 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 12 Jul 2009 16:40:58 +0200 Subject: s3:smbd: add support for marshalling SMB2 FileFullEaInformation metze --- source3/smbd/trans2.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index f13c2f0338..6554fb67b7 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -367,6 +367,69 @@ static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned in return ret_data_size; } +static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx, + char *pdata, + unsigned int total_data_size, + unsigned int *ret_data_size, + connection_struct *conn, + struct ea_list *ea_list) +{ + uint8_t *p = (uint8_t *)pdata; + uint8_t *last_start = NULL; + + *ret_data_size = 0; + + if (!lp_ea_support(SNUM(conn))) { + return NT_STATUS_NO_EAS_ON_FILE; + } + + for (; ea_list; ea_list = ea_list->next) { + size_t dos_namelen; + fstring dos_ea_name; + size_t this_size; + + if (last_start) { + SIVAL(last_start, 0, PTR_DIFF(p, last_start)); + } + last_start = p; + + push_ascii_fstring(dos_ea_name, ea_list->ea.name); + dos_namelen = strlen(dos_ea_name); + if (dos_namelen > 255 || dos_namelen == 0) { + return NT_STATUS_INTERNAL_ERROR; + } + if (ea_list->ea.value.length > 65535) { + return NT_STATUS_INTERNAL_ERROR; + } + + this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length; + + if (ea_list->next) { + size_t pad = 4 - (this_size % 4); + this_size += pad; + } + + if (this_size > total_data_size) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + + /* We know we have room. */ + SIVAL(p, 0x00, 0); /* next offset */ + SCVAL(p, 0x04, ea_list->ea.flags); + SCVAL(p, 0x05, dos_namelen); + SSVAL(p, 0x06, ea_list->ea.value.length); + fstrcpy((char *)(p+0x08), dos_ea_name); + memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length); + + total_data_size -= this_size; + p += this_size; + } + + *ret_data_size = PTR_DIFF(p, pdata); + DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size)); + return NT_STATUS_OK; +} + static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname) { size_t total_ea_len = 0; @@ -4105,6 +4168,35 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, break; } + case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/ + { + /* We have data_size bytes to put EA's into. */ + size_t total_ea_len = 0; + struct ea_list *ea_file_list = NULL; + + DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n")); + + /*TODO: add filtering and index handling */ + + ea_file_list = get_ea_list_from_file(mem_ctx, + conn, fsp, + fname, + &total_ea_len); + if (!ea_file_list) { + return NT_STATUS_NO_EAS_ON_FILE; + } + + status = fill_ea_chained_buffer(mem_ctx, + pdata, + data_size, + &data_size, + conn, ea_file_list); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + break; + } + case SMB_FILE_BASIC_INFORMATION: case SMB_QUERY_FILE_BASIC_INFO: -- cgit From d7809f65cf25ea10b3edd7df209cbf67a43df138 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2009 20:39:08 +0200 Subject: s3:smbd: start SMB2 GetInfo support for File*Information levels TODO: the EA levels are not fully supported. metze --- source3/smbd/smb2_getinfo.c | 140 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 139 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index ba725fdec9..b6b7462e90 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -233,7 +233,145 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED); + if (IS_IPC(conn)) { + tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); + return tevent_req_post(req, ev); + } + + switch (in_info_type) { + case 0x01:/* SMB2_GETINFO_FILE */ + { + uint16_t file_info_level; + char *data = NULL; + unsigned int data_size = 0; + struct smb_filename *smb_fname = NULL; + bool delete_pending = false; + struct timespec write_time_ts; + struct file_id fileid; + struct ea_list *ea_list = NULL; + int lock_data_count = 0; + char *lock_data = NULL; + bool ms_dfs_link = false; + NTSTATUS status; + + ZERO_STRUCT(write_time_ts); + + switch (in_file_info_class) { + case 0x0F:/* RAW_FILEINFO_SMB2_ALL_EAS */ + file_info_level = 0xFF00 | in_file_info_class; + break; + + case 0x12:/* RAW_FILEINFO_SMB2_ALL_INFORMATION */ + file_info_level = 0xFF00 | in_file_info_class; + break; + + default: + /* the levels directly map to the passthru levels */ + file_info_level = in_file_info_class + 1000; + break; + } + + status = create_synthetic_smb_fname_split(state, + fsp->fsp_name, + NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + + if (fsp->fake_file_handle) { + /* + * This is actually for the QUOTA_FAKE_FILE --metze + */ + + /* We know this name is ok, it's already passed the checks. */ + + } else if (fsp && (fsp->is_directory || fsp->fh->fd == -1)) { + /* + * This is actually a QFILEINFO on a directory + * handle (returned from an NT SMB). NT5.0 seems + * to do this call. JRA. + */ + + if (INFO_LEVEL_IS_UNIX(file_info_level)) { + /* Always do lstat for UNIX calls. */ + if (SMB_VFS_LSTAT(conn, smb_fname)) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_LSTAT of %s failed " + "(%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + } else if (SMB_VFS_STAT(conn, smb_fname)) { + DEBUG(3,("call_trans2qfilepathinfo: " + "SMB_VFS_STAT of %s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + + fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + get_file_infos(fileid, &delete_pending, &write_time_ts); + } else { + /* + * Original code - this is an open file. + */ + + if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + DEBUG(3, ("fstat of fnum %d failed (%s)\n", + fsp->fnum, strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + get_file_infos(fileid, &delete_pending, &write_time_ts); + } + + status = smbd_do_qfilepathinfo(conn, state, + file_info_level, + fsp, + smb_fname, + delete_pending, + write_time_ts, + ms_dfs_link, + ea_list, + lock_data_count, + lock_data, + STR_UNICODE, + in_output_buffer_length, + &data, + &data_size); + if (!NT_STATUS_IS_OK(status)) { + SAFE_FREE(data); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + if (data_size > 0) { + state->out_output_buffer = data_blob_talloc(state, + data, + data_size); + SAFE_FREE(data); + if (tevent_req_nomem(state->out_output_buffer.data, req)) { + return tevent_req_post(req, ev); + } + } + SAFE_FREE(data); + break; + } + + default: + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + tevent_req_done(req); return tevent_req_post(req, ev); } -- cgit From f26a2ca8e43884a62bf5822e7571692870ecc7a1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 08:59:32 +0200 Subject: s3:smbd: split out smbd_do_setfilepathinfo() from call_trans2setfilepathinfo() metze --- source3/smbd/trans2.c | 404 +++++++++++++++++++++++++++----------------------- 1 file changed, 216 insertions(+), 188 deletions(-) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 6554fb67b7..54d873065c 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -7055,200 +7055,45 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, return close_file(req, fsp, NORMAL_CLOSE); } -/**************************************************************************** - Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname). -****************************************************************************/ - -static void call_trans2setfilepathinfo(connection_struct *conn, - struct smb_request *req, - unsigned int tran_call, - char **pparams, int total_params, - char **ppdata, int total_data, - unsigned int max_data_bytes) +static NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, + struct smb_request *req, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + files_struct *fsp, + struct smb_filename *smb_fname, + char **ppdata, int total_data, + int *ret_data_size) { - char *params = *pparams; char *pdata = *ppdata; - uint16 info_level; SMB_STRUCT_STAT sbuf; char *fname = NULL; - struct smb_filename *smb_fname = NULL; - files_struct *fsp = NULL; NTSTATUS status = NT_STATUS_OK; int data_return_size = 0; - TALLOC_CTX *ctx = talloc_tos(); - - if (!params) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; - } - - if (tran_call == TRANSACT2_SETFILEINFO) { - if (total_params < 4) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; - } - - fsp = file_fsp(req, SVAL(params,0)); - /* Basic check for non-null fsp. */ - if (!check_fsp_open(conn, req, fsp)) { - return; - } - info_level = SVAL(params,2); - - fname = talloc_strdup(talloc_tos(),fsp->fsp_name); - if (!fname) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - return; - } - if(fsp->is_directory || fsp->fh->fd == -1) { - /* - * This is actually a SETFILEINFO on a directory - * handle (returned from an NT SMB). NT5.0 seems - * to do this call. JRA. - */ - if (INFO_LEVEL_IS_UNIX(info_level)) { - /* Always do lstat for UNIX calls. */ - if (SMB_VFS_LSTAT(conn, smb_fname)) { - DEBUG(3,("call_trans2setfilepathinfo: " - "SMB_VFS_LSTAT of %s failed " - "(%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req, map_nt_error_from_unix(errno)); - return; - } - } else { - if (SMB_VFS_STAT(conn, smb_fname) != 0) { - DEBUG(3,("call_trans2setfilepathinfo: " - "fileinfo of %s failed (%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req, map_nt_error_from_unix(errno)); - return; - } - } - } else if (fsp->print_file) { - /* - * Doing a DELETE_ON_CLOSE should cancel a print job. - */ - if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) { - fsp->fh->private_options |= FILE_DELETE_ON_CLOSE; - - DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name )); - - SSVAL(params,0,0); - send_trans2_replies(conn, req, params, 2, - *ppdata, 0, - max_data_bytes); - return; - } else { - reply_doserror(req, ERRDOS, ERRbadpath); - return; - } - } else { - /* - * Original code - this is an open file. - */ - if (!check_fsp(conn, req, fsp)) { - return; - } - - if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { - DEBUG(3,("call_trans2setfilepathinfo: fstat " - "of fnum %d failed (%s)\n", fsp->fnum, - strerror(errno))); - reply_nterror(req, map_nt_error_from_unix(errno)); - return; - } - } - } else { - /* set path info */ - if (total_params < 7) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; - } - - info_level = SVAL(params,0); - srvstr_get_path(ctx, params, req->flags2, &fname, ¶ms[6], - total_params - 6, STR_TERMINATE, - &status); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - return; - } - - status = filename_convert(ctx, conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - fname, - &smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { - reply_botherror(req, - NT_STATUS_PATH_NOT_COVERED, - ERRSRV, ERRbadpath); - return; - } - reply_nterror(req, status); - return; - } - - if (INFO_LEVEL_IS_UNIX(info_level)) { - /* - * For CIFS UNIX extensions the target name may not exist. - */ - - /* Always do lstat for UNIX calls. */ - SMB_VFS_LSTAT(conn, smb_fname); - - } else if (!VALID_STAT(smb_fname->st) && - SMB_VFS_STAT(conn, smb_fname)) { - DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of " - "%s failed (%s)\n", - smb_fname_str_dbg(smb_fname), - strerror(errno))); - reply_nterror(req, map_nt_error_from_unix(errno)); - return; - } - } + *ret_data_size = 0; /* Set sbuf for use below. */ sbuf = smb_fname->st; if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } if (!CAN_WRITE(conn)) { /* Allow POSIX opens. The open path will deny * any non-readonly opens. */ if (info_level != SMB_POSIX_PATH_OPEN) { - reply_doserror(req, ERRSRV, ERRaccess); - return; + return NT_STATUS_DOS(ERRSRV, ERRaccess); } } - DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n", - tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data)); - - /* Realloc the parameter size */ - *pparams = (char *)SMB_REALLOC(*pparams,2); - if (*pparams == NULL) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + status = get_full_smb_filename(mem_ctx, smb_fname, &fname); + if (!NT_STATUS_IS_OK(status)) { + return status; } - params = *pparams; - SSVAL(params,0,0); + DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d totdata=%d\n", + fname, fsp ? fsp->fnum : -1, info_level, total_data)); switch (info_level) { @@ -7374,10 +7219,9 @@ static void call_trans2setfilepathinfo(connection_struct *conn, case SMB_SET_FILE_UNIX_LINK: { - if (tran_call != TRANSACT2_SETPATHINFO) { + if (fsp) { /* We must have a pathname for this. */ - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } status = smb_set_file_unix_link(conn, req, pdata, total_data, fname); @@ -7386,10 +7230,9 @@ static void call_trans2setfilepathinfo(connection_struct *conn, case SMB_SET_FILE_UNIX_HLINK: { - if (tran_call != TRANSACT2_SETPATHINFO || smb_fname == NULL) { + if (fsp || smb_fname == NULL) { /* We must have a pathname for this. */ - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } status = smb_set_file_unix_hlink(conn, req, pdata, total_data, @@ -7420,9 +7263,8 @@ static void call_trans2setfilepathinfo(connection_struct *conn, case SMB_SET_POSIX_LOCK: { - if (tran_call != TRANSACT2_SETFILEINFO) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + if (fsp) { + return NT_STATUS_INVALID_LEVEL; } status = smb_set_posix_lock(conn, req, pdata, total_data, fsp); @@ -7431,10 +7273,9 @@ static void call_trans2setfilepathinfo(connection_struct *conn, case SMB_POSIX_PATH_OPEN: { - if (tran_call != TRANSACT2_SETPATHINFO) { + if (fsp) { /* We must have a pathname for this. */ - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } status = smb_posix_open(conn, req, @@ -7448,10 +7289,9 @@ static void call_trans2setfilepathinfo(connection_struct *conn, case SMB_POSIX_PATH_UNLINK: { - if (tran_call != TRANSACT2_SETPATHINFO) { + if (fsp) { /* We must have a pathname for this. */ - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } status = smb_posix_unlink(conn, req, @@ -7462,10 +7302,199 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } default: - reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return NT_STATUS_INVALID_LEVEL; + } + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + *ret_data_size = data_return_size; + return NT_STATUS_OK; +} + +/**************************************************************************** + Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname). +****************************************************************************/ + +static void call_trans2setfilepathinfo(connection_struct *conn, + struct smb_request *req, + unsigned int tran_call, + char **pparams, int total_params, + char **ppdata, int total_data, + unsigned int max_data_bytes) +{ + char *params = *pparams; + char *pdata = *ppdata; + uint16 info_level; + char *fname = NULL; + struct smb_filename *smb_fname = NULL; + files_struct *fsp = NULL; + NTSTATUS status = NT_STATUS_OK; + int data_return_size = 0; + + if (!params) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } + + if (tran_call == TRANSACT2_SETFILEINFO) { + if (total_params < 4) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } + + fsp = file_fsp(req, SVAL(params,0)); + /* Basic check for non-null fsp. */ + if (!check_fsp_open(conn, req, fsp)) { + return; + } + info_level = SVAL(params,2); + + fname = talloc_strdup(talloc_tos(),fsp->fsp_name); + if (!fname) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + + status = create_synthetic_smb_fname_split(talloc_tos(), fname, + NULL, &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; + } + + if(fsp->is_directory || fsp->fh->fd == -1) { + /* + * This is actually a SETFILEINFO on a directory + * handle (returned from an NT SMB). NT5.0 seems + * to do this call. JRA. + */ + if (INFO_LEVEL_IS_UNIX(info_level)) { + /* Always do lstat for UNIX calls. */ + if (SMB_VFS_LSTAT(conn, smb_fname)) { + DEBUG(3,("call_trans2setfilepathinfo: " + "SMB_VFS_LSTAT of %s failed " + "(%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, map_nt_error_from_unix(errno)); + return; + } + } else { + if (SMB_VFS_STAT(conn, smb_fname) != 0) { + DEBUG(3,("call_trans2setfilepathinfo: " + "fileinfo of %s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, map_nt_error_from_unix(errno)); + return; + } + } + } else if (fsp->print_file) { + /* + * Doing a DELETE_ON_CLOSE should cancel a print job. + */ + if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) { + fsp->fh->private_options |= FILE_DELETE_ON_CLOSE; + + DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name )); + + SSVAL(params,0,0); + send_trans2_replies(conn, req, params, 2, + *ppdata, 0, + max_data_bytes); + return; + } else { + reply_doserror(req, ERRDOS, ERRbadpath); + return; + } + } else { + /* + * Original code - this is an open file. + */ + if (!check_fsp(conn, req, fsp)) { + return; + } + + if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + DEBUG(3,("call_trans2setfilepathinfo: fstat " + "of fnum %d failed (%s)\n", fsp->fnum, + strerror(errno))); + reply_nterror(req, map_nt_error_from_unix(errno)); + return; + } + } + } else { + /* set path info */ + if (total_params < 7) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; + } + + info_level = SVAL(params,0); + srvstr_get_path(req, params, req->flags2, &fname, ¶ms[6], + total_params - 6, STR_TERMINATE, + &status); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; + } + + status = filename_convert(req, conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + fname, + &smb_fname, + &fname); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + return; + } + reply_nterror(req, status); + return; + } + + if (INFO_LEVEL_IS_UNIX(info_level)) { + /* + * For CIFS UNIX extensions the target name may not exist. + */ + + /* Always do lstat for UNIX calls. */ + SMB_VFS_LSTAT(conn, smb_fname); + + } else if (!VALID_STAT(smb_fname->st) && + SMB_VFS_STAT(conn, smb_fname)) { + DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of " + "%s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + reply_nterror(req, map_nt_error_from_unix(errno)); + return; + } } + DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n", + tran_call, fname, fsp ? fsp->fnum : -1, info_level,total_data)); + + /* Realloc the parameter size */ + *pparams = (char *)SMB_REALLOC(*pparams,2); + if (*pparams == NULL) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + params = *pparams; + + SSVAL(params,0,0); + + status = smbd_do_setfilepathinfo(conn, req, req, + info_level, + fsp, + smb_fname, + ppdata, total_data, + &data_return_size); if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { /* We have re-scheduled this call. */ @@ -7489,7 +7518,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn, return; } - SSVAL(params,0,0); send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size, max_data_bytes); -- cgit From 7d735519d7f6a726240dff8cdcae36acd73df48c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 09:01:56 +0200 Subject: s3:smbd: make smbd_do_setfilepathinfo() non static for use in SMB2 SetInfo metze --- source3/smbd/globals.h | 9 +++++++++ source3/smbd/trans2.c | 16 ++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'source3') diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 725a94a90b..109c29a1ae 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -201,6 +201,15 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, char **ppdata, unsigned int *pdata_size); +NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, + struct smb_request *req, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + files_struct *fsp, + struct smb_filename *smb_fname, + char **ppdata, int total_data, + int *ret_data_size); + void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn, const char *reason, const char *location); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 54d873065c..085a0b2acb 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -7055,14 +7055,14 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, return close_file(req, fsp, NORMAL_CLOSE); } -static NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, - struct smb_request *req, - TALLOC_CTX *mem_ctx, - uint16_t info_level, - files_struct *fsp, - struct smb_filename *smb_fname, - char **ppdata, int total_data, - int *ret_data_size) +NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, + struct smb_request *req, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + files_struct *fsp, + struct smb_filename *smb_fname, + char **ppdata, int total_data, + int *ret_data_size) { char *pdata = *ppdata; SMB_STRUCT_STAT sbuf; -- cgit From 2a92139a1ca8b2c1950f6ca32255b8fcfdeefff6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 11:54:20 +0200 Subject: s3:smbd: split out smbd_do_qfsinfo() from call_trans2qfsinfo() metze --- source3/smbd/trans2.c | 172 +++++++++++++++++++++++++++----------------------- 1 file changed, 93 insertions(+), 79 deletions(-) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 085a0b2acb..2ee3938aec 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2687,67 +2687,37 @@ static void samba_extended_info_version(struct smb_extended_info *extended_info) "%s", samba_version_string()); } -/**************************************************************************** - Reply to a TRANS2_QFSINFO (query filesystem info). -****************************************************************************/ - -static void call_trans2qfsinfo(connection_struct *conn, - struct smb_request *req, - char **pparams, int total_params, - char **ppdata, int total_data, - unsigned int max_data_bytes) +static NTSTATUS smbd_do_qfsinfo(connection_struct *conn, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + SMB_STRUCT_STAT st, + uint16_t flags2, + unsigned int max_data_bytes, + char **ppdata, + int *ret_data_len) { char *pdata, *end_data; - char *params = *pparams; - uint16 info_level; - int data_len, len; - SMB_STRUCT_STAT st; + int data_len = 0, len; const char *vname = volume_label(SNUM(conn)); int snum = SNUM(conn); char *fstype = lp_fstype(SNUM(conn)); uint32 additional_flags = 0; - if (total_params < 2) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; - } - - info_level = SVAL(params,0); - if (IS_IPC(conn)) { if (info_level != SMB_QUERY_CIFS_UNIX_INFO) { - DEBUG(0,("call_trans2qfsinfo: not an allowed " + DEBUG(0,("smbd_do_qfsinfo: not an allowed " "info level (0x%x) on IPC$.\n", (unsigned int)info_level)); - reply_nterror(req, NT_STATUS_ACCESS_DENIED); - return; - } - } - - if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) { - if (info_level != SMB_QUERY_CIFS_UNIX_INFO) { - DEBUG(0,("call_trans2qfsinfo: encryption required " - "and info level 0x%x sent.\n", - (unsigned int)info_level)); - exit_server_cleanly("encryption required " - "on connection"); - return; + return NT_STATUS_ACCESS_DENIED; } } - DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level)); - - if(vfs_stat_smb_fname(conn,".",&st)!=0) { - DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno))); - reply_doserror(req, ERRSRV, ERRinvdevice); - return; - } + DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level)); *ppdata = (char *)SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); - if (*ppdata == NULL ) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + if (*ppdata == NULL) { + return NT_STATUS_NO_MEMORY; } pdata = *ppdata; @@ -2760,8 +2730,7 @@ static void call_trans2qfsinfo(connection_struct *conn, uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 18; if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_nterror(req, map_nt_error_from_unix(errno)); - return; + return map_nt_error_from_unix(errno); } block_size = lp_block_size(snum); @@ -2780,7 +2749,7 @@ static void call_trans2qfsinfo(connection_struct *conn, bytes_per_sector = 512; sectors_per_unit = bsize/bytes_per_sector; - DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \ + DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit, (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree)); @@ -2806,13 +2775,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u * the pushed string. The change here was adding the STR_TERMINATE. JRA. */ len = srvstr_push( - pdata, req->flags2, + pdata, flags2, pdata+l2_vol_szVolLabel, vname, PTR_DIFF(end_data, pdata+l2_vol_szVolLabel), STR_NOALIGN|STR_TERMINATE); SCVAL(pdata,l2_vol_cch,len); data_len = l2_vol_szVolLabel + len; - DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n", + DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n", (unsigned)convert_timespec_to_time_t(st.st_ex_ctime), len, vname)); break; @@ -2839,7 +2808,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u SIVAL(pdata,4,255); /* Max filename component length */ /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it and will think we can't do long filenames */ - len = srvstr_push(pdata, req->flags2, pdata+12, fstype, + len = srvstr_push(pdata, flags2, pdata+12, fstype, PTR_DIFF(end_data, pdata+12), STR_UNICODE); SIVAL(pdata,8,len); @@ -2848,7 +2817,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u case SMB_QUERY_FS_LABEL_INFO: case SMB_FS_LABEL_INFORMATION: - len = srvstr_push(pdata, req->flags2, pdata+4, vname, + len = srvstr_push(pdata, flags2, pdata+4, vname, PTR_DIFF(end_data, pdata+4), 0); data_len = 4 + len; SIVAL(pdata,0,len); @@ -2865,13 +2834,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u (str_checksum(get_local_machine_name())<<16)); /* Max label len is 32 characters. */ - len = srvstr_push(pdata, req->flags2, pdata+18, vname, + len = srvstr_push(pdata, flags2, pdata+18, vname, PTR_DIFF(end_data, pdata+18), STR_UNICODE); SIVAL(pdata,12,len); data_len = 18+len; - DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", + DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", (int)strlen(vname),vname, lp_servicename(snum))); break; @@ -2881,8 +2850,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 24; if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_nterror(req, map_nt_error_from_unix(errno)); - return; + return map_nt_error_from_unix(errno); } block_size = lp_block_size(snum); if (bsize < block_size) { @@ -2899,7 +2867,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u } bytes_per_sector = 512; sectors_per_unit = bsize/bytes_per_sector; - DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \ + DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit, (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree)); SBIG_UINT(pdata,0,dsize); @@ -2914,8 +2882,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 32; if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) { - reply_nterror(req, map_nt_error_from_unix(errno)); - return; + return map_nt_error_from_unix(errno); } block_size = lp_block_size(snum); if (bsize < block_size) { @@ -2932,7 +2899,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned } bytes_per_sector = 512; sectors_per_unit = bsize/bytes_per_sector; - DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \ + DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit, (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree)); SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */ @@ -2990,19 +2957,18 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned "service [%s] user [%s]\n", lp_servicename(SNUM(conn)), conn->server_info->unix_name)); - reply_doserror(req, ERRDOS, ERRnoaccess); - return; + return NT_STATUS_DOS(ERRDOS, ERRnoaccess); } if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); - reply_doserror(req, ERRSRV, ERRerror); - return; + return NT_STATUS_DOS(ERRSRV, ERRerror); } data_len = 48; - DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn)))); + DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n", + lp_servicename(SNUM(conn)))); /* Unknown1 24 NULL bytes*/ SBIG_UINT(pdata,0,(uint64_t)0); @@ -3053,8 +3019,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int encrypt_caps = 0; if (!lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } switch (conn->encrypt_level) { @@ -3099,8 +3064,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned vfs_statvfs_struct svfs; if (!lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } rc = SMB_VFS_STATVFS(conn, ".", &svfs); @@ -3115,16 +3079,14 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned SBIG_UINT(pdata,32,svfs.TotalFileNodes); SBIG_UINT(pdata,40,svfs.FreeFileNodes); SBIG_UINT(pdata,48,svfs.FsIdentifier); - DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n")); + DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n")); #ifdef EOPNOTSUPP } else if (rc == EOPNOTSUPP) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; #endif /* EOPNOTSUPP */ } else { DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn)))); - reply_doserror(req, ERRSRV, ERRerror); - return; + return NT_STATUS_DOS(ERRSRV, ERRerror); } break; } @@ -3136,13 +3098,11 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int i; if (!lp_unix_extensions()) { - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + return NT_STATUS_INVALID_LEVEL; } if (max_data_bytes < 40) { - reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); - return; + return NT_STATUS_BUFFER_TOO_SMALL; } /* We ARE guest if global_sid_Builtin_Guests is @@ -3256,12 +3216,66 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned } /* drop through */ default: - reply_nterror(req, NT_STATUS_INVALID_LEVEL); + return NT_STATUS_INVALID_LEVEL; + } + + *ret_data_len = data_len; + return NT_STATUS_OK; +} + +/**************************************************************************** + Reply to a TRANS2_QFSINFO (query filesystem info). +****************************************************************************/ + +static void call_trans2qfsinfo(connection_struct *conn, + struct smb_request *req, + char **pparams, int total_params, + char **ppdata, int total_data, + unsigned int max_data_bytes) +{ + char *params = *pparams; + uint16_t info_level; + int data_len = 0; + SMB_STRUCT_STAT st; + NTSTATUS status; + + if (total_params < 2) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } + + info_level = SVAL(params,0); + + if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) { + if (info_level != SMB_QUERY_CIFS_UNIX_INFO) { + DEBUG(0,("call_trans2qfsinfo: encryption required " + "and info level 0x%x sent.\n", + (unsigned int)info_level)); + exit_server_cleanly("encryption required " + "on connection"); return; + } } + DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level)); + + if(vfs_stat_smb_fname(conn,".",&st)!=0) { + DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno))); + reply_doserror(req, ERRSRV, ERRinvdevice); + return; + } + + status = smbd_do_qfsinfo(conn, req, + info_level, st, + req->flags2, + max_data_bytes, + ppdata, &data_len); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; + } - send_trans2_replies(conn, req, params, 0, pdata, data_len, + send_trans2_replies(conn, req, params, 0, *ppdata, data_len, max_data_bytes); DEBUG( 4, ( "%s info_level = %d\n", -- cgit From ed99bf7317fccdb13e832e98f389486443f9fd48 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 12:05:34 +0200 Subject: s3:smbd: make smbd_do_qfsinfo() non static for use in SMB2 GetInfo metze --- source3/smbd/globals.h | 9 +++++++++ source3/smbd/trans2.c | 16 ++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'source3') diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 109c29a1ae..cd3e054d1a 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -210,6 +210,15 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, char **ppdata, int total_data, int *ret_data_size); +NTSTATUS smbd_do_qfsinfo(connection_struct *conn, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + SMB_STRUCT_STAT st, + uint16_t flags2, + unsigned int max_data_bytes, + char **ppdata, + int *ret_data_len); + void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn, const char *reason, const char *location); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 2ee3938aec..4dd0375067 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2687,14 +2687,14 @@ static void samba_extended_info_version(struct smb_extended_info *extended_info) "%s", samba_version_string()); } -static NTSTATUS smbd_do_qfsinfo(connection_struct *conn, - TALLOC_CTX *mem_ctx, - uint16_t info_level, - SMB_STRUCT_STAT st, - uint16_t flags2, - unsigned int max_data_bytes, - char **ppdata, - int *ret_data_len) +NTSTATUS smbd_do_qfsinfo(connection_struct *conn, + TALLOC_CTX *mem_ctx, + uint16_t info_level, + SMB_STRUCT_STAT st, + uint16_t flags2, + unsigned int max_data_bytes, + char **ppdata, + int *ret_data_len) { char *pdata, *end_data; int data_len = 0, len; -- cgit From 3ee3eb3acf5783894f358c415b342a88db248449 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 13:14:39 +0200 Subject: s3:smbd: close_file() handles named pipes just fine, no reason to return NOT_SUPPORTED metze --- source3/smbd/smb2_close.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3') diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c index 6724e5cc15..a46b36e2bb 100644 --- a/source3/smbd/smb2_close.c +++ b/source3/smbd/smb2_close.c @@ -107,11 +107,6 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req, return NT_STATUS_NO_MEMORY; } - /* If it's an IPC, pass off the pipe handler. */ - if (IS_IPC(conn)) { - return NT_STATUS_NOT_IMPLEMENTED; - } - fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile); if (fsp == NULL) { return NT_STATUS_FILE_CLOSED; -- cgit From 8db45607f8d19781d33ebff0d0b13c473f34009b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 12 Jun 2009 14:27:19 +0200 Subject: libds: share UF_ flags between samba3 and 4. Guenther --- source3/include/ads.h | 127 +------------------------------------------------- 1 file changed, 2 insertions(+), 125 deletions(-) (limited to 'source3') diff --git a/source3/include/ads.h b/source3/include/ads.h index afa4e12175..9761d54086 100644 --- a/source3/include/ads.h +++ b/source3/include/ads.h @@ -6,6 +6,8 @@ basically this is a wrapper around ldap */ +#include "../libds/common/flags.h" + enum wb_posix_mapping { WB_POSIX_MAP_UNKNOWN = -1, WB_POSIX_MAP_TEMPLATE = 0, @@ -202,124 +204,6 @@ typedef void **ADS_MODLIST; #define ADS_LDAP_MATCHING_RULE_BIT_AND "1.2.840.113556.1.4.803" #define ADS_LDAP_MATCHING_RULE_BIT_OR "1.2.840.113556.1.4.804" -/* UserFlags for userAccountControl */ -#define UF_SCRIPT 0x00000001 -#define UF_ACCOUNTDISABLE 0x00000002 -#define UF_UNUSED_1 0x00000004 -#define UF_HOMEDIR_REQUIRED 0x00000008 - -#define UF_LOCKOUT 0x00000010 -#define UF_PASSWD_NOTREQD 0x00000020 -#define UF_PASSWD_CANT_CHANGE 0x00000040 -#define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000080 - -#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100 -#define UF_NORMAL_ACCOUNT 0x00000200 -#define UF_UNUSED_2 0x00000400 -#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800 - -#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000 -#define UF_SERVER_TRUST_ACCOUNT 0x00002000 -#define UF_UNUSED_3 0x00004000 -#define UF_UNUSED_4 0x00008000 - -#define UF_DONT_EXPIRE_PASSWD 0x00010000 -#define UF_MNS_LOGON_ACCOUNT 0x00020000 -#define UF_SMARTCARD_REQUIRED 0x00040000 -#define UF_TRUSTED_FOR_DELEGATION 0x00080000 - -#define UF_NOT_DELEGATED 0x00100000 -#define UF_USE_DES_KEY_ONLY 0x00200000 -#define UF_DONT_REQUIRE_PREAUTH 0x00400000 -#define UF_PASSWORD_EXPIRED 0x00800000 - -#define UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 0x01000000 -#define UF_NO_AUTH_DATA_REQUIRED 0x02000000 -#define UF_UNUSED_8 0x04000000 -#define UF_UNUSED_9 0x08000000 - -#define UF_UNUSED_10 0x10000000 -#define UF_UNUSED_11 0x20000000 -#define UF_UNUSED_12 0x40000000 -#define UF_UNUSED_13 0x80000000 - -#define UF_MACHINE_ACCOUNT_MASK (\ - UF_INTERDOMAIN_TRUST_ACCOUNT |\ - UF_WORKSTATION_TRUST_ACCOUNT |\ - UF_SERVER_TRUST_ACCOUNT \ - ) - -#define UF_ACCOUNT_TYPE_MASK (\ - UF_TEMP_DUPLICATE_ACCOUNT |\ - UF_NORMAL_ACCOUNT |\ - UF_INTERDOMAIN_TRUST_ACCOUNT |\ - UF_WORKSTATION_TRUST_ACCOUNT |\ - UF_SERVER_TRUST_ACCOUNT \ - ) - -#define UF_SETTABLE_BITS (\ - UF_SCRIPT |\ - UF_ACCOUNTDISABLE |\ - UF_HOMEDIR_REQUIRED |\ - UF_LOCKOUT |\ - UF_PASSWD_NOTREQD |\ - UF_PASSWD_CANT_CHANGE |\ - UF_ACCOUNT_TYPE_MASK | \ - UF_DONT_EXPIRE_PASSWD | \ - UF_MNS_LOGON_ACCOUNT |\ - UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |\ - UF_SMARTCARD_REQUIRED |\ - UF_TRUSTED_FOR_DELEGATION |\ - UF_NOT_DELEGATED |\ - UF_USE_DES_KEY_ONLY |\ - UF_DONT_REQUIRE_PREAUTH \ - ) - -/* sAMAccountType */ -#define ATYPE_NORMAL_ACCOUNT 0x30000000 /* 805306368 */ -#define ATYPE_WORKSTATION_TRUST 0x30000001 /* 805306369 */ -#define ATYPE_INTERDOMAIN_TRUST 0x30000002 /* 805306370 */ -#define ATYPE_SECURITY_GLOBAL_GROUP 0x10000000 /* 268435456 */ -#define ATYPE_DISTRIBUTION_GLOBAL_GROUP 0x10000001 /* 268435457 */ -#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP ATYPE_DISTRIBUTION_GLOBAL_GROUP -#define ATYPE_SECURITY_LOCAL_GROUP 0x20000000 /* 536870912 */ -#define ATYPE_DISTRIBUTION_LOCAL_GROUP 0x20000001 /* 536870913 */ - -#define ATYPE_ACCOUNT ATYPE_NORMAL_ACCOUNT /* 0x30000000 805306368 */ -#define ATYPE_GLOBAL_GROUP ATYPE_SECURITY_GLOBAL_GROUP /* 0x10000000 268435456 */ -#define ATYPE_LOCAL_GROUP ATYPE_SECURITY_LOCAL_GROUP /* 0x20000000 536870912 */ - -/* groupType */ -#define GROUP_TYPE_BUILTIN_LOCAL_GROUP 0x00000001 -#define GROUP_TYPE_ACCOUNT_GROUP 0x00000002 -#define GROUP_TYPE_RESOURCE_GROUP 0x00000004 -#define GROUP_TYPE_UNIVERSAL_GROUP 0x00000008 -#define GROUP_TYPE_APP_BASIC_GROUP 0x00000010 -#define GROUP_TYPE_APP_QUERY_GROUP 0x00000020 -#define GROUP_TYPE_SECURITY_ENABLED 0x80000000 - -#define GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ( /* 0x80000005 -2147483643 */ \ - GROUP_TYPE_BUILTIN_LOCAL_GROUP| \ - GROUP_TYPE_RESOURCE_GROUP| \ - GROUP_TYPE_SECURITY_ENABLED \ - ) -#define GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ( /* 0x80000004 -2147483644 */ \ - GROUP_TYPE_RESOURCE_GROUP| \ - GROUP_TYPE_SECURITY_ENABLED \ - ) -#define GTYPE_SECURITY_GLOBAL_GROUP ( /* 0x80000002 -2147483646 */ \ - GROUP_TYPE_ACCOUNT_GROUP| \ - GROUP_TYPE_SECURITY_ENABLED \ - ) -#define GTYPE_SECURITY_UNIVERSAL_GROUP ( /* 0x80000008 -2147483656 */ \ - GROUP_TYPE_UNIVERSAL_GROUP| \ - GROUP_TYPE_SECURITY_ENABLED \ - ) - -#define GTYPE_DISTRIBUTION_GLOBAL_GROUP 0x00000002 /* 2 */ -#define GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP 0x00000004 /* 4 */ -#define GTYPE_DISTRIBUTION_UNIVERSAL_GROUP 0x00000008 /* 8 */ - #define ADS_PINGS 0x0000FFFF /* Ping response */ #define ADS_DNS_CONTROLLER 0x20000000 /* DomainControllerName is a DNS name*/ #define ADS_DNS_DOMAIN 0x40000000 /* DomainName is a DNS name */ @@ -411,11 +295,4 @@ typedef struct { #define ADS_IGNORE_PRINCIPAL "not_defined_in_RFC4178@please_ignore" -/* Settings for the domainFunctionality attribute in the rootDSE */ - -#define DS_DOMAIN_FUNCTION_2000 0 -#define DS_DOMAIN_FUCNTION_2003_MIXED 1 -#define DS_DOMAIN_FUNCTION_2003 2 -#define DS_DOMAIN_FUNCTION_2008 3 - #endif /* _INCLUDE_ADS_H_ */ -- cgit From 05fbe0c7f763fbe8c1c48eb82ebdfe04bfa034ea Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 12 Jun 2009 15:20:48 +0200 Subject: libds: merge the UF<->ACB flag mapping functions. Guenther --- source3/Makefile.in | 2 +- source3/include/proto.h | 16 +++-- source3/lib/ads_flags.c | 150 ---------------------------------------- source3/lib/netapi/user.c | 2 +- source3/passdb/pdb_ads.c | 6 +- source3/winbindd/winbindd_ads.c | 2 +- 6 files changed, 15 insertions(+), 163 deletions(-) delete mode 100644 source3/lib/ads_flags.c (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 4c927e7346..bc00f6a863 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -381,7 +381,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \ lib/interface.o lib/pidfile.o \ lib/system.o lib/sendfile.o lib/recvfile.o lib/time.o \ lib/username.o \ - lib/ads_flags.o \ + ../libds/common/flag_mapping.o \ lib/util_pw.o lib/access.o lib/smbrun.o \ lib/bitmap.o lib/dprintf.o $(UTIL_REG_OBJ) \ lib/wins_srv.o \ diff --git a/source3/include/proto.h b/source3/include/proto.h index 27b5f45eb0..44132b6519 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1678,13 +1678,6 @@ ADS_STRUCT *ads_init(const char *realm, const char *ldap_server); void ads_destroy(ADS_STRUCT **ads); -/* The following definitions come from libads/ads_utils.c */ - -uint32 ads_acb2uf(uint32 acb); -uint32 ads_uf2acb(uint32 uf); -uint32 ads_uf2atype(uint32 uf); -uint32 ads_gtype2atype(uint32 gtype); -enum lsa_SidType ads_atype_map(uint32 atype); const char *ads_get_ldap_server_name(ADS_STRUCT *ads); /* The following definitions come from libads/authdata.c */ @@ -7262,4 +7255,13 @@ NTSTATUS access_check_object( SEC_DESC *psd, NT_USER_TOKEN *token, const char *debug); void map_max_allowed_access(const NT_USER_TOKEN *token, uint32_t *pacc_requested); + +/* The following definitions come from ../libds/common/flag_mapping.c */ + +uint32_t ds_acb2uf(uint32_t acb); +uint32_t ds_uf2acb(uint32_t uf); +uint32_t ds_uf2atype(uint32_t uf); +uint32_t ds_gtype2atype(uint32_t gtype); +enum lsa_SidType ds_atype_map(uint32_t atype); + #endif /* _PROTO_H_ */ diff --git a/source3/lib/ads_flags.c b/source3/lib/ads_flags.c deleted file mode 100644 index a8fa062f2a..0000000000 --- a/source3/lib/ads_flags.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - Unix SMB/CIFS implementation. - ads (active directory) utility library - - Copyright (C) Stefan (metze) Metzmacher 2002 - Copyright (C) Andrew Tridgell 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -/* -translated the ACB_CTRL Flags to UserFlags (userAccountControl) -*/ -uint32 ads_acb2uf(uint32 acb) -{ - uint32 uf = 0x00000000; - - if (acb & ACB_DISABLED) uf |= UF_ACCOUNTDISABLE; - if (acb & ACB_HOMDIRREQ) uf |= UF_HOMEDIR_REQUIRED; - if (acb & ACB_PWNOTREQ) uf |= UF_PASSWD_NOTREQD; - if (acb & ACB_TEMPDUP) uf |= UF_TEMP_DUPLICATE_ACCOUNT; - if (acb & ACB_NORMAL) uf |= UF_NORMAL_ACCOUNT; - if (acb & ACB_MNS) uf |= UF_MNS_LOGON_ACCOUNT; - if (acb & ACB_DOMTRUST) uf |= UF_INTERDOMAIN_TRUST_ACCOUNT; - if (acb & ACB_WSTRUST) uf |= UF_WORKSTATION_TRUST_ACCOUNT; - if (acb & ACB_SVRTRUST) uf |= UF_SERVER_TRUST_ACCOUNT; - if (acb & ACB_PWNOEXP) uf |= UF_DONT_EXPIRE_PASSWD; - if (acb & ACB_AUTOLOCK) uf |= UF_LOCKOUT; - if (acb & ACB_USE_DES_KEY_ONLY) uf |= UF_USE_DES_KEY_ONLY; - if (acb & ACB_SMARTCARD_REQUIRED) uf |= UF_SMARTCARD_REQUIRED; - if (acb & ACB_TRUSTED_FOR_DELEGATION) uf |= UF_TRUSTED_FOR_DELEGATION; - if (acb & ACB_DONT_REQUIRE_PREAUTH) uf |= UF_DONT_REQUIRE_PREAUTH; - if (acb & ACB_NO_AUTH_DATA_REQD) uf |= UF_NO_AUTH_DATA_REQUIRED; - if (acb & ACB_NOT_DELEGATED) uf |= UF_NOT_DELEGATED; - if (acb & ACB_ENC_TXT_PWD_ALLOWED) uf |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED; - - return uf; -} - -/* -translated the UserFlags (userAccountControl) to ACB_CTRL Flags -*/ -uint32 ads_uf2acb(uint32 uf) -{ - uint32 acb = 0x00000000; - - if (uf & UF_ACCOUNTDISABLE) acb |= ACB_DISABLED; - if (uf & UF_HOMEDIR_REQUIRED) acb |= ACB_HOMDIRREQ; - if (uf & UF_PASSWD_NOTREQD) acb |= ACB_PWNOTREQ; - if (uf & UF_MNS_LOGON_ACCOUNT) acb |= ACB_MNS; - if (uf & UF_DONT_EXPIRE_PASSWD) acb |= ACB_PWNOEXP; - if (uf & UF_LOCKOUT) acb |= ACB_AUTOLOCK; - if (uf & UF_USE_DES_KEY_ONLY) acb |= ACB_USE_DES_KEY_ONLY; - if (uf & UF_SMARTCARD_REQUIRED) acb |= ACB_SMARTCARD_REQUIRED; - if (uf & UF_TRUSTED_FOR_DELEGATION) acb |= ACB_TRUSTED_FOR_DELEGATION; - if (uf & UF_DONT_REQUIRE_PREAUTH) acb |= ACB_DONT_REQUIRE_PREAUTH; - if (uf & UF_NO_AUTH_DATA_REQUIRED) acb |= ACB_NO_AUTH_DATA_REQD; - if (uf & UF_NOT_DELEGATED) acb |= ACB_NOT_DELEGATED; - if (uf & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED) acb |= ACB_ENC_TXT_PWD_ALLOWED; - - switch (uf & UF_ACCOUNT_TYPE_MASK) - { - case UF_TEMP_DUPLICATE_ACCOUNT: acb |= ACB_TEMPDUP;break; - case UF_NORMAL_ACCOUNT: acb |= ACB_NORMAL;break; - case UF_INTERDOMAIN_TRUST_ACCOUNT: acb |= ACB_DOMTRUST;break; - case UF_WORKSTATION_TRUST_ACCOUNT: acb |= ACB_WSTRUST;break; - case UF_SERVER_TRUST_ACCOUNT: acb |= ACB_SVRTRUST;break; - /*Fix Me: what should we do here? */ - default: acb |= ACB_NORMAL;break; - } - - return acb; -} - -/* -get the accountType from the UserFlags -*/ -uint32 ads_uf2atype(uint32 uf) -{ - uint32 atype = 0x00000000; - - if (uf & UF_NORMAL_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT; - else if (uf & UF_TEMP_DUPLICATE_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT; - else if (uf & UF_SERVER_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST; - else if (uf & UF_WORKSTATION_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST; - else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT) atype = ATYPE_INTERDOMAIN_TRUST; - - return atype; -} - -/* -get the accountType from the groupType -*/ -uint32 ads_gtype2atype(uint32 gtype) -{ - uint32 atype = 0x00000000; - - switch(gtype) { - case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP: - atype = ATYPE_SECURITY_LOCAL_GROUP; - break; - case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP: - atype = ATYPE_SECURITY_LOCAL_GROUP; - break; - case GTYPE_SECURITY_GLOBAL_GROUP: - atype = ATYPE_SECURITY_GLOBAL_GROUP; - break; - - case GTYPE_DISTRIBUTION_GLOBAL_GROUP: - atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP; - break; - case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP: - atype = ATYPE_DISTRIBUTION_UNIVERSAL_GROUP; - break; - case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP: - atype = ATYPE_DISTRIBUTION_LOCAL_GROUP; - break; - } - - return atype; -} - -/* turn a sAMAccountType into a SID_NAME_USE */ -enum lsa_SidType ads_atype_map(uint32 atype) -{ - switch (atype & 0xF0000000) { - case ATYPE_GLOBAL_GROUP: - return SID_NAME_DOM_GRP; - case ATYPE_SECURITY_LOCAL_GROUP: - return SID_NAME_ALIAS; - case ATYPE_ACCOUNT: - return SID_NAME_USER; - default: - DEBUG(1,("hmm, need to map account type 0x%x\n", atype)); - } - return SID_NAME_UNKNOWN; -} diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c index 39472b20d7..9fa3ddd9a8 100644 --- a/source3/lib/netapi/user.c +++ b/source3/lib/netapi/user.c @@ -770,7 +770,7 @@ static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb) { uint32_t fl = UF_SCRIPT; /* god knows why */ - fl |= ads_acb2uf(acb); + fl |= ds_acb2uf(acb); return fl; } diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c index ddfeb8ed80..4f7c210915 100644 --- a/source3/passdb/pdb_ads.c +++ b/source3/passdb/pdb_ads.c @@ -250,7 +250,7 @@ static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m, DEBUG(10, ("Could not pull userAccountControl\n")); goto fail; } - pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET); + pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET); if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) { if (blob.length != NT_HASH_LEN) { @@ -310,7 +310,7 @@ static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state, ret &= tldap_make_mod_fmt( existing, mem_ctx, pnum_mods, pmods, "userAccountControl", - "%d", ads_acb2uf(pdb_get_acct_ctrl(sam))); + "%d", ds_acb2uf(pdb_get_acct_ctrl(sam))); ret &= tldap_make_mod_fmt( existing, mem_ctx, pnum_mods, pmods, "homeDirectory", @@ -1682,7 +1682,7 @@ static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m, DEBUG(10, ("no samAccountType")); continue; } - lsa_attrs[i] = ads_atype_map(attr); + lsa_attrs[i] = ds_atype_map(attr); num_mapped += 1; } diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index edd70667c0..08afb46674 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -210,7 +210,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, gid_t primary_gid = (gid_t)-1; if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) || - ads_atype_map(atype) != SID_NAME_USER) { + ds_atype_map(atype) != SID_NAME_USER) { DEBUG(1,("Not a user account? atype=0x%x\n", atype)); continue; } -- cgit From f7ff6bd1425cc4f0aa13ce8e7498cdac3967acf3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 29 Jun 2009 20:34:03 +0200 Subject: s3-rpc_server: pass down full unix token to map_max_allowed_access(). Also use unix_token->uid instead of geteuid() when checking for mapping of the SEC_FLAG_MAXIMUM_ALLOWED flag. Guenther --- source3/include/proto.h | 5 +++-- source3/rpc_server/srv_lsa_nt.c | 8 ++++++-- source3/rpc_server/srv_samr_nt.c | 42 ++++++++++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 18 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 44132b6519..c0ce35a865 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -7253,8 +7253,9 @@ NTSTATUS access_check_object( SEC_DESC *psd, NT_USER_TOKEN *token, SE_PRIV *rights, uint32 rights_mask, uint32 des_access, uint32 *acc_granted, const char *debug); -void map_max_allowed_access(const NT_USER_TOKEN *token, - uint32_t *pacc_requested); +void map_max_allowed_access(const NT_USER_TOKEN *nt_token, + const struct unix_user_token *unix_token, + uint32_t *pacc_requested); /* The following definitions come from ../libds/common/flag_mapping.c */ diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 324483b3ee..c62991ee01 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -349,7 +349,9 @@ NTSTATUS _lsa_OpenPolicy2(pipes_struct *p, NTSTATUS status; /* Work out max allowed. */ - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); /* map the generic bits to the lsa policy ones */ se_map_generic(&des_access, &lsa_policy_mapping); @@ -1628,7 +1630,9 @@ NTSTATUS _lsa_OpenAccount(pipes_struct *p, * handle - so don't check against policy handle. */ /* Work out max allowed. */ - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); /* map the generic bits to the lsa account ones */ se_map_generic(&des_access, &lsa_account_mapping); diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 8560ee97c6..1085251421 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -236,8 +236,9 @@ done: Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set. ********************************************************************/ -void map_max_allowed_access(const NT_USER_TOKEN *token, - uint32_t *pacc_requested) +void map_max_allowed_access(const NT_USER_TOKEN *nt_token, + const struct unix_user_token *unix_token, + uint32_t *pacc_requested) { if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) { return; @@ -248,15 +249,15 @@ void map_max_allowed_access(const NT_USER_TOKEN *token, *pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS; /* root gets anything. */ - if (geteuid() == sec_initial_uid()) { + if (unix_token->uid == sec_initial_uid()) { *pacc_requested |= GENERIC_ALL_ACCESS; return; } /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */ - if (is_sid_in_token(token, &global_sid_Builtin_Administrators) || - is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) { + if (is_sid_in_token(nt_token, &global_sid_Builtin_Administrators) || + is_sid_in_token(nt_token, &global_sid_Builtin_Account_Operators)) { *pacc_requested |= GENERIC_ALL_ACCESS; return; } @@ -266,7 +267,7 @@ void map_max_allowed_access(const NT_USER_TOKEN *token, DOM_SID domadmin_sid; sid_copy( &domadmin_sid, get_global_sam_sid() ); sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS ); - if (is_sid_in_token(token, &domadmin_sid)) { + if (is_sid_in_token(nt_token, &domadmin_sid)) { *pacc_requested |= GENERIC_ALL_ACCESS; return; } @@ -550,7 +551,9 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p, } /*check if access can be granted as requested by client. */ - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 ); se_map_generic( &des_access, &dom_generic_mapping ); @@ -2260,8 +2263,9 @@ NTSTATUS _samr_OpenUser(pipes_struct *p, return NT_STATUS_NO_SUCH_USER; /* check if access can be granted as requested by client. */ - - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW); se_map_generic(&des_access, &usr_generic_mapping); @@ -3834,7 +3838,9 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p, sid_compose(&sid, get_global_sam_sid(), *r->out.rid); - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW); @@ -3914,7 +3920,9 @@ NTSTATUS _samr_Connect(pipes_struct *p, was observed from a win98 client trying to enumerate users (when configured user level access control on shares) --jerry */ - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); se_map_generic( &des_access, &sam_generic_mapping ); @@ -3974,7 +3982,9 @@ NTSTATUS _samr_Connect2(pipes_struct *p, return NT_STATUS_ACCESS_DENIED; } - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0); se_map_generic(&des_access, &sam_generic_mapping); @@ -4187,7 +4197,9 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p, /*check if access can be granted as requested by client. */ - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0); se_map_generic(&des_access,&ali_generic_mapping); @@ -6237,7 +6249,9 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p, } /*check if access can be granted as requested by client. */ - map_max_allowed_access(p->server_info->ptok, &des_access); + map_max_allowed_access(p->server_info->ptok, + &p->server_info->utok, + &des_access); make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0); se_map_generic(&des_access,&grp_generic_mapping); -- cgit From 8646b9521d267284a335aafba3df6039c41b8370 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 13:24:19 +0200 Subject: s3:net: Fix Bug #6222. Default to DRSUAPI replication for net rpc vampire keytab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit metze Signed-off-by: Günther Deschner --- source3/utils/net_rpc_samsync.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source3') diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index bd5047c1ff..c0de247e7f 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -493,17 +493,20 @@ int rpc_vampire_keytab(struct net_context *c, int argc, const char **argv) if (!dc_info.is_ad) { printf("DC is not running Active Directory\n"); - return -1; - } - - if (dc_info.is_mixed_mode) { ret = run_rpc_command(c, cli, &ndr_table_netlogon.syntax_id, 0, rpc_vampire_keytab_internals, argc, argv); + return -1; } else { ret = run_rpc_command(c, cli, &ndr_table_drsuapi.syntax_id, NET_FLAGS_SEAL, rpc_vampire_keytab_ds_internals, argc, argv); + if (ret != 0 && dc_info.is_mixed_mode) { + printf("Fallback to NT4 vampire on Mixed-Mode AD Domain\n"); + ret = run_rpc_command(c, cli, &ndr_table_netlogon.syntax_id, + 0, + rpc_vampire_keytab_internals, argc, argv); + } } return ret; -- cgit From e4fca7466d3bc064587638560572813e62df00d8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 13 Jul 2009 21:56:31 +0200 Subject: s3-pdb_ads: set correct pdb field with the value from 'accountExpires' attribute. Guenther --- source3/passdb/pdb_ads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c index 4f7c210915..66fdff181f 100644 --- a/source3/passdb/pdb_ads.c +++ b/source3/passdb/pdb_ads.c @@ -203,7 +203,7 @@ static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m, pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET); } if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) { - pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET); + pdb_set_kickoff_time(sam, tmp_time, PDB_SET); } str = tldap_talloc_single_attribute(entry, "displayName", -- cgit From b25e3b6c8a7a1dd31607dd344e6e767716dd645d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 13 Jul 2009 17:17:37 -0700 Subject: Fix set_posix_lock check which had been reversed in the recent changes. Jeremy. --- source3/smbd/trans2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 4dd0375067..a862c1466f 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -7277,7 +7277,7 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, case SMB_SET_POSIX_LOCK: { - if (fsp) { + if (!fsp) { return NT_STATUS_INVALID_LEVEL; } status = smb_set_posix_lock(conn, req, -- cgit From e67de63ba6c6de60400e7deb4664d259f6dfb638 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 13 Jul 2009 18:43:10 -0700 Subject: Make cli_posix_lock/unlock asynchronous. Jeremy. --- source3/client/client.c | 4 +- source3/include/proto.h | 21 +++- source3/libsmb/clifile.c | 273 ++++++++++++++++++++++++++++++++++++---------- source3/torture/torture.c | 12 ++ 4 files changed, 247 insertions(+), 63 deletions(-) (limited to 'source3') diff --git a/source3/client/client.c b/source3/client/client.c index ed45f4e2ca..6b273b47b0 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2605,7 +2605,7 @@ static int cmd_lock(void) len = (uint64_t)strtol(buf, (char **)NULL, 16); - if (!cli_posix_lock(cli, fnum, start, len, true, lock_type)) { + if (!NT_STATUS_IS_OK(cli_posix_lock(cli, fnum, start, len, true, lock_type))) { d_printf("lock failed %d: %s\n", fnum, cli_errstr(cli)); } @@ -2639,7 +2639,7 @@ static int cmd_unlock(void) len = (uint64_t)strtol(buf, (char **)NULL, 16); - if (!cli_posix_unlock(cli, fnum, start, len)) { + if (!NT_STATUS_IS_OK(cli_posix_unlock(cli, fnum, start, len))) { d_printf("unlock failed %d: %s\n", fnum, cli_errstr(cli)); } diff --git a/source3/include/proto.h b/source3/include/proto.h index c0ce35a865..7b3eaa0659 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2516,11 +2516,26 @@ bool cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t bool cli_lock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len, int timeout, enum brl_type lock_type); bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len); -bool cli_posix_lock(struct cli_state *cli, uint16_t fnum, +struct tevent_req *cli_posix_lock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len, + bool wait_lock, + enum brl_type lock_type); +NTSTATUS cli_posix_lock_recv(struct tevent_req *req); +NTSTATUS cli_posix_lock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len, bool wait_lock, enum brl_type lock_type); -bool cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len); -bool cli_posix_getlock(struct cli_state *cli, uint16_t fnum, uint64_t *poffset, uint64_t *plen); +struct tevent_req *cli_posix_unlock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len); +NTSTATUS cli_posix_unlock_recv(struct tevent_req *req); +NTSTATUS cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len); struct tevent_req *cli_getattrE_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index af67fcb746..0e2b3640f2 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -2857,103 +2857,260 @@ bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_ Get/unlock a POSIX lock on a file - internal function. ****************************************************************************/ -static bool cli_posix_lock_internal(struct cli_state *cli, uint16_t fnum, - uint64_t offset, uint64_t len, bool wait_lock, enum brl_type lock_type) +struct posix_lock_state { + uint16_t setup; + uint8_t param[4]; + uint8_t data[POSIX_LOCK_DATA_SIZE]; +}; + +static void cli_posix_unlock_internal_done(struct tevent_req *subreq) { - unsigned int param_len = 4; - unsigned int data_len = POSIX_LOCK_DATA_SIZE; - uint16_t setup = TRANSACT2_SETFILEINFO; - char param[4]; - unsigned char data[POSIX_LOCK_DATA_SIZE]; - char *rparam=NULL, *rdata=NULL; - int saved_timeout = cli->timeout; + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct posix_lock_state *state = tevent_req_data(req, struct posix_lock_state); + NTSTATUS status; - SSVAL(param,0,fnum); - SSVAL(param,2,SMB_SET_POSIX_LOCK); + status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + tevent_req_done(req); +} + +static struct tevent_req *cli_posix_lock_internal_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len, + bool wait_lock, + enum brl_type lock_type) +{ + struct tevent_req *req = NULL, *subreq = NULL; + struct posix_lock_state *state = NULL; + req = tevent_req_create(mem_ctx, &state, struct posix_lock_state); + if (req == NULL) { + return NULL; + } + + /* Setup setup word. */ + SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO); + + /* Setup param array. */ + SSVAL(&state->param, 0, fnum); + SSVAL(&state->param, 2, SMB_SET_POSIX_LOCK); + + /* Setup data array. */ switch (lock_type) { case READ_LOCK: - SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_READ); + SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET, + POSIX_LOCK_TYPE_READ); break; case WRITE_LOCK: - SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_WRITE); + SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET, + POSIX_LOCK_TYPE_WRITE); break; case UNLOCK_LOCK: - SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK); + SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET, + POSIX_LOCK_TYPE_UNLOCK); break; default: - return False; + return NULL; } if (wait_lock) { - SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_WAIT); - cli->timeout = 0x7FFFFFFF; + SSVAL(&state->data, POSIX_LOCK_FLAGS_OFFSET, + POSIX_LOCK_FLAG_WAIT); } else { - SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_NOWAIT); - } - - SIVAL(data, POSIX_LOCK_PID_OFFSET, cli->pid); - SOFF_T(data, POSIX_LOCK_START_OFFSET, offset); - SOFF_T(data, POSIX_LOCK_LEN_OFFSET, len); - - if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - (char *)&data, data_len, cli->max_xmit /* data, length, max */ - )) { - cli->timeout = saved_timeout; - return False; - } + SSVAL(state->data, POSIX_LOCK_FLAGS_OFFSET, + POSIX_LOCK_FLAG_NOWAIT); + } + + SIVAL(&state->data, POSIX_LOCK_PID_OFFSET, cli->pid); + SOFF_T(&state->data, POSIX_LOCK_START_OFFSET, offset); + SOFF_T(&state->data, POSIX_LOCK_LEN_OFFSET, len); + + subreq = cli_trans_send(state, /* mem ctx. */ + ev, /* event ctx. */ + cli, /* cli_state. */ + SMBtrans2, /* cmd. */ + NULL, /* pipe name. */ + -1, /* fid. */ + 0, /* function. */ + 0, /* flags. */ + &state->setup, /* setup. */ + 1, /* num setup uint16_t words. */ + 0, /* max returned setup. */ + state->param, /* param. */ + 4, /* num param. */ + 2, /* max returned param. */ + state->data, /* data. */ + POSIX_LOCK_DATA_SIZE, /* num data. */ + 0); /* max returned data. */ - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - cli->timeout = saved_timeout; - SAFE_FREE(rdata); - SAFE_FREE(rparam); - return False; + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); } - - cli->timeout = saved_timeout; - - SAFE_FREE(rdata); - SAFE_FREE(rparam); - - return True; + tevent_req_set_callback(subreq, cli_posix_unlock_internal_done, req); + return req; } /**************************************************************************** POSIX Lock a file. ****************************************************************************/ -bool cli_posix_lock(struct cli_state *cli, uint16_t fnum, +struct tevent_req *cli_posix_lock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len, + bool wait_lock, + enum brl_type lock_type) +{ + return cli_posix_lock_internal_send(mem_ctx, ev, cli, fnum, offset, len, + wait_lock, lock_type); +} + +NTSTATUS cli_posix_lock_recv(struct tevent_req *req) +{ + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + return NT_STATUS_OK; +} + +NTSTATUS cli_posix_lock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len, bool wait_lock, enum brl_type lock_type) { + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + if (lock_type != READ_LOCK && lock_type != WRITE_LOCK) { - return False; + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_posix_lock_send(frame, + ev, + cli, + fnum, + offset, + len, + wait_lock, + lock_type); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; } - return cli_posix_lock_internal(cli, fnum, offset, len, wait_lock, lock_type); + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_posix_lock_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** POSIX Unlock a file. ****************************************************************************/ -bool cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len) +struct tevent_req *cli_posix_unlock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len) { - return cli_posix_lock_internal(cli, fnum, offset, len, False, UNLOCK_LOCK); + return cli_posix_lock_internal_send(mem_ctx, ev, cli, fnum, offset, len, + false, UNLOCK_LOCK); } -/**************************************************************************** - POSIX Get any lock covering a file. -****************************************************************************/ +NTSTATUS cli_posix_unlock_recv(struct tevent_req *req) +{ + NTSTATUS status; -bool cli_posix_getlock(struct cli_state *cli, uint16_t fnum, uint64_t *poffset, uint64_t *plen) + if (tevent_req_is_nterror(req, &status)) { + return status; + } + return NT_STATUS_OK; +} + +NTSTATUS cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len) { - return True; + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_posix_unlock_send(frame, + ev, + cli, + fnum, + offset, + len); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_posix_unlock_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 8e38093e33..8cebc2adcc 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -4295,6 +4295,18 @@ static bool run_simple_posix_open_test(int dummy) goto out; } + /* Do a POSIX lock/unlock. */ + if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, WRITE_LOCK))) { + printf("POSIX lock failed\n"); + goto out; + } + + /* Punch a hole in the locked area. */ + if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) { + printf("POSIX unlock failed\n"); + goto out; + } + cli_close(cli1, fnum1); /* Open the symlink for read - this should fail. A POSIX -- cgit From bd58a1461724eb92c9fedd014edb7465f5a16b40 Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Thu, 9 Jul 2009 14:45:23 +0200 Subject: reject ACLs with DESC_DACL_PROTECTED on GPFS as GPFS does not support the ACE4_FLAG_NO_PROPAGATE NFSv4 flag (which would be the mapping for the DESC_DACL_PROTECTED flag), the status of this flag is currently silently ignored by Samba. That means that if you deselect the "Allow inheritable permissions..." checkbox in Windows' ACL dialog and then apply the ACL, the flag will be back immediately. To make sure that automatic migration with e.g. robocopy does not lead to ACLs silently (and unintentionally) changed, this patch adds an explicit check for this flag and if set, it will return NT_STATUS_NOT_SUPPORTED so errors are shown up on the Windows side and the Administrator is aware of the ACLs not being settable like intended Signed-off-by: Christian Ambach --- source3/modules/vfs_gpfs.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 47858cb352..ffa8db00b3 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -445,6 +445,11 @@ static NTSTATUS gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_i if (acl->acl_version&GPFS_ACL_VERSION_NFS4) { + if ((psd->type&SEC_DESC_DACL_PROTECTED)) { + DEBUG(2, ("Rejecting unsupported ACL with DACL_PROTECTED bit set\n")); + return NT_STATUS_NOT_SUPPORTED; + } + result = smb_set_nt_acl_nfs4( fsp, security_info_sent, psd, gpfsacl_process_smbacl); -- cgit From 39fa9468c6b8099429b971d75c0647033b60901c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 13 Jul 2009 23:42:57 +0200 Subject: s3-account_policy: remove trailing whitespace. Guenther --- source3/lib/account_pol.c | 64 +++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'source3') diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c index 1e435ca53e..4b63375e29 100644 --- a/source3/lib/account_pol.c +++ b/source3/lib/account_pol.c @@ -1,20 +1,20 @@ -/* +/* * Unix SMB/CIFS implementation. * account policy storage * Copyright (C) Jean François Micouleau 1998-2001. * Copyright (C) Andrew Bartlett 2002 * Copyright (C) Guenther Deschner 2004-2005 - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ @@ -39,51 +39,51 @@ struct ap_table { }; static const struct ap_table account_policy_names[] = { - {AP_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH, - "Minimal password length (default: 5)", + {AP_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH, + "Minimal password length (default: 5)", "sambaMinPwdLength" }, {AP_PASSWORD_HISTORY, "password history", 0, - "Length of Password History Entries (default: 0 => off)", + "Length of Password History Entries (default: 0 => off)", "sambaPwdHistoryLength" }, - + {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0, "Force Users to logon for password change (default: 0 => off, 2 => on)", "sambaLogonToChgPwd" }, - + {AP_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1, - "Maximum password age, in seconds (default: -1 => never expire passwords)", + "Maximum password age, in seconds (default: -1 => never expire passwords)", "sambaMaxPwdAge" }, - + {AP_MIN_PASSWORD_AGE,"minimum password age", 0, - "Minimal password age, in seconds (default: 0 => allow immediate password change)", + "Minimal password age, in seconds (default: 0 => allow immediate password change)", "sambaMinPwdAge" }, - + {AP_LOCK_ACCOUNT_DURATION, "lockout duration", 30, "Lockout duration in minutes (default: 30, -1 => forever)", "sambaLockoutDuration" }, - + {AP_RESET_COUNT_TIME, "reset count minutes", 30, - "Reset time after lockout in minutes (default: 30)", + "Reset time after lockout in minutes (default: 30)", "sambaLockoutObservationWindow" }, - + {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0, - "Lockout users after bad logon attempts (default: 0 => off)", + "Lockout users after bad logon attempts (default: 0 => off)", "sambaLockoutThreshold" }, - + {AP_TIME_TO_LOGOUT, "disconnect time", (uint32) -1, - "Disconnect Users outside logon hours (default: -1 => off, 0 => on)", - "sambaForceLogoff" }, - + "Disconnect Users outside logon hours (default: -1 => off, 0 => on)", + "sambaForceLogoff" }, + {AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0, "Allow Machine Password changes (default: 0 => off)", "sambaRefuseMachinePwdChange" }, - + {0, NULL, 0, "", NULL} }; void account_policy_names_list(const char ***names, int *num_names) -{ +{ const char **nl; int i, count; @@ -175,7 +175,7 @@ bool account_policy_get_default(int account_policy, uint32 *val) return True; } } - DEBUG(0,("no default for account_policy index %d found. This should never happen\n", + DEBUG(0,("no default for account_policy index %d found. This should never happen\n", account_policy)); return False; } @@ -189,7 +189,7 @@ static bool account_policy_set_default_on_empty(int account_policy) uint32 value; - if (!account_policy_get(account_policy, &value) && + if (!account_policy_get(account_policy, &value) && !account_policy_get_default(account_policy, &value)) { return False; } @@ -299,7 +299,7 @@ bool init_account_policy(void) } /***************************************************************************** -Get an account policy (from tdb) +Get an account policy (from tdb) *****************************************************************************/ bool account_policy_get(int field, uint32 *value) @@ -320,12 +320,12 @@ bool account_policy_get(int field, uint32 *value) DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", field)); return False; } - + if (!dbwrap_fetch_uint32(db, name, ®val)) { DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for field %d (%s), returning 0\n", field, name)); return False; } - + if (value) { *value = regval; } @@ -336,7 +336,7 @@ bool account_policy_get(int field, uint32 *value) /**************************************************************************** -Set an account policy (in tdb) +Set an account policy (in tdb) ****************************************************************************/ bool account_policy_set(int field, uint32 value) @@ -362,12 +362,12 @@ bool account_policy_set(int field, uint32 value) } DEBUG(10,("account_policy_set: name: %s, value: %d\n", name, value)); - + return True; } /**************************************************************************** -Set an account policy in the cache +Set an account policy in the cache ****************************************************************************/ bool cache_account_policy_set(int field, uint32 value) @@ -404,7 +404,7 @@ bool cache_account_policy_set(int field, uint32 value) } /***************************************************************************** -Get an account policy from the cache +Get an account policy from the cache *****************************************************************************/ bool cache_account_policy_get(int field, uint32 *value) -- cgit From 9f15ef11bdf75dbc1a1af3c2bc35b1d653216f62 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 13 Jul 2009 23:53:49 +0200 Subject: s3-account_policy: add pdb_policy_type enum. Guenther --- source3/include/passdb.h | 22 ++++++- source3/include/proto.h | 22 +++---- source3/include/smb.h | 14 ---- source3/lib/account_pol.c | 88 +++++++++++++------------- source3/libnet/libnet_samsync_passdb.c | 23 ++++--- source3/passdb/passdb.c | 16 ++--- source3/passdb/pdb_ads.c | 10 +-- source3/passdb/pdb_get_set.c | 6 +- source3/passdb/pdb_interface.c | 16 ++--- source3/passdb/pdb_ldap.c | 40 ++++++------ source3/registry/reg_backend_netlogon_params.c | 2 +- source3/rpc_server/srv_samr_nt.c | 62 +++++++++--------- source3/rpc_server/srv_samr_util.c | 2 +- source3/smbd/chgpasswd.c | 6 +- source3/torture/pdbtest.c | 6 +- source3/winbindd/winbindd_passdb.c | 10 +-- 16 files changed, 179 insertions(+), 166 deletions(-) (limited to 'source3') diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 4e53311eba..2b4f9c2e43 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -205,6 +205,22 @@ struct pdb_domain_info { struct GUID guid; }; +/* + * Types of account policy. + */ +enum pdb_policy_type { + PDB_POLICY_MIN_PASSWORD_LEN = 1, + PDB_POLICY_PASSWORD_HISTORY = 2, + PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS = 3, + PDB_POLICY_MAX_PASSWORD_AGE = 4, + PDB_POLICY_MIN_PASSWORD_AGE = 5, + PDB_POLICY_LOCK_ACCOUNT_DURATION = 6, + PDB_POLICY_RESET_COUNT_TIME = 7, + PDB_POLICY_BAD_ATTEMPT_LOCKOUT = 8, + PDB_POLICY_TIME_TO_LOGOUT = 9, + PDB_POLICY_REFUSE_MACHINE_PW_CHANGE = 10 +}; + #define PDB_CAP_STORE_RIDS 0x0001 #define PDB_CAP_ADS 0x0002 @@ -351,10 +367,12 @@ struct pdb_methods enum lsa_SidType *attrs); NTSTATUS (*get_account_policy)(struct pdb_methods *methods, - int policy_index, uint32 *value); + enum pdb_policy_type type, + uint32_t *value); NTSTATUS (*set_account_policy)(struct pdb_methods *methods, - int policy_index, uint32 value); + enum pdb_policy_type type, + uint32_t value); NTSTATUS (*get_seq_num)(struct pdb_methods *methods, time_t *seq_num); diff --git a/source3/include/proto.h b/source3/include/proto.h index 7b3eaa0659..0dd1e98c86 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -290,16 +290,16 @@ bool check_access(int sock, const char **allow_list, const char **deny_list); /* The following definitions come from lib/account_pol.c */ void account_policy_names_list(const char ***names, int *num_names); -const char *decode_account_policy_name(int field); -const char *get_account_policy_attr(int field); -const char *account_policy_get_desc(int field); -int account_policy_name_to_fieldnum(const char *name); -bool account_policy_get_default(int account_policy, uint32 *val); +const char *decode_account_policy_name(enum pdb_policy_type type); +const char *get_account_policy_attr(enum pdb_policy_type type); +const char *account_policy_get_desc(enum pdb_policy_type type); +enum pdb_policy_type account_policy_name_to_typenum(const char *name); +bool account_policy_get_default(enum pdb_policy_type type, uint32_t *val); bool init_account_policy(void); -bool account_policy_get(int field, uint32 *value); -bool account_policy_set(int field, uint32 value); -bool cache_account_policy_set(int field, uint32 value); -bool cache_account_policy_get(int field, uint32 *value); +bool account_policy_get(enum pdb_policy_type type, uint32_t *value); +bool account_policy_set(enum pdb_policy_type type, uint32_t value); +bool cache_account_policy_set(enum pdb_policy_type type, uint32_t value); +bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value); struct db_context *get_account_pol_db( void ); /* The following definitions come from lib/adt_tree.c */ @@ -4595,8 +4595,8 @@ NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid, const char **names, uint32 *rids, enum lsa_SidType *attrs); -bool pdb_get_account_policy(int policy_index, uint32 *value); -bool pdb_set_account_policy(int policy_index, uint32 value); +bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value); +bool pdb_set_account_policy(enum pdb_policy_type type, uint32_t value); bool pdb_get_seq_num(time_t *seq_num); bool pdb_uid_to_rid(uid_t uid, uint32 *rid); bool pdb_uid_to_sid(uid_t uid, DOM_SID *sid); diff --git a/source3/include/smb.h b/source3/include/smb.h index 9afeb67b00..2e9cf1b54a 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -833,20 +833,6 @@ struct pipe_open_rec { #define PW_HISTORY_ENTRY_LEN (PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN) #define MAX_PW_HISTORY_LEN 24 -/* - * Flags for account policy. - */ -#define AP_MIN_PASSWORD_LEN 1 -#define AP_PASSWORD_HISTORY 2 -#define AP_USER_MUST_LOGON_TO_CHG_PASS 3 -#define AP_MAX_PASSWORD_AGE 4 -#define AP_MIN_PASSWORD_AGE 5 -#define AP_LOCK_ACCOUNT_DURATION 6 -#define AP_RESET_COUNT_TIME 7 -#define AP_BAD_ATTEMPT_LOCKOUT 8 -#define AP_TIME_TO_LOGOUT 9 -#define AP_REFUSE_MACHINE_PW_CHANGE 10 - /* * Flags for local user manipulation. */ diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c index 4b63375e29..f4101e96bc 100644 --- a/source3/lib/account_pol.c +++ b/source3/lib/account_pol.c @@ -31,7 +31,7 @@ static struct db_context *db; struct ap_table { - int field; + enum pdb_policy_type type; const char *string; uint32 default_val; const char *description; @@ -39,43 +39,43 @@ struct ap_table { }; static const struct ap_table account_policy_names[] = { - {AP_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH, + {PDB_POLICY_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH, "Minimal password length (default: 5)", "sambaMinPwdLength" }, - {AP_PASSWORD_HISTORY, "password history", 0, + {PDB_POLICY_PASSWORD_HISTORY, "password history", 0, "Length of Password History Entries (default: 0 => off)", "sambaPwdHistoryLength" }, - {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0, + {PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0, "Force Users to logon for password change (default: 0 => off, 2 => on)", "sambaLogonToChgPwd" }, - {AP_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1, + {PDB_POLICY_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1, "Maximum password age, in seconds (default: -1 => never expire passwords)", "sambaMaxPwdAge" }, - {AP_MIN_PASSWORD_AGE,"minimum password age", 0, + {PDB_POLICY_MIN_PASSWORD_AGE,"minimum password age", 0, "Minimal password age, in seconds (default: 0 => allow immediate password change)", "sambaMinPwdAge" }, - {AP_LOCK_ACCOUNT_DURATION, "lockout duration", 30, + {PDB_POLICY_LOCK_ACCOUNT_DURATION, "lockout duration", 30, "Lockout duration in minutes (default: 30, -1 => forever)", "sambaLockoutDuration" }, - {AP_RESET_COUNT_TIME, "reset count minutes", 30, + {PDB_POLICY_RESET_COUNT_TIME, "reset count minutes", 30, "Reset time after lockout in minutes (default: 30)", "sambaLockoutObservationWindow" }, - {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0, + {PDB_POLICY_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0, "Lockout users after bad logon attempts (default: 0 => off)", "sambaLockoutThreshold" }, - {AP_TIME_TO_LOGOUT, "disconnect time", (uint32) -1, + {PDB_POLICY_TIME_TO_LOGOUT, "disconnect time", (uint32) -1, "Disconnect Users outside logon hours (default: -1 => off, 0 => on)", "sambaForceLogoff" }, - {AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0, + {PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0, "Allow Machine Password changes (default: 0 => off)", "sambaRefuseMachinePwdChange" }, @@ -106,11 +106,11 @@ void account_policy_names_list(const char ***names, int *num_names) Get the account policy name as a string from its #define'ed number ****************************************************************************/ -const char *decode_account_policy_name(int field) +const char *decode_account_policy_name(enum pdb_policy_type type) { int i; for (i=0; account_policy_names[i].string; i++) { - if (field == account_policy_names[i].field) { + if (type == account_policy_names[i].type) { return account_policy_names[i].string; } } @@ -121,11 +121,11 @@ const char *decode_account_policy_name(int field) Get the account policy LDAP attribute as a string from its #define'ed number ****************************************************************************/ -const char *get_account_policy_attr(int field) +const char *get_account_policy_attr(enum pdb_policy_type type) { int i; - for (i=0; account_policy_names[i].field; i++) { - if (field == account_policy_names[i].field) { + for (i=0; account_policy_names[i].type; i++) { + if (type == account_policy_names[i].type) { return account_policy_names[i].ldap_attr; } } @@ -136,11 +136,11 @@ const char *get_account_policy_attr(int field) Get the account policy description as a string from its #define'ed number ****************************************************************************/ -const char *account_policy_get_desc(int field) +const char *account_policy_get_desc(enum pdb_policy_type type) { int i; for (i=0; account_policy_names[i].string; i++) { - if (field == account_policy_names[i].field) { + if (type == account_policy_names[i].type) { return account_policy_names[i].description; } } @@ -151,12 +151,12 @@ const char *account_policy_get_desc(int field) Get the account policy name as a string from its #define'ed number ****************************************************************************/ -int account_policy_name_to_fieldnum(const char *name) +enum pdb_policy_type account_policy_name_to_typenum(const char *name) { int i; for (i=0; account_policy_names[i].string; i++) { if (strcmp(name, account_policy_names[i].string) == 0) { - return account_policy_names[i].field; + return account_policy_names[i].type; } } return 0; @@ -166,35 +166,35 @@ int account_policy_name_to_fieldnum(const char *name) Get default value for account policy *****************************************************************************/ -bool account_policy_get_default(int account_policy, uint32 *val) +bool account_policy_get_default(enum pdb_policy_type type, uint32_t *val) { int i; - for (i=0; account_policy_names[i].field; i++) { - if (account_policy_names[i].field == account_policy) { + for (i=0; account_policy_names[i].type; i++) { + if (account_policy_names[i].type == type) { *val = account_policy_names[i].default_val; return True; } } DEBUG(0,("no default for account_policy index %d found. This should never happen\n", - account_policy)); + type)); return False; } /***************************************************************************** - Set default for a field if it is empty + Set default for a type if it is empty *****************************************************************************/ -static bool account_policy_set_default_on_empty(int account_policy) +static bool account_policy_set_default_on_empty(enum pdb_policy_type type) { uint32 value; - if (!account_policy_get(account_policy, &value) && - !account_policy_get_default(account_policy, &value)) { + if (!account_policy_get(type, &value) && + !account_policy_get_default(type, &value)) { return False; } - return account_policy_set(account_policy, value); + return account_policy_set(type, value); } /***************************************************************************** @@ -255,9 +255,9 @@ bool init_account_policy(void) goto cancel; } - for (i=0; account_policy_names[i].field; i++) { + for (i=0; account_policy_names[i].type; i++) { - if (!account_policy_set_default_on_empty(account_policy_names[i].field)) { + if (!account_policy_set_default_on_empty(account_policy_names[i].type)) { DEBUG(0,("failed to set default value in account policy tdb\n")); goto cancel; } @@ -302,7 +302,7 @@ bool init_account_policy(void) Get an account policy (from tdb) *****************************************************************************/ -bool account_policy_get(int field, uint32 *value) +bool account_policy_get(enum pdb_policy_type type, uint32_t *value) { const char *name; uint32 regval; @@ -315,14 +315,14 @@ bool account_policy_get(int field, uint32 *value) *value = 0; } - name = decode_account_policy_name(field); + name = decode_account_policy_name(type); if (name == NULL) { - DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", field)); + DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", type)); return False; } if (!dbwrap_fetch_uint32(db, name, ®val)) { - DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for field %d (%s), returning 0\n", field, name)); + DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for type %d (%s), returning 0\n", type, name)); return False; } @@ -339,7 +339,7 @@ bool account_policy_get(int field, uint32 *value) Set an account policy (in tdb) ****************************************************************************/ -bool account_policy_set(int field, uint32 value) +bool account_policy_set(enum pdb_policy_type type, uint32_t value) { const char *name; NTSTATUS status; @@ -348,16 +348,16 @@ bool account_policy_set(int field, uint32 value) return False; } - name = decode_account_policy_name(field); + name = decode_account_policy_name(type); if (name == NULL) { - DEBUG(1, ("Field %d is not a valid account policy type! Cannot set.\n", field)); + DEBUG(1, ("Field %d is not a valid account policy type! Cannot set.\n", type)); return False; } status = dbwrap_trans_store_uint32(db, name, value); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("store_uint32 failed for field %d (%s) on value " - "%u: %s\n", field, name, value, nt_errstr(status))); + DEBUG(1, ("store_uint32 failed for type %d (%s) on value " + "%u: %s\n", type, name, value, nt_errstr(status))); return False; } @@ -370,14 +370,14 @@ bool account_policy_set(int field, uint32 value) Set an account policy in the cache ****************************************************************************/ -bool cache_account_policy_set(int field, uint32 value) +bool cache_account_policy_set(enum pdb_policy_type type, uint32_t value) { const char *policy_name = NULL; char *cache_key = NULL; char *cache_value = NULL; bool ret = False; - policy_name = decode_account_policy_name(field); + policy_name = decode_account_policy_name(type); if (policy_name == NULL) { DEBUG(0,("cache_account_policy_set: no policy found\n")); return False; @@ -407,14 +407,14 @@ bool cache_account_policy_set(int field, uint32 value) Get an account policy from the cache *****************************************************************************/ -bool cache_account_policy_get(int field, uint32 *value) +bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value) { const char *policy_name = NULL; char *cache_key = NULL; char *cache_value = NULL; bool ret = False; - policy_name = decode_account_policy_name(field); + policy_name = decode_account_policy_name(type); if (policy_name == NULL) { DEBUG(0,("cache_account_policy_set: no policy found\n")); return False; diff --git a/source3/libnet/libnet_samsync_passdb.c b/source3/libnet/libnet_samsync_passdb.c index 27c7aac7e7..41a9b3d9f3 100644 --- a/source3/libnet/libnet_samsync_passdb.c +++ b/source3/libnet/libnet_samsync_passdb.c @@ -676,21 +676,24 @@ static NTSTATUS fetch_domain_info(TALLOC_CTX *mem_ctx, } - if (!pdb_set_account_policy(AP_PASSWORD_HISTORY, + if (!pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY, r->password_history_length)) return nt_status; - if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN, + if (!pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, r->min_password_length)) return nt_status; - if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (uint32)u_max_age)) + if (!pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, + (uint32)u_max_age)) return nt_status; - if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (uint32)u_min_age)) + if (!pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, + (uint32)u_min_age)) return nt_status; - if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT, (uint32)u_logout)) + if (!pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, + (uint32)u_logout)) return nt_status; if (lockstr) { @@ -699,21 +702,23 @@ static NTSTATUS fetch_domain_info(TALLOC_CTX *mem_ctx, u_lockoutreset = uint64s_nt_time_to_unix_abs(&lockstr->reset_count); u_lockouttime = uint64s_nt_time_to_unix_abs((uint64_t *)&lockstr->lockout_duration); - if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, + if (!pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, lockstr->bad_attempt_lockout)) return nt_status; - if (!pdb_set_account_policy(AP_RESET_COUNT_TIME, (uint32_t)u_lockoutreset/60)) + if (!pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, + (uint32_t)u_lockoutreset/60)) return nt_status; if (u_lockouttime != -1) u_lockouttime /= 60; - if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (uint32_t)u_lockouttime)) + if (!pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, + (uint32_t)u_lockouttime)) return nt_status; } - if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + if (!pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, r->logon_to_chgpass)) return nt_status; diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 4ed04e4e7a..0678181669 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -1439,7 +1439,7 @@ static bool init_samu_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 bu } /* Change from V1 is addition of password history field. */ - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); if (pwHistLen) { uint8 *pw_hist = SMB_MALLOC_ARRAY(uint8, pwHistLen * PW_HISTORY_ENTRY_LEN); if (!pw_hist) { @@ -1674,7 +1674,7 @@ static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 bu } } - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); if (pwHistLen) { uint8 *pw_hist = (uint8 *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN); if (!pw_hist) { @@ -1879,7 +1879,7 @@ static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool nt_pw_len = 0; } - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len); if (pwHistLen && nt_pw_hist && nt_pw_hist_len) { nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN; @@ -2085,7 +2085,7 @@ bool pdb_copy_sam_account(struct samu *dst, struct samu *src ) } /********************************************************************* - Update the bad password count checking the AP_RESET_COUNT_TIME + Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME *********************************************************************/ bool pdb_update_bad_password_count(struct samu *sampass, bool *updated) @@ -2102,7 +2102,7 @@ bool pdb_update_bad_password_count(struct samu *sampass, bool *updated) } become_root(); - res = pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime); + res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime); unbecome_root(); if (!res) { @@ -2131,7 +2131,7 @@ bool pdb_update_bad_password_count(struct samu *sampass, bool *updated) } /********************************************************************* - Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION + Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION *********************************************************************/ bool pdb_update_autolock_flag(struct samu *sampass, bool *updated) @@ -2147,7 +2147,7 @@ bool pdb_update_autolock_flag(struct samu *sampass, bool *updated) } become_root(); - res = pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration); + res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration); unbecome_root(); if (!res) { @@ -2199,7 +2199,7 @@ bool pdb_increment_bad_password_count(struct samu *sampass) /* Retrieve the account lockout policy */ become_root(); - ret = pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout); + ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout); unbecome_root(); if ( !ret ) { DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n")); diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c index 66fdff181f..70d550042b 100644 --- a/source3/passdb/pdb_ads.c +++ b/source3/passdb/pdb_ads.c @@ -1706,16 +1706,18 @@ static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m, } static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m, - int policy_index, uint32 *value) + enum pdb_policy_type type, + uint32_t *value) { - return account_policy_get(policy_index, value) + return account_policy_get(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m, - int policy_index, uint32 value) + enum pdb_policy_type type, + uint32_t value) { - return account_policy_set(policy_index, value) + return account_policy_set(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index f55b77f675..30775e49fe 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -88,7 +88,7 @@ time_t pdb_get_pass_can_change_time(const struct samu *sampass) pdb_get_init_flags(sampass, PDB_CANCHANGETIME) == PDB_CHANGED) return sampass->pass_can_change_time; - if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &allow)) + if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &allow)) allow = 0; /* in normal cases, just calculate it from policy */ @@ -112,7 +112,7 @@ time_t pdb_get_pass_must_change_time(const struct samu *sampass) if (sampass->acct_ctrl & ACB_PWNOEXP) return get_time_t_max(); - if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire) + if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire) || expire == (uint32)-1 || expire == 0) return get_time_t_max(); @@ -1013,7 +1013,7 @@ bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext) if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) { uchar *pwhistory; uint32 pwHistLen; - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); if (pwHistLen != 0){ uint32 current_history_len; /* We need to make sure we don't have a race condition here - the diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 465a6bf595..5d0b625da5 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -994,25 +994,25 @@ NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid, } #endif -bool pdb_get_account_policy(int policy_index, uint32 *value) +bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value) { struct pdb_methods *pdb = pdb_get_methods(); NTSTATUS status; become_root(); - status = pdb->get_account_policy(pdb, policy_index, value); + status = pdb->get_account_policy(pdb, type, value); unbecome_root(); return NT_STATUS_IS_OK(status); } -bool pdb_set_account_policy(int policy_index, uint32 value) +bool pdb_set_account_policy(enum pdb_policy_type type, uint32_t value) { struct pdb_methods *pdb = pdb_get_methods(); NTSTATUS status; become_root(); - status = pdb->set_account_policy(pdb, policy_index, value); + status = pdb->set_account_policy(pdb, type, value); unbecome_root(); return NT_STATUS_IS_OK(status); @@ -1174,14 +1174,14 @@ static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, return NT_STATUS_OK; } -static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value) +static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value) { - return account_policy_get(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; + return account_policy_get(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } -static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value) +static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value) { - return account_policy_set(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; + return account_policy_set(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } static NTSTATUS pdb_default_get_seq_num(struct pdb_methods *methods, time_t *seq_num) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 173298561f..11554a76ac 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -902,7 +902,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state, pwHistLen = 0; - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); if (pwHistLen > 0){ uint8 *pwhist = NULL; int i; @@ -1327,7 +1327,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state, if (need_update(sampass, PDB_PWHISTORY)) { char *pwstr = NULL; uint32 pwHistLen = 0; - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); pwstr = SMB_MALLOC_ARRAY(char, 1024); if (!pwstr) { @@ -1404,7 +1404,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state, uint16 badcount = pdb_get_bad_password_count(sampass); time_t badtime = pdb_get_bad_password_time(sampass); uint32 pol; - pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &pol); + pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &pol); DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n", (unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime)); @@ -3762,7 +3762,7 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods, } static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, - int policy_index, + enum pdb_policy_type type, uint32 value) { NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL; @@ -3780,7 +3780,7 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, return NT_STATUS_INVALID_PARAMETER; } - policy_attr = get_account_policy_attr(policy_index); + policy_attr = get_account_policy_attr(type); if (policy_attr == NULL) { DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid " "policy\n")); @@ -3800,7 +3800,7 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, return ntstatus; } - if (!cache_account_policy_set(policy_index, value)) { + if (!cache_account_policy_set(type, value)) { DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to " "update local tdb cache\n")); return ntstatus; @@ -3810,14 +3810,15 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, } static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods, - int policy_index, uint32 value) + enum pdb_policy_type type, + uint32_t value) { - return ldapsam_set_account_policy_in_ldap(methods, policy_index, + return ldapsam_set_account_policy_in_ldap(methods, type, value); } static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods, - int policy_index, + enum pdb_policy_type type, uint32 *value) { NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL; @@ -3839,10 +3840,10 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods return NT_STATUS_INVALID_PARAMETER; } - policy_attr = get_account_policy_attr(policy_index); + policy_attr = get_account_policy_attr(type); if (!policy_attr) { DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid " - "policy index: %d\n", policy_index)); + "policy index: %d\n", type)); return ntstatus; } @@ -3896,17 +3897,18 @@ out: Guenther */ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, - int policy_index, uint32 *value) + enum pdb_policy_type type, + uint32_t *value) { NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL; - if (cache_account_policy_get(policy_index, value)) { + if (cache_account_policy_get(type, value)) { DEBUG(11,("ldapsam_get_account_policy: got valid value from " "cache\n")); return NT_STATUS_OK; } - ntstatus = ldapsam_get_account_policy_from_ldap(methods, policy_index, + ntstatus = ldapsam_get_account_policy_from_ldap(methods, type, value); if (NT_STATUS_IS_OK(ntstatus)) { goto update_cache; @@ -3917,27 +3919,27 @@ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, #if 0 /* should we automagically migrate old tdb value here ? */ - if (account_policy_get(policy_index, value)) + if (account_policy_get(type, value)) goto update_ldap; DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying " - "default\n", policy_index)); + "default\n", type)); #endif - if (!account_policy_get_default(policy_index, value)) { + if (!account_policy_get_default(type, value)) { return ntstatus; } /* update_ldap: */ - ntstatus = ldapsam_set_account_policy(methods, policy_index, *value); + ntstatus = ldapsam_set_account_policy(methods, type, *value); if (!NT_STATUS_IS_OK(ntstatus)) { return ntstatus; } update_cache: - if (!cache_account_policy_set(policy_index, *value)) { + if (!cache_account_policy_set(type, *value)) { DEBUG(0,("ldapsam_get_account_policy: failed to update local " "tdb as a cache\n")); return NT_STATUS_UNSUCCESSFUL; diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c index 682c7fe9a5..6fc87efb1d 100644 --- a/source3/registry/reg_backend_netlogon_params.c +++ b/source3/registry/reg_backend_netlogon_params.c @@ -35,7 +35,7 @@ static int netlogon_params_fetch_values(const char *key, struct regval_ctr *regv { uint32 dwValue; - if (!pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue)) { + if (!pdb_get_account_policy(PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, &dwValue)) { dwValue = 0; } diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 1085251421..b27603f261 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -639,9 +639,9 @@ NTSTATUS _samr_GetUserPwInfo(pipes_struct *p, switch (sid_type) { case SID_NAME_USER: become_root(); - pdb_get_account_policy(AP_MIN_PASSWORD_LEN, + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &min_password_length); - pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, &password_properties); unbecome_root(); @@ -2079,19 +2079,19 @@ NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p, /* AS ROOT !!! */ - pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp); + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp); dominfo->min_password_length = tmp; - pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp); dominfo->password_history_length = tmp; - pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, &dominfo->password_properties); - pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp); u_expire = account_policy_temp; - pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp); u_min_age = account_policy_temp; /* !AS ROOT */ @@ -3305,19 +3305,19 @@ static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx, /* AS ROOT !!! */ - pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp); r->min_password_length = account_policy_temp; - pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp); r->password_history_length = account_policy_temp; - pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, &r->password_properties); - pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp); u_expire = account_policy_temp; - pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp); u_min_age = account_policy_temp; /* !AS ROOT */ @@ -3352,7 +3352,7 @@ static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx, r->num_groups = count_sam_groups(dinfo->disp_info); r->num_aliases = count_sam_aliases(dinfo->disp_info); - pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout); + pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout); unix_to_nt_time_abs(&r->force_logoff_time, u_logout); @@ -3389,7 +3389,7 @@ static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx, { uint32_t ul; - pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul); + pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul); u_logout = (time_t)ul; } @@ -3506,16 +3506,16 @@ static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx, become_root(); - pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp); u_lock_duration = account_policy_temp; if (u_lock_duration != -1) { u_lock_duration *= 60; } - pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp); u_reset_time = account_policy_temp * 60; - pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp); r->lockout_threshold = account_policy_temp; /* !AS ROOT */ @@ -3541,16 +3541,16 @@ static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx, /* AS ROOT !!! */ - pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp); u_lock_duration = account_policy_temp; if (u_lock_duration != -1) { u_lock_duration *= 60; } - pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp); u_reset_time = account_policy_temp * 60; - pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp); + pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp); r->lockout_threshold = account_policy_temp; /* !AS ROOT */ @@ -6205,9 +6205,9 @@ NTSTATUS _samr_GetDomPwInfo(pipes_struct *p, } become_root(); - pdb_get_account_policy(AP_MIN_PASSWORD_LEN, + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &min_password_length); - pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, &password_properties); unbecome_root(); @@ -6376,14 +6376,14 @@ static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx, u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age); u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age); - pdb_set_account_policy(AP_MIN_PASSWORD_LEN, + pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, (uint32_t)r->min_password_length); - pdb_set_account_policy(AP_PASSWORD_HISTORY, + pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY, (uint32_t)r->password_history_length); - pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, (uint32_t)r->password_properties); - pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire); - pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age); + pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire); + pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age); return NT_STATUS_OK; } @@ -6398,7 +6398,7 @@ static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx, u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time); - pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout); + pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout); return NT_STATUS_OK; } @@ -6418,9 +6418,9 @@ static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx, u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60; - pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration); - pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time); - pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, + pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration); + pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time); + pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, (uint32_t)r->lockout_threshold); return NT_STATUS_OK; diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c index 69daa31e9c..1e5988af33 100644 --- a/source3/rpc_server/srv_samr_util.c +++ b/source3/rpc_server/srv_samr_util.c @@ -619,7 +619,7 @@ void copy_id21_to_sam_passwd(const char *log_prefix, uint32_t pwd_max_age = 0; time_t now = time(NULL); - pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &pwd_max_age); + pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &pwd_max_age); if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) { pwd_max_age = get_time_t_max(); diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 2eb09d176d..64f988f1f7 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -1024,7 +1024,7 @@ static bool check_passwd_history(struct samu *sampass, const char *plaintext) int i; uint32 pwHisLen, curr_pwHisLen; - pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHisLen); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHisLen); if (pwHisLen == 0) { return False; } @@ -1107,7 +1107,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw * denies machines to change the password. * * Should we deny also SRVTRUST and/or DOMSTRUST ? .SSS. */ if (pdb_get_acct_ctrl(hnd) & ACB_WSTRUST) { - if (pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &refuse) && refuse) { + if (pdb_get_account_policy(PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, &refuse) && refuse) { DEBUG(1, ("Machine %s cannot change password now, " "denied by Refuse Machine Password Change policy\n", username)); @@ -1130,7 +1130,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw return NT_STATUS_ACCOUNT_RESTRICTION; } - if (pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) { + if (pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) { DEBUG(1, ("user %s cannot change password - password too short\n", username)); DEBUGADD(1, (" account policy min password len = %d\n", min_len)); diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c index ab7edde85d..950177c3ca 100644 --- a/source3/torture/pdbtest.c +++ b/source3/torture/pdbtest.c @@ -288,7 +288,7 @@ int main(int argc, char **argv) pdb_set_homedir(out, "\\\\torture\\home", PDB_SET); pdb_set_logon_script(out, "torture_script.cmd", PDB_SET); - pdb_get_account_policy(AP_PASSWORD_HISTORY, &history); + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &history); if (history * PW_HISTORY_ENTRY_LEN < NT_HASH_LEN) { buf = (uint8 *)TALLOC(ctx, NT_HASH_LEN); } else { @@ -311,8 +311,8 @@ int main(int argc, char **argv) } pdb_set_pw_history(out, buf, history, PDB_SET); - pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire); - pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &min_age); + pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire); + pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &min_age); pdb_set_pass_last_set_time(out, time(NULL), PDB_SET); if (expire == 0 || expire == (uint32)-1) { diff --git a/source3/winbindd/winbindd_passdb.c b/source3/winbindd/winbindd_passdb.c index b18f0ff595..9a43c6d6a2 100644 --- a/source3/winbindd/winbindd_passdb.c +++ b/source3/winbindd/winbindd_passdb.c @@ -332,29 +332,29 @@ static NTSTATUS password_policy(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - if (!pdb_get_account_policy(AP_MIN_PASSWORD_LEN, + if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp)) { return NT_STATUS_ACCESS_DENIED; } p->min_password_length = account_policy_temp; - if (!pdb_get_account_policy(AP_PASSWORD_HISTORY, + if (!pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp)) { return NT_STATUS_ACCESS_DENIED; } p->password_history_length = account_policy_temp; - if (!pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + if (!pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, &p->password_properties)) { return NT_STATUS_ACCESS_DENIED; } - if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp)) { + if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp)) { return NT_STATUS_ACCESS_DENIED; } u_expire = account_policy_temp; - if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp)) { + if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp)) { return NT_STATUS_ACCESS_DENIED; } u_min_age = account_policy_temp; -- cgit From d9c0d5823624d302c6fa635d2e44aab985fd307c Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Tue, 14 Jul 2009 17:40:21 +0200 Subject: s3: don't make same innetgr check twice --- source3/smbd/password.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'source3') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 928ef0169e..58824b6e23 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -428,16 +428,16 @@ bool user_in_netgroup(struct smbd_server_connection *sconn, if (innetgr(ngname, NULL, user, sconn->smb1.sessions.my_yp_domain)) { DEBUG(5,("user_in_netgroup: Found\n")); return true; - } else { - - /* - * Ok, innetgr is case sensitive. Try once more with lowercase - * just in case. Attempt to fix #703. JRA. - */ + } - fstrcpy(lowercase_user, user); - strlower_m(lowercase_user); + /* + * Ok, innetgr is case sensitive. Try once more with lowercase + * just in case. Attempt to fix #703. JRA. + */ + fstrcpy(lowercase_user, user); + strlower_m(lowercase_user); + if (strcmp(user,lowercase_user) != 0) { DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", lowercase_user, sconn->smb1.sessions.my_yp_domain? @@ -449,6 +449,9 @@ bool user_in_netgroup(struct smbd_server_connection *sconn, DEBUG(5,("user_in_netgroup: Found\n")); return true; } + } else { + /* user name was already lower case! */ + return false; } #endif /* HAVE_NETGROUP */ return false; -- cgit From 99c7ee3c9145b6187113ff29500b55a32320a9bc Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Tue, 14 Jul 2009 17:55:50 +0200 Subject: s3: make d9c0d58236 better readble and reduce indentation --- source3/smbd/password.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source3') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 58824b6e23..b1a749736d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -437,22 +437,22 @@ bool user_in_netgroup(struct smbd_server_connection *sconn, fstrcpy(lowercase_user, user); strlower_m(lowercase_user); - if (strcmp(user,lowercase_user) != 0) { - DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", - lowercase_user, - sconn->smb1.sessions.my_yp_domain? - sconn->smb1.sessions.my_yp_domain:"(ANY)", - ngname)); - - if (innetgr(ngname, NULL, lowercase_user, - sconn->smb1.sessions.my_yp_domain)) { - DEBUG(5,("user_in_netgroup: Found\n")); - return true; - } - } else { + if (strcmp(user,lowercase_user) == 0) { /* user name was already lower case! */ return false; } + + DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", + lowercase_user, + sconn->smb1.sessions.my_yp_domain? + sconn->smb1.sessions.my_yp_domain:"(ANY)", + ngname)); + + if (innetgr(ngname, NULL, lowercase_user, + sconn->smb1.sessions.my_yp_domain)) { + DEBUG(5,("user_in_netgroup: Found\n")); + return true; + } #endif /* HAVE_NETGROUP */ return false; } -- cgit From 9ef6af73b319048fc6f3891573f0e10066dffee6 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Wed, 15 Jul 2009 15:34:10 +0800 Subject: s3: Make smbd aware of permission change of usershare. Since usershare are relatively volatile and non-previledge users must disconnect from smbd and reconnect to it to make share permission in effect. --- source3/include/proto.h | 7 +++- source3/include/smb.h | 6 +++ source3/param/loadparm.c | 11 +++++ source3/smbd/conn.c | 1 + source3/smbd/notify_inotify.c | 4 +- source3/smbd/process.c | 58 +++++++++++++++++++++++++- source3/smbd/service.c | 80 ++++++++++++++++++++++++++++++++++++ source3/smbd/uid.c | 96 ++++++++++++++++++++++++++++++++----------- 8 files changed, 235 insertions(+), 28 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 0dd1e98c86..d141de44cf 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4296,6 +4296,7 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx, char **pp_comment, SEC_DESC **ppsd, bool *pallow_guest); +bool am_usershare(int iService); int load_usershare_service(const char *servicename); int load_usershare_shares(void); void gfree_loadparm(void); @@ -7063,7 +7064,8 @@ void reply_transs2(struct smb_request *req); bool change_to_guest(void); void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid); -bool change_to_user(connection_struct *conn, uint16 vuid); +bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, + bool recheck, NTSTATUS *pstatus); bool change_to_root_user(void); bool become_authenticated_pipe_user(pipes_struct *p); bool unbecome_authenticated_pipe_user(void); @@ -7072,6 +7074,9 @@ void unbecome_root(void); bool become_user(connection_struct *conn, uint16 vuid); bool unbecome_user(void); +#define change_to_user(conn, vuid) \ + change_to_user_force_recheck(conn, vuid, 0, NULL) + /* The following definitions come from smbd/utmp.c */ void sys_utmp_claim(const char *username, const char *hostname, diff --git a/source3/include/smb.h b/source3/include/smb.h index 2e9cf1b54a..44216f856a 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -550,6 +550,7 @@ typedef struct connection_struct { unsigned cnum; /* an index passed over the wire */ struct share_params *params; bool force_user; + bool force_recheck_perm; struct vuid_cache vuid_cache; struct dptr_struct *dirptr; bool printer; @@ -1398,6 +1399,11 @@ struct bitmap { #define FILE_NOTIFY_CHANGE_STREAM_NAME 0x00000200 #define FILE_NOTIFY_CHANGE_STREAM_SIZE 0x00000400 #define FILE_NOTIFY_CHANGE_STREAM_WRITE 0x00000800 +#define FILE_NOTIFY_CHANGE_FILE_CONTENT \ + (FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME \ + | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE \ + | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_EA \ + | FILE_NOTIFY_CHANGE_SECURITY) #define FILE_NOTIFY_CHANGE_NAME \ (FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 7e4371bf0b..7b4e363f1b 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -8726,6 +8726,17 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i return iService; } +/*************************************************************************** +Am I a usershare service? +***************************************************************************/ +bool am_usershare(int iService) +{ + if (iService >= 0) { + return (ServicePtrs[iService]->usershare == USERSHARE_VALID); + } + return false; +} + /*************************************************************************** Checks if a usershare entry has been modified since last load. ***************************************************************************/ diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index af6e0919a4..3ddb4c094f 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -155,6 +155,7 @@ find_again: return NULL; } conn->cnum = i; + conn->force_recheck_perm = false; conn->force_group_gid = (gid_t)-1; bitmap_set(sconn->smb1.tcons.bmap, i); diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c index 26570a2216..b6be69c8fd 100644 --- a/source3/smbd/notify_inotify.c +++ b/source3/smbd/notify_inotify.c @@ -316,7 +316,9 @@ static const struct { {FILE_NOTIFY_CHANGE_LAST_WRITE, IN_ATTRIB}, {FILE_NOTIFY_CHANGE_LAST_ACCESS, IN_ATTRIB}, {FILE_NOTIFY_CHANGE_EA, IN_ATTRIB}, - {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB} + {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB}, + {FILE_NOTIFY_CHANGE_FILE_CONTENT, IN_MODIFY|IN_DELETE|IN_CREATE|IN_DELETE_SELF + |IN_MOVE_SELF|IN_MOVED_FROM|IN_MOVED_TO}, }; static uint32_t inotify_map(struct notify_entry *e) diff --git a/source3/smbd/process.c b/source3/smbd/process.c index b26bc150db..5b8a325d22 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -1286,7 +1286,6 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in } } } - /* Does this call need to be run as the connected user? */ if (flags & AS_USER) { @@ -1303,12 +1302,67 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in } return NULL; } - +#ifdef HAVE_INOTIFY + if (conn->force_recheck_perm) { + int old; + int iService = -1; + const char *service = NULL; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + conn->force_recheck_perm = false; + DEBUG(5, ("switch_message: rechecking permission for connection %x\n", + (unsigned int)conn)); + old = SNUM(conn); + service = lp_servicename(old); + conn->read_only = False; + if (lp_snum_ok(old) && am_usershare(old)) { + iService = load_usershare_service(service); + if (iService < 0 || old != iService) { + /* non-exist service */ + DEBUG(5, ("switch_message: deleting connection %x\n", + (unsigned int)conn)); + DEBUG(5, ("snum %d, sname %s\n", + old, service ? service : "NULL")); + delete_share_security(service); + set_current_service(NULL, 0, True); + close_cnum(smbd_server_conn, conn, conn->vuid); + lp_killservice(old); + reply_nterror(req, NT_STATUS_BAD_NETWORK_NAME); + return NULL; + } + + /* + * Don't have to reauthentication here, but + * need to check share permissions..... + * the vuid cache is a problem.. + */ + + if (!change_to_root_user()) { + smb_panic("cann't change to root user!\n"); + } + + if (!change_to_user_force_recheck(conn, session_tag, + True, &status)) { + reply_nterror(req, status); + remove_deferred_open_smb_message(req->mid); + return conn; + } + } + } else { + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + if (!change_to_user_force_recheck(conn, session_tag, + False, &status)) { + reply_nterror(req, status); + remove_deferred_open_smb_message(req->mid); + return conn; + } + } +#else if (!change_to_user(conn,session_tag)) { reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid)); remove_deferred_open_smb_message(req->mid); return conn; } +#endif /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */ diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 0124b2b047..8ae13b14f3 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -630,6 +630,33 @@ static NTSTATUS create_connection_server_info(struct smbd_server_connection *sco return NT_STATUS_ACCESS_DENIED; } +#ifdef HAVE_INOTIFY +static void share_perm_changed(struct sys_notify_context *ctx, + void *ptr, struct notify_event *ev) +{ + connection_struct *conn = talloc_get_type_abort(ptr, connection_struct); + const char *service = NULL; + service = lp_servicename(SNUM(conn)); + if (strequal(ev->path, service)) { + conn->force_recheck_perm = true; + DEBUG(0, ("share_perm_changed: set recheck flag for connection %x\n", + (unsigned int)conn)); + } +} + +struct notify_context { + struct db_context *db_recursive; + struct db_context *db_onelevel; + struct server_id server; + struct messaging_context *messaging_ctx; + struct notify_list *list; + struct notify_array *array; + int seqnum; + struct sys_notify_context *sys_notify_ctx; + TDB_DATA key; +}; +#endif + /**************************************************************************** Make a connection, given the snum to connect to, and the vuser of the @@ -867,11 +894,64 @@ connection_struct *make_connection_snum(struct smbd_server_connection *sconn, } if ((!conn->printer) && (!conn->ipc)) { +#ifdef HAVE_INOTIFY + struct sys_notify_context *sys_ctx = NULL; + struct notify_entry e; + struct inotify_watch_context *w = NULL; +#endif conn->notify_ctx = notify_init(conn, server_id_self(), smbd_messaging_context(), smbd_event_context(), conn); +#ifdef HAVE_INOTIFY + /* + * here is the start of monitoring share permissions change. + * For usershares, we have to watch on both + * get_dyn_STATDIR()/servicename and get_dyn_STATDIR()/share_info.tdb. + * For shares in smb.conf, we just watch on + * get_dyn_STATDIR()/share_info.tdb + */ + if (!conn->notify_ctx) { + DEBUG(1, ("change notify is not enabled??\n")); + goto nonotify; + } + sys_ctx = conn->notify_ctx->sys_notify_ctx; + if (!sys_ctx) { + DEBUG(1, ("change notify: out of memory!!\n")); + *pstatus = NT_STATUS_NO_MEMORY; + conn_free(sconn, conn); + return NULL; + } + ZERO_STRUCT(e); + if (am_usershare(SNUM(conn))) { + const char *usershare_path = lp_usershare_path(); + /* This is usershare service. */ + e.path = talloc_strdup(conn, usershare_path); + } else { + goto nonotify; + /* watch normal shares' permission? */ + } + if (!e.path) { + DEBUG(1, ("setting up usershare notify: out of memory!\n")); + *pstatus = status; + conn_free(sconn, conn); + return NULL; + } + e.path_len = strlen(e.path); + e.filter = FILE_NOTIFY_CHANGE_FILE_CONTENT; + status = inotify_watch(sys_ctx, &e, share_perm_changed, + (void *)conn, (void *)&w); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(1, ("add inotify for usershare permission failed!\n")); + *pstatus = status; + conn_free(sconn, conn); + return NULL; + } +#endif } +#ifdef HAVE_INOTIFY +nonotify: +#endif /* ROOT Activities: */ /* diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 2ec50cd4d8..8e5a386a2d 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -82,12 +82,17 @@ static void free_conn_server_info_if_unused(connection_struct *conn) static bool check_user_ok(connection_struct *conn, uint16_t vuid, const struct auth_serversupplied_info *server_info, - int snum) + int snum, bool recheck, NTSTATUS *pstatus) { bool valid_vuid = (vuid != UID_FIELD_INVALID); unsigned int i; bool readonly_share; bool admin_user; + struct vuid_cache_entry *ent0; + + if (pstatus) { + *pstatus = NT_STATUS_OK; + } if (valid_vuid) { struct vuid_cache_entry *ent; @@ -96,18 +101,27 @@ static bool check_user_ok(connection_struct *conn, ent = &conn->vuid_cache.array[i]; if (ent->vuid == vuid) { free_conn_server_info_if_unused(conn); - conn->server_info = ent->server_info; - conn->read_only = ent->read_only; - conn->admin_user = ent->admin_user; - return(True); + ent0 = ent; + if (!recheck) { + conn->server_info = ent->server_info; + conn->read_only = ent->read_only; + conn->admin_user = ent->admin_user; + return(True); + } else { + break; + } } } } if (!user_ok_token(server_info->unix_name, pdb_get_domain(server_info->sam_account), - server_info->ptok, snum)) + server_info->ptok, snum)) { + if (pstatus) { + *pstatus = NT_STATUS_ACCESS_DENIED; + } return(False); + } readonly_share = is_share_read_only_for_token( server_info->unix_name, @@ -128,6 +142,9 @@ static bool check_user_ok(connection_struct *conn, if (!share_access_check(server_info->ptok, lp_servicename(snum), readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { + if (pstatus) { + *pstatus = NT_STATUS_ACCESS_DENIED; + } return False; } @@ -137,13 +154,26 @@ static bool check_user_ok(connection_struct *conn, NULL, server_info->ptok, lp_admin_users(snum)); if (valid_vuid) { - struct vuid_cache_entry *ent = - &conn->vuid_cache.array[conn->vuid_cache.next_entry]; + struct vuid_cache_entry *ent = NULL; + + if (!recheck || i == VUID_CACHE_SIZE) { + /* find a new entry and fill it. */ + ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry]; - conn->vuid_cache.next_entry = - (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE; + conn->vuid_cache.next_entry = + (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE; - TALLOC_FREE(ent->server_info); + TALLOC_FREE(ent->server_info); + } else if (recheck && (i < VUID_CACHE_SIZE) && (ent0->vuid == vuid)) { + /* she perform forced recheck, replace the old one. */ + ent = ent0; + } else { + /* must not happen */ + DEBUG(0, ("check_user_ok: recheck %s\n", recheck ? "true" : "false")); + DEBUG(0, ("check_user_ok: vuid cache %d -- %d\n", i, VUID_CACHE_SIZE)); + DEBUG(0, ("check_user_ok: vuid %d -- %d\n", ent0->vuid, vuid)); + smb_panic("should not happen"); + } /* * If force_user was set, all server_info's are based on the same @@ -155,6 +185,9 @@ static bool check_user_ok(connection_struct *conn, if (ent->server_info == NULL) { ent->vuid = UID_FIELD_INVALID; + if (pstatus) { + *pstatus = NT_STATUS_NO_MEMORY; + } return false; } @@ -221,7 +254,8 @@ void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid) stack, but modify the current_user entries. ****************************************************************************/ -bool change_to_user(connection_struct *conn, uint16 vuid) +bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, + bool recheck, NTSTATUS *pstatus) { const struct auth_serversupplied_info *server_info = NULL; struct smbd_server_connection *sconn = smbd_server_conn; @@ -235,6 +269,9 @@ bool change_to_user(connection_struct *conn, uint16 vuid) if (!conn) { DEBUG(2,("change_to_user: Connection not open\n")); + if (pstatus) { + *pstatus = NT_STATUS_INVALID_HANDLE; + } return(False); } @@ -245,17 +282,19 @@ bool change_to_user(connection_struct *conn, uint16 vuid) * SMB's - this hurts performance - Badly. */ - if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && - (current_user.ut.uid == conn->server_info->utok.uid)) { - DEBUG(4,("change_to_user: Skipping user change - already " - "user\n")); - return(True); - } else if ((current_user.conn == conn) && - (vuser != NULL) && (current_user.vuid == vuid) && - (current_user.ut.uid == vuser->server_info->utok.uid)) { - DEBUG(4,("change_to_user: Skipping user change - already " - "user\n")); - return(True); + if (!recheck) { + if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && + (current_user.ut.uid == conn->server_info->utok.uid)) { + DEBUG(4,("change_to_user: Skipping user change - already " + "user\n")); + return(True); + } else if ((current_user.conn == conn) && + (vuser != NULL) && (current_user.vuid == vuid) && + (current_user.ut.uid == vuser->server_info->utok.uid)) { + DEBUG(4,("change_to_user: Skipping user change - already " + "user\n")); + return(True); + } } snum = SNUM(conn); @@ -266,10 +305,13 @@ bool change_to_user(connection_struct *conn, uint16 vuid) /* Invalid vuid sent - even with security = share. */ DEBUG(2,("change_to_user: Invalid vuid %d used on " "share %s.\n",vuid, lp_servicename(snum) )); + if (pstatus) { + *pstatus = NT_STATUS_ACCESS_VIOLATION; + } return false; } - if (!check_user_ok(conn, vuid, server_info, snum)) { + if (!check_user_ok(conn, vuid, server_info, snum, recheck, pstatus)) { DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) " "not permitted access to share %s.\n", server_info->sanitized_username, @@ -296,6 +338,9 @@ bool change_to_user(connection_struct *conn, uint16 vuid) } else { DEBUG(2,("change_to_user: Invalid vuid used %d in accessing " "share %s.\n",vuid, lp_servicename(snum) )); + if (pstatus) { + *pstatus = NT_STATUS_DOS(ERRSRV, ERRbaduid); + } return False; } @@ -353,6 +398,9 @@ bool change_to_user(connection_struct *conn, uint16 vuid) DEBUG(5,("change_to_user uid=(%d,%d) gid=(%d,%d)\n", (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); + if (pstatus) { + *pstatus = NT_STATUS_OK; + } return(True); } -- cgit From 86865365ce487a8943370ea2f313000a6440ea9a Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Wed, 15 Jul 2009 15:36:02 +0800 Subject: S3: Small fix to get rid of annoying log message. Signed-off-by: Bo Yang --- source3/param/loadparm.c | 3 +++ source3/rpc_server/srv_srvsvc_nt.c | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 7b4e363f1b..4415804a2d 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -5142,6 +5142,9 @@ static char *lp_string(const char *s) #if 0 DEBUG(10, ("lp_string(%s)\n", s)); #endif + if (!s) { + return NULL; + } ret = talloc_sub_basic(ctx, get_current_username(), diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 44acf4d647..c58c08ecdc 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -540,11 +540,13 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p, if (lp_browseable(snum) && lp_snum_ok(snum) && is_enumeration_allowed(p, snum) && (all_shares || !is_hidden_share(snum)) ) { - DEBUG(10, ("counting service %s\n", lp_servicename(snum))); + DEBUG(10, ("counting service %s\n", + lp_servicename(snum) ? lp_servicename(snum) : "(null)")); allowed[snum] = true; num_entries++; } else { - DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum))); + DEBUG(10, ("NOT counting service %s\n", + lp_servicename(snum) ? lp_servicename(snum) : "(null)")); } } -- cgit From 2821f5abf5d60cf420877e92db5c615c83471e95 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Wed, 15 Jul 2009 15:37:04 +0800 Subject: s3: Fix double free in net usershare. Signed-off-by: Bo Yang --- source3/utils/net_usershare.c | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) (limited to 'source3') diff --git a/source3/utils/net_usershare.c b/source3/utils/net_usershare.c index 992a03d813..d82d30bc2d 100644 --- a/source3/utils/net_usershare.c +++ b/source3/utils/net_usershare.c @@ -163,7 +163,7 @@ static int net_usershare_delete(struct net_context *c, int argc, const char **ar d_fprintf(stderr, "net usershare delete: share name %s contains " "invalid characters (any of %s)\n", sharename, INVALID_SHARENAME_CHARS); - SAFE_FREE(sharename); + TALLOC_FREE(sharename); return -1; } @@ -172,7 +172,7 @@ static int net_usershare_delete(struct net_context *c, int argc, const char **ar lp_usershare_path(), sharename); if (!us_path) { - SAFE_FREE(sharename); + TALLOC_FREE(sharename); return -1; } @@ -180,10 +180,10 @@ static int net_usershare_delete(struct net_context *c, int argc, const char **ar d_fprintf(stderr, "net usershare delete: unable to remove usershare %s. " "Error was %s\n", us_path, strerror(errno)); - SAFE_FREE(sharename); + TALLOC_FREE(sharename); return -1; } - SAFE_FREE(sharename); + TALLOC_FREE(sharename); return 0; } @@ -672,7 +672,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: maximum number of allowed usershares (%d) reached\n", lp_usershare_max_shares() ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -681,7 +680,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) "invalid characters (any of %s)\n", sharename, INVALID_SHARENAME_CHARS); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -690,7 +688,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: share name %s is already a valid system user name\n", sharename ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -698,7 +695,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) full_path = get_basepath(ctx); if (!full_path) { TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } full_path_tmp = talloc_asprintf(ctx, @@ -706,7 +702,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) full_path); if (!full_path_tmp) { TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -715,7 +710,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) sharename); if (!full_path) { TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -724,7 +718,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr,"net usershare add: path %s is not an absolute path.\n", us_path); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -734,7 +727,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) "this is a directory. Error was %s\n", us_path, strerror(errno) ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -742,7 +734,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: path %s is not a directory.\n", us_path ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -756,7 +747,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) "\tto the [global] section of the smb.conf to allow this.\n", us_path ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -786,7 +776,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: malformed acl %s (missing ':').\n", pacl ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -802,7 +791,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) "(access control must be 'r', 'f', or 'd')\n", pacl ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -810,7 +798,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: malformed terminating character for acl %s\n", pacl ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -818,7 +805,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) if ((name = talloc_strndup(ctx, pacl, pcolon - pacl)) == NULL) { d_fprintf(stderr, "talloc_strndup failed\n"); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } if (!string_to_sid(&sid, name)) { @@ -833,7 +819,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "\n"); } TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } } @@ -854,7 +839,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) "but the \"usershare allow guests\" parameter is not enabled " "by this server.\n"); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -865,7 +849,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: cannot create tmp file %s\n", full_path_tmp ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -874,7 +857,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: cannot lstat tmp file %s\n", full_path_tmp ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -883,7 +865,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: cannot fstat tmp file %s\n", full_path_tmp ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -891,7 +872,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: tmp file %s is not a regular file ?\n", full_path_tmp ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -899,7 +879,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) d_fprintf(stderr, "net usershare add: failed to fchmod tmp file %s to 0644n", full_path_tmp ); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -915,7 +894,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) (unsigned int)to_write, full_path_tmp, strerror(errno)); unlink(full_path_tmp); TALLOC_FREE(ctx); - SAFE_FREE(sharename); return -1; } @@ -926,7 +904,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) sharename, strerror(errno)); TALLOC_FREE(ctx); close(tmpfd); - SAFE_FREE(sharename); return -1; } @@ -939,7 +916,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) net_usershare_info(c, 1, my_argv); } - SAFE_FREE(sharename); TALLOC_FREE(ctx); return 0; } -- cgit From 73e96935c3604d21552ba93dfd561eaf7606f52d Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Wed, 15 Jul 2009 17:03:04 +0800 Subject: s3: fix build of pdbedit and net_sam. Guenther, please check. Signed-off-by: Bo Yang --- source3/utils/net_sam.c | 8 ++++---- source3/utils/pdbedit.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source3') diff --git a/source3/utils/net_sam.c b/source3/utils/net_sam.c index 62abef000d..41daa4180d 100644 --- a/source3/utils/net_sam.c +++ b/source3/utils/net_sam.c @@ -452,7 +452,7 @@ static int net_sam_policy_set(struct net_context *c, int argc, const char **argv const char *account_policy = NULL; uint32 value = 0; uint32 old_value = 0; - int field; + enum pdb_policy_type field; char *endptr; if (argc != 2 || c->display_usage) { @@ -462,7 +462,7 @@ static int net_sam_policy_set(struct net_context *c, int argc, const char **argv } account_policy = argv[0]; - field = account_policy_name_to_fieldnum(account_policy); + field = account_policy_name_to_typenum(account_policy); if (strequal(argv[1], "forever") || strequal(argv[1], "never") || strequal(argv[1], "off")) { @@ -519,7 +519,7 @@ static int net_sam_policy_show(struct net_context *c, int argc, const char **arg { const char *account_policy = NULL; uint32 old_value; - int field; + enum pdb_policy_type field; if (argc != 1 || c->display_usage) { d_fprintf(stderr, "usage: net sam policy show" @@ -528,7 +528,7 @@ static int net_sam_policy_show(struct net_context *c, int argc, const char **arg } account_policy = argv[0]; - field = account_policy_name_to_fieldnum(account_policy); + field = account_policy_name_to_typenum(account_policy); if (field == 0) { const char **names; diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index a464299438..dce2f05a83 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -1109,7 +1109,7 @@ int main (int argc, char **argv) /* account policy operations */ if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) { uint32 value; - int field = account_policy_name_to_fieldnum(account_policy); + enum pdb_policy_type field = account_policy_name_to_typenum(account_policy); if (field == 0) { const char **names; int count; -- cgit From d57e67f9eb5a6a05f0e173d48e86dd1fe050635e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Jul 2009 11:25:45 -0700 Subject: Revert this commit : s3: Make smbd aware of permission change of usershare. Since usershare are relatively volatile and non-previledge users must disconnect from smbd and reconnect to it to make share permission in effect. For now. This is a feature request and I think we need to design it a little differently so as not to touch core change_to_user() code. Jeremy. --- source3/include/proto.h | 7 +--- source3/include/smb.h | 6 --- source3/param/loadparm.c | 11 +++++ source3/smbd/conn.c | 1 - source3/smbd/notify_inotify.c | 4 +- source3/smbd/process.c | 58 +------------------------- source3/smbd/service.c | 80 ------------------------------------ source3/smbd/uid.c | 96 +++++++++++-------------------------------- 8 files changed, 39 insertions(+), 224 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index d141de44cf..0dd1e98c86 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4296,7 +4296,6 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx, char **pp_comment, SEC_DESC **ppsd, bool *pallow_guest); -bool am_usershare(int iService); int load_usershare_service(const char *servicename); int load_usershare_shares(void); void gfree_loadparm(void); @@ -7064,8 +7063,7 @@ void reply_transs2(struct smb_request *req); bool change_to_guest(void); void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid); -bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, - bool recheck, NTSTATUS *pstatus); +bool change_to_user(connection_struct *conn, uint16 vuid); bool change_to_root_user(void); bool become_authenticated_pipe_user(pipes_struct *p); bool unbecome_authenticated_pipe_user(void); @@ -7074,9 +7072,6 @@ void unbecome_root(void); bool become_user(connection_struct *conn, uint16 vuid); bool unbecome_user(void); -#define change_to_user(conn, vuid) \ - change_to_user_force_recheck(conn, vuid, 0, NULL) - /* The following definitions come from smbd/utmp.c */ void sys_utmp_claim(const char *username, const char *hostname, diff --git a/source3/include/smb.h b/source3/include/smb.h index 44216f856a..2e9cf1b54a 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -550,7 +550,6 @@ typedef struct connection_struct { unsigned cnum; /* an index passed over the wire */ struct share_params *params; bool force_user; - bool force_recheck_perm; struct vuid_cache vuid_cache; struct dptr_struct *dirptr; bool printer; @@ -1399,11 +1398,6 @@ struct bitmap { #define FILE_NOTIFY_CHANGE_STREAM_NAME 0x00000200 #define FILE_NOTIFY_CHANGE_STREAM_SIZE 0x00000400 #define FILE_NOTIFY_CHANGE_STREAM_WRITE 0x00000800 -#define FILE_NOTIFY_CHANGE_FILE_CONTENT \ - (FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME \ - | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE \ - | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_EA \ - | FILE_NOTIFY_CHANGE_SECURITY) #define FILE_NOTIFY_CHANGE_NAME \ (FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 4415804a2d..5d3ac9207e 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -8740,6 +8740,17 @@ bool am_usershare(int iService) return false; } +/*************************************************************************** +Am I a usershare service? +***************************************************************************/ +bool am_usershare(int iService) +{ + if (iService >= 0) { + return (ServicePtrs[iService]->usershare == USERSHARE_VALID); + } + return false; +} + /*************************************************************************** Checks if a usershare entry has been modified since last load. ***************************************************************************/ diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index 3ddb4c094f..af6e0919a4 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -155,7 +155,6 @@ find_again: return NULL; } conn->cnum = i; - conn->force_recheck_perm = false; conn->force_group_gid = (gid_t)-1; bitmap_set(sconn->smb1.tcons.bmap, i); diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c index b6be69c8fd..26570a2216 100644 --- a/source3/smbd/notify_inotify.c +++ b/source3/smbd/notify_inotify.c @@ -316,9 +316,7 @@ static const struct { {FILE_NOTIFY_CHANGE_LAST_WRITE, IN_ATTRIB}, {FILE_NOTIFY_CHANGE_LAST_ACCESS, IN_ATTRIB}, {FILE_NOTIFY_CHANGE_EA, IN_ATTRIB}, - {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB}, - {FILE_NOTIFY_CHANGE_FILE_CONTENT, IN_MODIFY|IN_DELETE|IN_CREATE|IN_DELETE_SELF - |IN_MOVE_SELF|IN_MOVED_FROM|IN_MOVED_TO}, + {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB} }; static uint32_t inotify_map(struct notify_entry *e) diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 5b8a325d22..b26bc150db 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -1286,6 +1286,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in } } } + /* Does this call need to be run as the connected user? */ if (flags & AS_USER) { @@ -1302,67 +1303,12 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in } return NULL; } -#ifdef HAVE_INOTIFY - if (conn->force_recheck_perm) { - int old; - int iService = -1; - const char *service = NULL; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - conn->force_recheck_perm = false; - DEBUG(5, ("switch_message: rechecking permission for connection %x\n", - (unsigned int)conn)); - old = SNUM(conn); - service = lp_servicename(old); - conn->read_only = False; - if (lp_snum_ok(old) && am_usershare(old)) { - iService = load_usershare_service(service); - if (iService < 0 || old != iService) { - /* non-exist service */ - DEBUG(5, ("switch_message: deleting connection %x\n", - (unsigned int)conn)); - DEBUG(5, ("snum %d, sname %s\n", - old, service ? service : "NULL")); - delete_share_security(service); - set_current_service(NULL, 0, True); - close_cnum(smbd_server_conn, conn, conn->vuid); - lp_killservice(old); - reply_nterror(req, NT_STATUS_BAD_NETWORK_NAME); - return NULL; - } - - /* - * Don't have to reauthentication here, but - * need to check share permissions..... - * the vuid cache is a problem.. - */ - - if (!change_to_root_user()) { - smb_panic("cann't change to root user!\n"); - } - - if (!change_to_user_force_recheck(conn, session_tag, - True, &status)) { - reply_nterror(req, status); - remove_deferred_open_smb_message(req->mid); - return conn; - } - } - } else { - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - if (!change_to_user_force_recheck(conn, session_tag, - False, &status)) { - reply_nterror(req, status); - remove_deferred_open_smb_message(req->mid); - return conn; - } - } -#else + if (!change_to_user(conn,session_tag)) { reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid)); remove_deferred_open_smb_message(req->mid); return conn; } -#endif /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */ diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 8ae13b14f3..0124b2b047 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -630,33 +630,6 @@ static NTSTATUS create_connection_server_info(struct smbd_server_connection *sco return NT_STATUS_ACCESS_DENIED; } -#ifdef HAVE_INOTIFY -static void share_perm_changed(struct sys_notify_context *ctx, - void *ptr, struct notify_event *ev) -{ - connection_struct *conn = talloc_get_type_abort(ptr, connection_struct); - const char *service = NULL; - service = lp_servicename(SNUM(conn)); - if (strequal(ev->path, service)) { - conn->force_recheck_perm = true; - DEBUG(0, ("share_perm_changed: set recheck flag for connection %x\n", - (unsigned int)conn)); - } -} - -struct notify_context { - struct db_context *db_recursive; - struct db_context *db_onelevel; - struct server_id server; - struct messaging_context *messaging_ctx; - struct notify_list *list; - struct notify_array *array; - int seqnum; - struct sys_notify_context *sys_notify_ctx; - TDB_DATA key; -}; -#endif - /**************************************************************************** Make a connection, given the snum to connect to, and the vuser of the @@ -894,64 +867,11 @@ connection_struct *make_connection_snum(struct smbd_server_connection *sconn, } if ((!conn->printer) && (!conn->ipc)) { -#ifdef HAVE_INOTIFY - struct sys_notify_context *sys_ctx = NULL; - struct notify_entry e; - struct inotify_watch_context *w = NULL; -#endif conn->notify_ctx = notify_init(conn, server_id_self(), smbd_messaging_context(), smbd_event_context(), conn); -#ifdef HAVE_INOTIFY - /* - * here is the start of monitoring share permissions change. - * For usershares, we have to watch on both - * get_dyn_STATDIR()/servicename and get_dyn_STATDIR()/share_info.tdb. - * For shares in smb.conf, we just watch on - * get_dyn_STATDIR()/share_info.tdb - */ - if (!conn->notify_ctx) { - DEBUG(1, ("change notify is not enabled??\n")); - goto nonotify; - } - sys_ctx = conn->notify_ctx->sys_notify_ctx; - if (!sys_ctx) { - DEBUG(1, ("change notify: out of memory!!\n")); - *pstatus = NT_STATUS_NO_MEMORY; - conn_free(sconn, conn); - return NULL; - } - ZERO_STRUCT(e); - if (am_usershare(SNUM(conn))) { - const char *usershare_path = lp_usershare_path(); - /* This is usershare service. */ - e.path = talloc_strdup(conn, usershare_path); - } else { - goto nonotify; - /* watch normal shares' permission? */ - } - if (!e.path) { - DEBUG(1, ("setting up usershare notify: out of memory!\n")); - *pstatus = status; - conn_free(sconn, conn); - return NULL; - } - e.path_len = strlen(e.path); - e.filter = FILE_NOTIFY_CHANGE_FILE_CONTENT; - status = inotify_watch(sys_ctx, &e, share_perm_changed, - (void *)conn, (void *)&w); - if (NT_STATUS_IS_ERR(status)) { - DEBUG(1, ("add inotify for usershare permission failed!\n")); - *pstatus = status; - conn_free(sconn, conn); - return NULL; - } -#endif } -#ifdef HAVE_INOTIFY -nonotify: -#endif /* ROOT Activities: */ /* diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 8e5a386a2d..2ec50cd4d8 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -82,17 +82,12 @@ static void free_conn_server_info_if_unused(connection_struct *conn) static bool check_user_ok(connection_struct *conn, uint16_t vuid, const struct auth_serversupplied_info *server_info, - int snum, bool recheck, NTSTATUS *pstatus) + int snum) { bool valid_vuid = (vuid != UID_FIELD_INVALID); unsigned int i; bool readonly_share; bool admin_user; - struct vuid_cache_entry *ent0; - - if (pstatus) { - *pstatus = NT_STATUS_OK; - } if (valid_vuid) { struct vuid_cache_entry *ent; @@ -101,27 +96,18 @@ static bool check_user_ok(connection_struct *conn, ent = &conn->vuid_cache.array[i]; if (ent->vuid == vuid) { free_conn_server_info_if_unused(conn); - ent0 = ent; - if (!recheck) { - conn->server_info = ent->server_info; - conn->read_only = ent->read_only; - conn->admin_user = ent->admin_user; - return(True); - } else { - break; - } + conn->server_info = ent->server_info; + conn->read_only = ent->read_only; + conn->admin_user = ent->admin_user; + return(True); } } } if (!user_ok_token(server_info->unix_name, pdb_get_domain(server_info->sam_account), - server_info->ptok, snum)) { - if (pstatus) { - *pstatus = NT_STATUS_ACCESS_DENIED; - } + server_info->ptok, snum)) return(False); - } readonly_share = is_share_read_only_for_token( server_info->unix_name, @@ -142,9 +128,6 @@ static bool check_user_ok(connection_struct *conn, if (!share_access_check(server_info->ptok, lp_servicename(snum), readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { - if (pstatus) { - *pstatus = NT_STATUS_ACCESS_DENIED; - } return False; } @@ -154,26 +137,13 @@ static bool check_user_ok(connection_struct *conn, NULL, server_info->ptok, lp_admin_users(snum)); if (valid_vuid) { - struct vuid_cache_entry *ent = NULL; - - if (!recheck || i == VUID_CACHE_SIZE) { - /* find a new entry and fill it. */ - ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry]; + struct vuid_cache_entry *ent = + &conn->vuid_cache.array[conn->vuid_cache.next_entry]; - conn->vuid_cache.next_entry = - (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE; + conn->vuid_cache.next_entry = + (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE; - TALLOC_FREE(ent->server_info); - } else if (recheck && (i < VUID_CACHE_SIZE) && (ent0->vuid == vuid)) { - /* she perform forced recheck, replace the old one. */ - ent = ent0; - } else { - /* must not happen */ - DEBUG(0, ("check_user_ok: recheck %s\n", recheck ? "true" : "false")); - DEBUG(0, ("check_user_ok: vuid cache %d -- %d\n", i, VUID_CACHE_SIZE)); - DEBUG(0, ("check_user_ok: vuid %d -- %d\n", ent0->vuid, vuid)); - smb_panic("should not happen"); - } + TALLOC_FREE(ent->server_info); /* * If force_user was set, all server_info's are based on the same @@ -185,9 +155,6 @@ static bool check_user_ok(connection_struct *conn, if (ent->server_info == NULL) { ent->vuid = UID_FIELD_INVALID; - if (pstatus) { - *pstatus = NT_STATUS_NO_MEMORY; - } return false; } @@ -254,8 +221,7 @@ void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid) stack, but modify the current_user entries. ****************************************************************************/ -bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, - bool recheck, NTSTATUS *pstatus) +bool change_to_user(connection_struct *conn, uint16 vuid) { const struct auth_serversupplied_info *server_info = NULL; struct smbd_server_connection *sconn = smbd_server_conn; @@ -269,9 +235,6 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, if (!conn) { DEBUG(2,("change_to_user: Connection not open\n")); - if (pstatus) { - *pstatus = NT_STATUS_INVALID_HANDLE; - } return(False); } @@ -282,19 +245,17 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, * SMB's - this hurts performance - Badly. */ - if (!recheck) { - if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && - (current_user.ut.uid == conn->server_info->utok.uid)) { - DEBUG(4,("change_to_user: Skipping user change - already " - "user\n")); - return(True); - } else if ((current_user.conn == conn) && - (vuser != NULL) && (current_user.vuid == vuid) && - (current_user.ut.uid == vuser->server_info->utok.uid)) { - DEBUG(4,("change_to_user: Skipping user change - already " - "user\n")); - return(True); - } + if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && + (current_user.ut.uid == conn->server_info->utok.uid)) { + DEBUG(4,("change_to_user: Skipping user change - already " + "user\n")); + return(True); + } else if ((current_user.conn == conn) && + (vuser != NULL) && (current_user.vuid == vuid) && + (current_user.ut.uid == vuser->server_info->utok.uid)) { + DEBUG(4,("change_to_user: Skipping user change - already " + "user\n")); + return(True); } snum = SNUM(conn); @@ -305,13 +266,10 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, /* Invalid vuid sent - even with security = share. */ DEBUG(2,("change_to_user: Invalid vuid %d used on " "share %s.\n",vuid, lp_servicename(snum) )); - if (pstatus) { - *pstatus = NT_STATUS_ACCESS_VIOLATION; - } return false; } - if (!check_user_ok(conn, vuid, server_info, snum, recheck, pstatus)) { + if (!check_user_ok(conn, vuid, server_info, snum)) { DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) " "not permitted access to share %s.\n", server_info->sanitized_username, @@ -338,9 +296,6 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, } else { DEBUG(2,("change_to_user: Invalid vuid used %d in accessing " "share %s.\n",vuid, lp_servicename(snum) )); - if (pstatus) { - *pstatus = NT_STATUS_DOS(ERRSRV, ERRbaduid); - } return False; } @@ -398,9 +353,6 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid, DEBUG(5,("change_to_user uid=(%d,%d) gid=(%d,%d)\n", (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); - if (pstatus) { - *pstatus = NT_STATUS_OK; - } return(True); } -- cgit From 74046c8054d2afe7da51c1ff09ffd594a9cb8b73 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Jul 2009 18:33:01 +0200 Subject: TALLOC_FREE(sd) in check_open_rights upon an error --- source3/smbd/open.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3') diff --git a/source3/smbd/open.c b/source3/smbd/open.c index e01350f2bf..404461fb5e 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -94,6 +94,7 @@ static NTSTATUS check_open_rights(struct connection_struct *conn, "on %s: %s\n", smb_fname_str_dbg(smb_fname), nt_errstr(status))); + TALLOC_FREE(sd); return status; } -- cgit From 749a50874906ba38f1085065933f2781b81d5dfa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Jul 2009 18:34:36 +0200 Subject: Create a talloc_stackframe for each file in wildcard unlink There might be *many* files to delete --- source3/smbd/reply.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index e35c5bc6d6..4d0a2b8c97 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2646,18 +2646,23 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, while ((dname = ReadDirName(dir_hnd, &offset, &smb_fname->st))) { + TALLOC_CTX *frame = talloc_stackframe(); + if (!is_visible_file(conn, fname_dir, dname, &smb_fname->st, true)) { + TALLOC_FREE(frame); continue; } /* Quick check for "." and ".." */ if (ISDOT(dname) || ISDOTDOT(dname)) { + TALLOC_FREE(frame); continue; } if(!mask_match(dname, fname_mask, conn->case_sensitive)) { + TALLOC_FREE(frame); continue; } @@ -2669,23 +2674,28 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, if (!smb_fname->base_name) { TALLOC_FREE(dir_hnd); status = NT_STATUS_NO_MEMORY; + TALLOC_FREE(frame); goto out; } status = check_name(conn, smb_fname->base_name); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(dir_hnd); + TALLOC_FREE(frame); goto out; } status = do_unlink(conn, req, smb_fname, dirtype); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); continue; } count++; DEBUG(3,("unlink_internals: successful unlink [%s]\n", smb_fname->base_name)); + + TALLOC_FREE(frame); } TALLOC_FREE(dir_hnd); } -- cgit From b134d4bc4ad665b82438eb8e1b5cbd1098a36aed Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Jul 2009 21:28:13 +0200 Subject: Attempt to fix the build --- source3/param/loadparm.c | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'source3') diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 5d3ac9207e..dbbd6e327d 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -8729,28 +8729,6 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i return iService; } -/*************************************************************************** -Am I a usershare service? -***************************************************************************/ -bool am_usershare(int iService) -{ - if (iService >= 0) { - return (ServicePtrs[iService]->usershare == USERSHARE_VALID); - } - return false; -} - -/*************************************************************************** -Am I a usershare service? -***************************************************************************/ -bool am_usershare(int iService) -{ - if (iService >= 0) { - return (ServicePtrs[iService]->usershare == USERSHARE_VALID); - } - return false; -} - /*************************************************************************** Checks if a usershare entry has been modified since last load. ***************************************************************************/ -- cgit From 036bad61317bc71f59db0e766881dd880253bb52 Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Tue, 14 Jul 2009 22:23:39 +0200 Subject: s3: allow setting the TCP_QUICKACK socket option --- source3/lib/util_sock.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 31261afd72..af64f370ba 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -348,6 +348,9 @@ static const smb_socket_option socket_options[] = { #endif #ifdef TCP_FASTACK {"TCP_FASTACK", IPPROTO_TCP, TCP_FASTACK, 0, OPT_INT}, +#endif +#ifdef TCP_QUICKACK + {"TCP_QUICKACK", IPPROTO_TCP, TCP_QUICKACK, 0, OPT_BOOL}, #endif {NULL,0,0,0,0}}; -- cgit From d05054133009526bd9dd08a226747e5cfeef8fc7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Jul 2009 23:12:59 +0200 Subject: Fix bug 5886 Ok, that's a very long-standing one. I finally got around to install a recent OpenLDAP and test the different variants of setting a NULL password etc. Thanks all for your patience! Volker --- source3/passdb/pdb_ldap.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'source3') diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 11554a76ac..1b1e22f2c8 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1701,6 +1701,7 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, char *utf8_password; char *utf8_dn; size_t converted_size; + int ret; if (!ldap_state->is_nds_ldap) { @@ -1732,14 +1733,31 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, } if ((ber_printf (ber, "{") < 0) || - (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn) < 0) || - (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password) < 0) || - (ber_printf (ber, "n}") < 0)) { - DEBUG(0,("ldapsam_modify_entry: ber_printf returns a value <0\n")); - ber_free(ber,1); - TALLOC_FREE(utf8_dn); - TALLOC_FREE(utf8_password); - return NT_STATUS_UNSUCCESSFUL; + (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, + utf8_dn) < 0)) { + DEBUG(0,("ldapsam_modify_entry: ber_printf returns a " + "value <0\n")); + ber_free(ber,1); + TALLOC_FREE(utf8_dn); + TALLOC_FREE(utf8_password); + return NT_STATUS_UNSUCCESSFUL; + } + + if ((utf8_password != NULL) && (*utf8_password != '\0')) { + ret = ber_printf(ber, "ts}", + LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, + utf8_password); + } else { + ret = ber_printf(ber, "}"); + } + + if (ret < 0) { + DEBUG(0,("ldapsam_modify_entry: ber_printf returns a " + "value <0\n")); + ber_free(ber,1); + TALLOC_FREE(utf8_dn); + TALLOC_FREE(utf8_password); + return NT_STATUS_UNSUCCESSFUL; } if ((rc = ber_flatten (ber, &bv))<0) { -- cgit From 4b6401ab2cce8319abe0f8176bb460d51bd4a390 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 14 Jul 2009 23:36:41 +0200 Subject: s3-passdb: fix wbc build warning. Guenther --- source3/passdb/pdb_wbc_sam.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c index ec54d553d1..2161d2ff5c 100644 --- a/source3/passdb/pdb_wbc_sam.c +++ b/source3/passdb/pdb_wbc_sam.c @@ -167,12 +167,12 @@ done: return result; } -static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value) +static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value) { return NT_STATUS_UNSUCCESSFUL; } -static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value) +static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value) { return NT_STATUS_UNSUCCESSFUL; } -- cgit From 565046891f9f7725b5d93eefbc3be5b9c62176fd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Jul 2009 10:54:33 +0200 Subject: Replace ASSERTs in gencache with "return false" It's a bit strong to panic here I think. --- source3/lib/gencache.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'source3') diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 7f133f20b0..5497c4c240 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -115,8 +115,9 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout) TDB_DATA databuf; char* valstr = NULL; - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr && value); + if ((keystr == NULL) || (value == NULL)) { + return false; + } if (!gencache_init()) return False; @@ -149,8 +150,9 @@ bool gencache_del(const char *keystr) { int ret; - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr); + if (keystr == NULL) { + return false; + } if (!gencache_init()) return False; @@ -180,8 +182,9 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout) time_t t; char *endptr; - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr); + if (keystr == NULL) { + return false; + } if (!gencache_init()) { return False; @@ -256,8 +259,9 @@ bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired) int buflen = 0, len = 0, blob_len = 0; unsigned char *blob_buf = NULL; - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr); + if (keystr == NULL) { + return false; + } if (!gencache_init()) { return False; @@ -333,8 +337,9 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t ti unsigned char *buf = NULL; int len = 0, buflen = 0; - /* fail completely if get null pointers passed */ - SMB_ASSERT(keystr && blob); + if ((keystr == NULL) || (blob == NULL)) { + return false; + } if (!gencache_init()) { return False; @@ -465,8 +470,9 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time { struct gencache_iterate_state state; - /* fail completely if get null pointers passed */ - SMB_ASSERT(fn && keystr_pattern); + if ((fn == NULL) || (keystr_pattern == NULL)) { + return; + } if (!gencache_init()) return; -- cgit From 3e965d017d243f0a99e7838e6c92c37df270486c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Jul 2009 11:00:24 +0200 Subject: TDB_CONTEXT -> "struct tdb_context" --- source3/lib/gencache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 5497c4c240..0e099f0dd0 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -31,7 +31,7 @@ #define BLOB_TYPE "DATA_BLOB" #define BLOB_TYPE_LEN 9 -static TDB_CONTEXT *cache; +static struct tdb_context *cache; /** * @file gencache.c -- cgit From e5a34b2533720ebb9181c0edebad6774ceeff189 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Jul 2009 12:03:35 +0200 Subject: Remove gencache_[un]lock_key --- source3/include/proto.h | 2 -- source3/lib/gencache.c | 25 ------------------------- source3/libsmb/dsgetdcname.c | 6 ------ 3 files changed, 33 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 0dd1e98c86..52ca7826ed 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -524,8 +524,6 @@ bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired); bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout); void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr), void* data, const char* keystr_pattern); -int gencache_lock_entry( const char *key ); -void gencache_unlock_entry( const char *key ); /* The following definitions come from lib/interface.c */ diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 0e099f0dd0..c94fb78541 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -483,28 +483,3 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time state.priv = data; tdb_traverse(cache, gencache_iterate_fn, &state); } - -/******************************************************************** - lock a key -********************************************************************/ - -int gencache_lock_entry( const char *key ) -{ - if (!gencache_init()) - return -1; - - return tdb_lock_bystring(cache, key); -} - -/******************************************************************** - unlock a key -********************************************************************/ - -void gencache_unlock_entry( const char *key ) -{ - if (!gencache_init()) - return; - - tdb_unlock_bystring(cache, key); - return; -} diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index fb87b4dc9a..8dee6926d2 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -171,14 +171,8 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL; - if (gencache_lock_entry(key) != 0) { - return NT_STATUS_LOCK_NOT_GRANTED; - } - ret = gencache_set_data_blob(key, blob, expire_time); - gencache_unlock_entry(key); - return ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } -- cgit From d936d1bd84e130aaff1de64cb1ecbd1f936dd9c4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Jul 2009 12:12:30 +0200 Subject: Fix some nonempty blank lines --- source3/libsmb/trustdom_cache.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) (limited to 'source3') diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index 6755de3814..d891c0768e 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -4,17 +4,17 @@ Trusted domain names cache on top of gencache. Copyright (C) Rafal Szczesniak 2002 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -38,7 +38,6 @@ * list of trusted domains **/ - /** * Initialise trustdom name caching system. Call gencache * initialisation routine to perform necessary activities. @@ -46,7 +45,7 @@ * @return true upon successful cache initialisation or * false if cache init failed **/ - + bool trustdom_cache_enable(void) { /* Init trustdom cache by calling gencache initialisation */ @@ -66,7 +65,7 @@ bool trustdom_cache_enable(void) * @return true upon successful cache close or * false if it failed **/ - + bool trustdom_cache_shutdown(void) { /* Close trustdom cache by calling gencache shutdown */ @@ -74,7 +73,7 @@ bool trustdom_cache_shutdown(void) DEBUG(2, ("trustdomcache_shutdown: Couldn't shutdown trustdom cache on top of gencache.\n")); return False; } - + return True; } @@ -91,7 +90,7 @@ static char* trustdom_cache_key(const char* name) { char* keystr = NULL; asprintf_strupper_m(&keystr, TDOMKEY_FMT, name); - + return keystr; } @@ -160,7 +159,7 @@ bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, * @return true if entry is found or * false if has expired/doesn't exist **/ - + bool trustdom_cache_fetch(const char* name, DOM_SID* sid) { char *key = NULL, *value = NULL; @@ -169,7 +168,7 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid) /* init the cache */ if (!gencache_init()) return False; - + /* exit now if null pointers were passed as they're required further */ if (!sid) return False; @@ -178,7 +177,7 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid) key = trustdom_cache_key(name); if (!key) return False; - + if (!gencache_get(key, &value, &timeout)) { DEBUG(5, ("no entry for trusted domain %s found.\n", name)); SAFE_FREE(key); @@ -194,7 +193,7 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid) SAFE_FREE(value); return False; } - + SAFE_FREE(value); return True; } @@ -213,7 +212,7 @@ uint32 trustdom_cache_fetch_timestamp( void ) /* init the cache */ if (!gencache_init()) return False; - + if (!gencache_get(TDOMTSKEY, &value, &timeout)) { DEBUG(5, ("no timestamp for trusted domain cache located.\n")); SAFE_FREE(value); @@ -221,7 +220,7 @@ uint32 trustdom_cache_fetch_timestamp( void ) } timestamp = atoi(value); - + SAFE_FREE(value); return timestamp; } @@ -237,9 +236,9 @@ bool trustdom_cache_store_timestamp( uint32 t, time_t timeout ) /* init the cache */ if (!gencache_init()) return False; - + fstr_sprintf(value, "%d", t ); - + if (!gencache_set(TDOMTSKEY, value, timeout)) { DEBUG(5, ("failed to set timestamp for trustdom_cache\n")); return False; @@ -294,13 +293,13 @@ void update_trustdom_cache( void ) TALLOC_CTX *mem_ctx = NULL; time_t now = time(NULL); int i; - + /* get the timestamp. We have to initialise it if the last timestamp == 0 */ if ( (last_check = trustdom_cache_fetch_timestamp()) == 0 ) trustdom_cache_store_timestamp(0, now+TRUSTDOM_UPDATE_INTERVAL); time_diff = (int) (now - last_check); - + if ( (time_diff > 0) && (time_diff < TRUSTDOM_UPDATE_INTERVAL) ) { DEBUG(10,("update_trustdom_cache: not time to update trustdom_cache yet\n")); return; @@ -310,14 +309,14 @@ void update_trustdom_cache( void ) smbd from blocking all other smbd daemons while we enumerate the trusted domains */ trustdom_cache_store_timestamp(now, now+TRUSTDOM_UPDATE_INTERVAL); - + if ( !(mem_ctx = talloc_init("update_trustdom_cache")) ) { DEBUG(0,("update_trustdom_cache: talloc_init() failed!\n")); goto done; } /* get the domains and store them */ - + if ( enumerate_domain_trusts(mem_ctx, lp_workgroup(), &domain_names, &num_domains, &dom_sids)) { for ( i=0; i Date: Fri, 10 Jul 2009 12:24:56 +0200 Subject: Remove gencache_init/shutdown gencache_get/set/del/iterate call gencache_init() internally anyway. And we've been very lazy calling gencache_shutdown, so this seems not really required. --- source3/include/proto.h | 2 -- source3/lib/gencache.c | 21 +-------------------- source3/lib/netapi/netapi.c | 1 - source3/libads/dns.c | 8 -------- source3/libsmb/dsgetdcname.c | 12 ------------ source3/libsmb/libsmb_context.c | 1 - source3/libsmb/namecache.c | 34 ---------------------------------- source3/libsmb/namequery.c | 12 ------------ source3/libsmb/trustdom_cache.c | 34 ---------------------------------- source3/torture/torture.c | 16 ---------------- source3/utils/net_cache.c | 4 ---- 11 files changed, 1 insertion(+), 144 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 52ca7826ed..23bd22aadc 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -515,8 +515,6 @@ void pull_file_id_24(char *buf, struct file_id *id); /* The following definitions come from lib/gencache.c */ -bool gencache_init(void); -bool gencache_shutdown(void); bool gencache_set(const char *keystr, const char *value, time_t timeout); bool gencache_del(const char *keystr); bool gencache_get(const char *keystr, char **valstr, time_t *timeout); diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index c94fb78541..06eb29345b 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -49,7 +49,7 @@ static struct tdb_context *cache; * false on failure **/ -bool gencache_init(void) +static bool gencache_init(void) { char* cache_fname = NULL; @@ -78,25 +78,6 @@ bool gencache_init(void) } -/** - * Cache shutdown function. Closes opened cache tdb file. - * - * @return true on successful closing the cache or - * false on failure during cache shutdown - **/ - -bool gencache_shutdown(void) -{ - int ret; - /* tdb_close routine returns -1 on error */ - if (!cache) return False; - DEBUG(5, ("Closing cache file\n")); - ret = tdb_close(cache); - cache = NULL; - return ret != -1; -} - - /** * Set an entry in the cache file. If there's no such * one, then add it. diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 2f8474b37f..e80879a1d2 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -170,7 +170,6 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) gfree_charcnv(); gfree_interfaces(); - gencache_shutdown(); secrets_shutdown(); TALLOC_FREE(ctx); diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 3a9e849668..5cf768de67 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -754,10 +754,6 @@ bool sitename_store(const char *realm, const char *sitename) bool ret = False; char *key; - if (!gencache_init()) { - return False; - } - if (!realm || (strlen(realm) == 0)) { DEBUG(0,("sitename_store: no realm\n")); return False; @@ -795,10 +791,6 @@ char *sitename_fetch(const char *realm) const char *query_realm; char *key; - if (!gencache_init()) { - return NULL; - } - if (!realm || (strlen(realm) == 0)) { query_realm = lp_realm(); } else { diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 8dee6926d2..9552ad1f22 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -133,10 +133,6 @@ static NTSTATUS dsgetdcname_cache_delete(TALLOC_CTX *mem_ctx, { char *key; - if (!gencache_init()) { - return NT_STATUS_INTERNAL_DB_ERROR; - } - key = dsgetdcname_cache_key(mem_ctx, domain_name); if (!key) { return NT_STATUS_NO_MEMORY; @@ -160,10 +156,6 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, char *key; bool ret = false; - if (!gencache_init()) { - return NT_STATUS_INTERNAL_DB_ERROR; - } - key = dsgetdcname_cache_key(mem_ctx, domain_name); if (!key) { return NT_STATUS_NO_MEMORY; @@ -357,10 +349,6 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, struct NETLOGON_SAM_LOGON_RESPONSE_EX r; NTSTATUS status; - if (!gencache_init()) { - return NT_STATUS_INTERNAL_DB_ERROR; - } - key = dsgetdcname_cache_key(mem_ctx, domain_name); if (!key) { return NT_STATUS_NO_MEMORY; diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 98885876b3..8b22ee5023 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -123,7 +123,6 @@ SMBC_module_init(void * punused) static void SMBC_module_terminate(void) { - gencache_shutdown(); secrets_shutdown(); gfree_all(); SMBC_initialized = false; diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index d3230cffef..dcfc609dcd 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -45,14 +45,6 @@ bool namecache_enable(void) return False; } - /* Init namecache by calling gencache initialisation */ - - if (!gencache_init()) { - DEBUG(2, ("namecache_enable: " - "Couldn't initialise namecache on top of gencache.\n")); - return False; - } - /* I leave it for now, though I don't think we really * need this (mimir, 27.09.2002) */ DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d " @@ -102,14 +94,6 @@ bool namecache_store(const char *name, int i; bool ret; - /* - * we use gecache call to avoid annoying debug messages about - * initialised namecache again and again... - */ - if (!gencache_init()) { - return False; - } - if (name_type > 255) { return False; /* Don't store non-real name types. */ } @@ -186,10 +170,6 @@ bool namecache_fetch(const char *name, return False; } - if (!gencache_init()) { - return False; - } - if (name_type > 255) { return False; /* Don't fetch non-real name types. */ } @@ -233,9 +213,6 @@ bool namecache_delete(const char *name, int name_type) bool ret; char *key; - if (!gencache_init()) - return False; - if (name_type > 255) { return False; /* Don't fetch non-real name types. */ } @@ -274,10 +251,6 @@ static void flush_netbios_name(const char *key, void namecache_flush(void) { - if (!gencache_init()) { - return; - } - /* * iterate through each NBT cache's entry and flush it * by flush_netbios_name function @@ -312,10 +285,6 @@ bool namecache_status_store(const char *keyname, int keyname_type, time_t expiry; bool ret; - if (!gencache_init()) { - return False; - } - key = namecache_status_record_key(keyname, keyname_type, name_type, keyip); if (!key) @@ -348,9 +317,6 @@ bool namecache_status_fetch(const char *keyname, char *value = NULL; time_t timeout; - if (!gencache_init()) - return False; - key = namecache_status_record_key(keyname, keyname_type, name_type, keyip); if (!key) diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 50fb9f1620..05143270b9 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -76,9 +76,6 @@ bool saf_store( const char *domain, const char *servername ) return False; } - if ( !gencache_init() ) - return False; - key = saf_key( domain ); expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL); @@ -108,9 +105,6 @@ bool saf_join_store( const char *domain, const char *servername ) return False; } - if ( !gencache_init() ) - return False; - key = saf_join_key( domain ); expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL); @@ -134,9 +128,6 @@ bool saf_delete( const char *domain ) return False; } - if ( !gencache_init() ) - return False; - key = saf_join_key(domain); ret = gencache_del(key); SAFE_FREE(key); @@ -171,9 +162,6 @@ char *saf_fetch( const char *domain ) return NULL; } - if ( !gencache_init() ) - return False; - key = saf_join_key( domain ); ret = gencache_get( key, &server, &timeout ); diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index d891c0768e..eb52b3588d 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -48,12 +48,6 @@ bool trustdom_cache_enable(void) { - /* Init trustdom cache by calling gencache initialisation */ - if (!gencache_init()) { - DEBUG(2, ("trustdomcache_enable: Couldn't initialise trustdom cache on top of gencache.\n")); - return False; - } - return True; } @@ -68,12 +62,6 @@ bool trustdom_cache_enable(void) bool trustdom_cache_shutdown(void) { - /* Close trustdom cache by calling gencache shutdown */ - if (!gencache_shutdown()) { - DEBUG(2, ("trustdomcache_shutdown: Couldn't shutdown trustdom cache on top of gencache.\n")); - return False; - } - return True; } @@ -114,13 +102,6 @@ bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, fstring sid_string; bool ret; - /* - * we use gecache call to avoid annoying debug messages - * about initialised trustdom - */ - if (!gencache_init()) - return False; - DEBUG(5, ("trustdom_store: storing SID %s of domain %s\n", sid_string_dbg(sid), name)); @@ -165,10 +146,6 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid) char *key = NULL, *value = NULL; time_t timeout; - /* init the cache */ - if (!gencache_init()) - return False; - /* exit now if null pointers were passed as they're required further */ if (!sid) return False; @@ -209,10 +186,6 @@ uint32 trustdom_cache_fetch_timestamp( void ) time_t timeout; uint32 timestamp; - /* init the cache */ - if (!gencache_init()) - return False; - if (!gencache_get(TDOMTSKEY, &value, &timeout)) { DEBUG(5, ("no timestamp for trusted domain cache located.\n")); SAFE_FREE(value); @@ -233,10 +206,6 @@ bool trustdom_cache_store_timestamp( uint32 t, time_t timeout ) { fstring value; - /* init the cache */ - if (!gencache_init()) - return False; - fstr_sprintf(value, "%d", t ); if (!gencache_set(TDOMTSKEY, value, timeout)) { @@ -267,9 +236,6 @@ static void flush_trustdom_name(const char* key, const char *value, time_t timeo void trustdom_cache_flush(void) { - if (!gencache_init()) - return; - /* * iterate through each TDOM cache's entry and flush it * by flush_trustdom_name function diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 8cebc2adcc..e3c4084e0c 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -5800,11 +5800,6 @@ static bool run_local_gencache(int dummy) time_t tm; DATA_BLOB blob; - if (!gencache_init()) { - d_printf("%s: gencache_init() failed\n", __location__); - return False; - } - if (!gencache_set("foo", "bar", time(NULL) + 1000)) { d_printf("%s: gencache_set() failed\n", __location__); return False; @@ -5878,17 +5873,6 @@ static bool run_local_gencache(int dummy) return False; } - if (!gencache_shutdown()) { - d_printf("%s: gencache_shutdown() failed\n", __location__); - return False; - } - - if (gencache_shutdown()) { - d_printf("%s: second gencache_shutdown() succeeded\n", - __location__); - return False; - } - return True; } diff --git a/source3/utils/net_cache.c b/source3/utils/net_cache.c index 5e7db38515..74d8d29b4b 100644 --- a/source3/utils/net_cache.c +++ b/source3/utils/net_cache.c @@ -171,12 +171,10 @@ static int net_cache_add(struct net_context *c, int argc, const char **argv) if (gencache_set(keystr, datastr, timeout)) { d_printf("New cache entry stored successfully.\n"); - gencache_shutdown(); return 0; } d_fprintf(stderr, "Entry couldn't be added. Perhaps there's already such a key.\n"); - gencache_shutdown(); return -1; } @@ -275,7 +273,6 @@ static int net_cache_list(struct net_context *c, int argc, const char **argv) return 0; } gencache_iterate(print_cache_entry, NULL, pattern); - gencache_shutdown(); return 0; } @@ -297,7 +294,6 @@ static int net_cache_flush(struct net_context *c, int argc, const char **argv) return 0; } gencache_iterate(delete_cache_entry, NULL, pattern); - gencache_shutdown(); return 0; } -- cgit From ed87594e5fd3251f9cb3beaca06c8eee1dcd4ed2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 13 Jul 2009 17:03:52 +0200 Subject: Add tdb_data_cmp --- source3/include/util_tdb.h | 2 ++ source3/lib/util_tdb.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'source3') diff --git a/source3/include/util_tdb.h b/source3/include/util_tdb.h index c79436434f..80b95921d7 100644 --- a/source3/include/util_tdb.h +++ b/source3/include/util_tdb.h @@ -59,4 +59,6 @@ struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx, NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err); +int tdb_data_cmp(TDB_DATA t1, TDB_DATA t2); + #endif /* __TDBUTIL_H__ */ diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c index 78fa7cd0a1..5b3d94dabe 100644 --- a/source3/lib/util_tdb.c +++ b/source3/lib/util_tdb.c @@ -630,3 +630,22 @@ NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err) return NT_STATUS_INTERNAL_ERROR; } + +int tdb_data_cmp(TDB_DATA t1, TDB_DATA t2) +{ + int ret; + if (t1.dptr == NULL && t2.dptr != NULL) { + return -1; + } + if (t1.dptr != NULL && t2.dptr == NULL) { + return 1; + } + if (t1.dptr == t2.dptr) { + return t1.dsize - t2.dsize; + } + ret = memcmp(t1.dptr, t2.dptr, MIN(t1.dsize, t2.dsize)); + if (ret == 0) { + return t1.dsize - t2.dsize; + } + return ret; +} -- cgit From 8a17cd810fa6cbe7b11139ff0f6f24e7bacd318b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 13 Jul 2009 17:04:29 +0200 Subject: Make gencache more stable This provides a compromise between stability and performance: gencache is a persistent database these days that for performance reasons can not use tdb transactions for all writes. This patch splits up gencache into gencache.tdb and gencache_notrans.tdb. gencache_notrans is used with CLEAR_IF_FIRST, writes to it don't use transactions. By default every 5 minutes and when a program exits, all entries from _notrans.tdb are transferred to gencache.tdb in one transaction. --- source3/include/proto.h | 1 + source3/lib/gencache.c | 283 +++++++++++++++++++++++++++++++++++++++++--- source3/nmbd/nmbd.c | 2 + source3/smbd/server.c | 1 + source3/utils/net.c | 2 + source3/utils/net_cache.c | 23 ++++ source3/winbindd/winbindd.c | 2 + 7 files changed, 299 insertions(+), 15 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 23bd22aadc..dd49e53338 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -519,6 +519,7 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout); bool gencache_del(const char *keystr); bool gencache_get(const char *keystr, char **valstr, time_t *timeout); bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired); +bool gencache_stabilize(void); bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout); void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr), void* data, const char* keystr_pattern); diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 06eb29345b..73f433c1c0 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -32,6 +32,7 @@ #define BLOB_TYPE_LEN 9 static struct tdb_context *cache; +static struct tdb_context *cache_notrans; /** * @file gencache.c @@ -52,6 +53,7 @@ static struct tdb_context *cache; static bool gencache_init(void) { char* cache_fname = NULL; + int open_flags = O_RDWR|O_CREAT; /* skip file open if it's already opened */ if (cache) return True; @@ -60,11 +62,12 @@ static bool gencache_init(void) DEBUG(5, ("Opening cache file at %s\n", cache_fname)); - cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, - O_RDWR|O_CREAT, 0644); + cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, open_flags, 0644); if (!cache && (errno == EACCES)) { - cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, O_RDONLY, 0644); + open_flags = O_RDONLY; + cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, open_flags, + 0644); if (cache) { DEBUG(5, ("gencache_init: Opening cache file %s read-only.\n", cache_fname)); } @@ -74,9 +77,30 @@ static bool gencache_init(void) DEBUG(5, ("Attempt to open gencache.tdb has failed.\n")); return False; } + + cache_fname = lock_path("gencache_notrans.tdb"); + + DEBUG(5, ("Opening cache file at %s\n", cache_fname)); + + cache_notrans = tdb_open_log(cache_fname, 0, TDB_CLEAR_IF_FIRST, + open_flags, 0644); + if (cache_notrans == NULL) { + DEBUG(5, ("Opening %s failed: %s\n", cache_fname, + strerror(errno))); + tdb_close(cache); + return false; + } + return True; } +static TDB_DATA last_stabilize_key(void) +{ + TDB_DATA result; + result.dptr = (uint8_t *)"@LAST_STABILIZED"; + result.dsize = 17; + return result; +} /** * Set an entry in the cache file. If there's no such @@ -95,6 +119,13 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout) int ret; TDB_DATA databuf; char* valstr = NULL; + time_t last_stabilize; + + if (tdb_data_cmp(string_term_tdb_data(keystr), + last_stabilize_key()) == 0) { + DEBUG(10, ("Can't store %s as a key\n", keystr)); + return false; + } if ((keystr == NULL) || (value == NULL)) { return false; @@ -112,9 +143,31 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout) (int)(timeout - time(NULL)), timeout > time(NULL) ? "ahead" : "in the past")); - ret = tdb_store_bystring(cache, keystr, databuf, 0); + ret = tdb_store_bystring(cache_notrans, keystr, databuf, 0); SAFE_FREE(valstr); + if (ret != 0) { + return false; + } + + /* + * Every 5 minutes, call gencache_stabilize() to not let grow + * gencache_notrans.tdb too large. + */ + + last_stabilize = 0; + databuf = tdb_fetch(cache_notrans, last_stabilize_key()); + if ((databuf.dptr != NULL) + && (databuf.dptr[databuf.dsize-1] == '\0')) { + last_stabilize = atoi((char *)databuf.dptr); + SAFE_FREE(databuf.dptr); + } + if ((last_stabilize + + lp_parm_int(-1, "gencache", "stabilize_interval", 300)) + < time(NULL)) { + gencache_stabilize(); + } + return ret == 0; } @@ -129,7 +182,9 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout) bool gencache_del(const char *keystr) { - int ret; + bool exists; + bool ret = false; + char *value; if (keystr == NULL) { return false; @@ -138,11 +193,46 @@ bool gencache_del(const char *keystr) if (!gencache_init()) return False; DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr)); - ret = tdb_delete_bystring(cache, keystr); - return ret == 0; + if (tdb_lock_bystring(cache_notrans, keystr) == -1) { + DEBUG(5, ("Could not lock key for %s\n", keystr)); + return false; + } + + /* + * We delete an element by setting its timeout to 0. This way we don't + * have to do a transaction on gencache.tdb every time we delete an + * element. + */ + + exists = gencache_get(keystr, &value, NULL); + if (exists) { + SAFE_FREE(value); + ret = gencache_set(keystr, "", 0); + } + tdb_unlock_bystring(cache_notrans, keystr); + return ret; } +static bool gencache_pull_timeout(char *val, time_t *pres, char **pendptr) +{ + time_t res; + char *endptr; + + res = strtol(val, &endptr, 10); + + if ((endptr == NULL) || (*endptr != '/')) { + DEBUG(2, ("Invalid gencache data format: %s\n", val)); + return false; + } + if (pres != NULL) { + *pres = res; + } + if (pendptr != NULL) { + *pendptr = endptr; + } + return true; +} /** * Get existing entry from the cache file. @@ -167,22 +257,29 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout) return false; } + if (tdb_data_cmp(string_term_tdb_data(keystr), + last_stabilize_key()) == 0) { + DEBUG(10, ("Can't get %s as a key\n", keystr)); + return false; + } + if (!gencache_init()) { return False; } - databuf = tdb_fetch_bystring(cache, keystr); + databuf = tdb_fetch_bystring(cache_notrans, keystr); if (databuf.dptr == NULL) { - DEBUG(10, ("Cache entry with key = %s couldn't be found\n", + databuf = tdb_fetch_bystring(cache, keystr); + } + + if (databuf.dptr == NULL) { + DEBUG(10, ("Cache entry with key = %s couldn't be found \n", keystr)); return False; } - t = strtol((const char *)databuf.dptr, &endptr, 10); - - if ((endptr == NULL) || (*endptr != '/')) { - DEBUG(2, ("Invalid gencache data format: %s\n", databuf.dptr)); + if (!gencache_pull_timeout((char *)databuf.dptr, &t, &endptr)) { SAFE_FREE(databuf.dptr); return False; } @@ -191,10 +288,21 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout) "timeout = %s", t > time(NULL) ? "valid" : "expired", keystr, endptr+1, ctime(&t))); + if (t == 0) { + /* Deleted */ + SAFE_FREE(databuf.dptr); + return False; + } + if (t <= time(NULL)) { - /* We're expired, delete the entry */ - tdb_delete_bystring(cache, keystr); + /* + * We're expired, delete the entry. We can't use gencache_del + * here, because that uses gencache_get_data_blob for checking + * the existence of a record. We know the thing exists and + * directly store an empty value with 0 timeout. + */ + gencache_set(keystr, "", 0); SAFE_FREE(databuf.dptr); return False; @@ -218,6 +326,137 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout) return True; } +struct stabilize_state { + bool written; + bool error; +}; +static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val, + void *priv); + +/** + * Stabilize gencache + * + * Migrate the clear-if-first gencache data to the stable, + * transaction-based gencache.tdb + */ + +bool gencache_stabilize(void) +{ + struct stabilize_state state; + int res; + char *now; + + if (!gencache_init()) { + return false; + } + + res = tdb_transaction_start(cache); + if (res == -1) { + DEBUG(10, ("Could not start transaction on gencache.tdb: " + "%s\n", tdb_errorstr(cache))); + return false; + } + res = tdb_transaction_start(cache_notrans); + if (res == -1) { + tdb_transaction_cancel(cache); + DEBUG(10, ("Could not start transaction on " + "gencache_notrans.tdb: %s\n", + tdb_errorstr(cache_notrans))); + return false; + } + + state.error = false; + state.written = false; + + res = tdb_traverse(cache_notrans, stabilize_fn, &state); + if ((res == -1) || state.error) { + if ((tdb_transaction_cancel(cache_notrans) == -1) + || (tdb_transaction_cancel(cache) == -1)) { + smb_panic("tdb_transaction_cancel failed\n"); + } + return false; + } + + if (!state.written) { + if ((tdb_transaction_cancel(cache_notrans) == -1) + || (tdb_transaction_cancel(cache) == -1)) { + smb_panic("tdb_transaction_cancel failed\n"); + } + return true; + } + + res = tdb_transaction_commit(cache); + if (res == -1) { + DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: " + "%s\n", tdb_errorstr(cache))); + if (tdb_transaction_cancel(cache_notrans) == -1) { + smb_panic("tdb_transaction_cancel failed\n"); + } + return false; + } + + res = tdb_transaction_commit(cache_notrans); + if (res == -1) { + DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: " + "%s\n", tdb_errorstr(cache))); + return false; + } + + now = talloc_asprintf(talloc_tos(), "%d", (int)time(NULL)); + if (now != NULL) { + tdb_store(cache_notrans, last_stabilize_key(), + string_term_tdb_data(now), 0); + TALLOC_FREE(now); + } + + return true; +} + +static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val, + void *priv) +{ + struct stabilize_state *state = (struct stabilize_state *)priv; + int res; + time_t timeout; + + if (tdb_data_cmp(key, last_stabilize_key()) == 0) { + return 0; + } + + if (!gencache_pull_timeout((char *)val.dptr, &timeout, NULL)) { + DEBUG(10, ("Ignoring invalid entry\n")); + return 0; + } + if ((timeout < time(NULL)) || (val.dsize == 0)) { + res = tdb_delete(cache, key); + if ((res == -1) && (tdb_error(cache) == TDB_ERR_NOEXIST)) { + res = 0; + } else { + state->written = true; + } + } else { + res = tdb_store(cache, key, val, 0); + if (res == 0) { + state->written = true; + } + } + + if (res == -1) { + DEBUG(10, ("Transfer to gencache.tdb failed: %s\n", + tdb_errorstr(cache))); + state->error = true; + return -1; + } + + if (tdb_delete(cache_notrans, key) == -1) { + DEBUG(10, ("tdb_delete from gencache_notrans.tdb failed: " + "%s\n", tdb_errorstr(cache_notrans))); + state->error = true; + return -1; + } + return 0; +} + /** * Get existing entry from the cache file. * @@ -387,6 +626,7 @@ struct gencache_iterate_state { void *priv); const char *pattern; void *priv; + bool in_persistent; }; static int gencache_iterate_fn(struct tdb_context *tdb, TDB_DATA key, @@ -402,6 +642,14 @@ static int gencache_iterate_fn(struct tdb_context *tdb, TDB_DATA key, time_t timeout; char *timeout_endp; + if (tdb_data_cmp(key, last_stabilize_key()) == 0) { + return 0; + } + + if (state->in_persistent && tdb_exists(cache_notrans, key)) { + return 0; + } + if (key.dptr[key.dsize-1] == '\0') { keystr = (char *)key.dptr; } else { @@ -462,5 +710,10 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time state.fn = fn; state.pattern = keystr_pattern; state.priv = data; + + state.in_persistent = false; + tdb_traverse(cache_notrans, gencache_iterate_fn, &state); + + state.in_persistent = true; tdb_traverse(cache, gencache_iterate_fn, &state); } diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 848baeff3d..961e930728 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -82,6 +82,8 @@ static void terminate(void) /* If there was an async dns child - kill it. */ kill_async_dns_child(); + gencache_stabilize(); + pidfile_unlink(); exit(0); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 6951fac171..a1dec0327c 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -868,6 +868,7 @@ static void exit_server_common(enum server_exit_reason how, if (am_parent) { pidfile_unlink(); } + gencache_stabilize(); } /* if we had any open SMB connections when we exited then we diff --git a/source3/utils/net.c b/source3/utils/net.c index 0e3946f5a5..9f29ac42fe 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -762,6 +762,8 @@ static struct functable net_func[] = { DEBUG(2,("return code = %d\n", rc)); + gencache_stabilize(); + libnetapi_free(c->netapi_ctx); poptFreeContext(pc); diff --git a/source3/utils/net_cache.c b/source3/utils/net_cache.c index 74d8d29b4b..36cd12fb82 100644 --- a/source3/utils/net_cache.c +++ b/source3/utils/net_cache.c @@ -297,6 +297,21 @@ static int net_cache_flush(struct net_context *c, int argc, const char **argv) return 0; } +static int net_cache_stabilize(struct net_context *c, int argc, + const char **argv) +{ + if (c->display_usage) { + d_printf("Usage:\n" + "net cache flush\n" + " Delete all cache entries.\n"); + return 0; + } + + if (!gencache_stabilize()) { + return -1; + } + return 0; +} /** * Entry point to 'net cache' subfunctionality * @@ -362,6 +377,14 @@ int net_cache(struct net_context *c, int argc, const char **argv) "net cache flush\n" " Delete all cache entries" }, + { + "stabilize", + net_cache_stabilize, + NET_TRANSPORT_LOCAL, + "Move transient cache content to stable storage", + "net cache stabilize\n" + " Move transient cache content to stable storage" + }, {NULL, NULL, 0, NULL, NULL} }; diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index d617fe1f0b..34eaeb2d79 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -163,6 +163,8 @@ static void terminate(bool is_parent) trustdom_cache_shutdown(); + gencache_stabilize(); + #if 0 if (interactive) { TALLOC_CTX *mem_ctx = talloc_init("end_description"); -- cgit From 3d7dfc1197017c34bdb8dbc6e62460f19bd7d141 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Jul 2009 11:33:04 +0200 Subject: Consolidate string and data_blob routines in gencache --- source3/include/proto.h | 3 +- source3/lib/gencache.c | 194 +++++++++++++------------------------------ source3/libsmb/dsgetdcname.c | 15 ++-- 3 files changed, 65 insertions(+), 147 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index dd49e53338..df7815587c 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -518,7 +518,8 @@ void pull_file_id_24(char *buf, struct file_id *id); bool gencache_set(const char *keystr, const char *value, time_t timeout); bool gencache_del(const char *keystr); bool gencache_get(const char *keystr, char **valstr, time_t *timeout); -bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired); +bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, + time_t *timeout); bool gencache_stabilize(void); bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout); void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr), diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 73f433c1c0..6496ad3ed6 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -26,7 +26,7 @@ #define DBGC_CLASS DBGC_TDB #define TIMEOUT_LEN 12 -#define CACHE_DATA_FMT "%12u/%s" +#define CACHE_DATA_FMT "%12u/" #define READ_CACHE_DATA_FMT_TEMPLATE "%%12u/%%%us" #define BLOB_TYPE "DATA_BLOB" #define BLOB_TYPE_LEN 9 @@ -107,18 +107,19 @@ static TDB_DATA last_stabilize_key(void) * one, then add it. * * @param keystr string that represents a key of this entry - * @param value text representation value being cached + * @param blob DATA_BLOB value being cached * @param timeout time when the value is expired * * @retval true when entry is successfuly stored * @retval false on failure **/ -bool gencache_set(const char *keystr, const char *value, time_t timeout) +bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, + time_t timeout) { int ret; TDB_DATA databuf; - char* valstr = NULL; + char* val; time_t last_stabilize; if (tdb_data_cmp(string_term_tdb_data(keystr), @@ -127,24 +128,35 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout) return false; } - if ((keystr == NULL) || (value == NULL)) { + if ((keystr == NULL) || (blob == NULL)) { return false; } if (!gencache_init()) return False; - if (asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value) == -1) { + val = talloc_asprintf(talloc_tos(), CACHE_DATA_FMT, (int)timeout); + if (val == NULL) { return False; } + val = talloc_realloc(NULL, val, char, talloc_array_length(val)-1); + if (val == NULL) { + return false; + } + val = (char *)talloc_append_blob(NULL, val, *blob); + if (val == NULL) { + return false; + } - databuf = string_term_tdb_data(valstr); - DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout =" - " %s (%d seconds %s)\n", keystr, value,ctime(&timeout), + DEBUG(10, ("Adding cache entry with key = %s and timeout =" + " %s (%d seconds %s)\n", keystr, ctime(&timeout), (int)(timeout - time(NULL)), timeout > time(NULL) ? "ahead" : "in the past")); - ret = tdb_store_bystring(cache_notrans, keystr, databuf, 0); - SAFE_FREE(valstr); + ret = tdb_store_bystring( + cache_notrans, keystr, + make_tdb_data((uint8_t *)val, talloc_array_length(val)), + 0); + TALLOC_FREE(val); if (ret != 0) { return false; @@ -238,8 +250,7 @@ static bool gencache_pull_timeout(char *val, time_t *pres, char **pendptr) * Get existing entry from the cache file. * * @param keystr string that represents a key of this entry - * @param valstr buffer that is allocated and filled with the entry value - * buffer's disposing must be done outside + * @param blob DATA_BLOB that is filled with entry's blob * @param timeout pointer to a time_t that is filled with entry's * timeout * @@ -247,7 +258,8 @@ static bool gencache_pull_timeout(char *val, time_t *pres, char **pendptr) * @retval False for failure **/ -bool gencache_get(const char *keystr, char **valstr, time_t *timeout) +bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, + time_t *timeout) { TDB_DATA databuf; time_t t; @@ -308,11 +320,13 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout) return False; } - if (valstr) { - *valstr = SMB_STRDUP(endptr+1); - if (*valstr == NULL) { + if (blob != NULL) { + *blob = data_blob( + endptr+1, + databuf.dsize - PTR_DIFF(endptr+1, databuf.dptr)); + if (blob->data == NULL) { SAFE_FREE(databuf.dptr); - DEBUG(0, ("strdup failed\n")); + DEBUG(0, ("memdup failed\n")); return False; } } @@ -461,79 +475,39 @@ static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val, * Get existing entry from the cache file. * * @param keystr string that represents a key of this entry - * @param blob DATA_BLOB that is filled with entry's blob - * @param expired pointer to a bool that indicates whether the entry is expired + * @param valstr buffer that is allocated and filled with the entry value + * buffer's disposing must be done outside + * @param timeout pointer to a time_t that is filled with entry's + * timeout * * @retval true when entry is successfuly fetched * @retval False for failure **/ -bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired) +bool gencache_get(const char *keystr, char **value, time_t *ptimeout) { - TDB_DATA databuf; - time_t t; - char *blob_type; - unsigned char *buf = NULL; + DATA_BLOB blob; bool ret = False; - fstring valstr; - int buflen = 0, len = 0, blob_len = 0; - unsigned char *blob_buf = NULL; - if (keystr == NULL) { + ret = gencache_get_data_blob(keystr, &blob, ptimeout); + if (!ret) { return false; } - - if (!gencache_init()) { - return False; - } - - databuf = tdb_fetch_bystring(cache, keystr); - if (!databuf.dptr) { - DEBUG(10,("Cache entry with key = %s couldn't be found\n", - keystr)); - return False; - } - - buf = (unsigned char *)databuf.dptr; - buflen = databuf.dsize; - - len += tdb_unpack(buf+len, buflen-len, "fB", - &valstr, - &blob_len, &blob_buf); - if (len == -1) { - goto out; - } - - t = strtol(valstr, &blob_type, 10); - - if (strcmp(blob_type+1, BLOB_TYPE) != 0) { - goto out; + if ((blob.data == NULL) || (blob.length == 0)) { + SAFE_FREE(blob.data); + return false; } - - DEBUG(10,("Returning %s cache entry: key = %s, " - "timeout = %s", t > time(NULL) ? "valid" : - "expired", keystr, ctime(&t))); - - if (t <= time(NULL)) { - /* We're expired */ - if (expired) { - *expired = True; - } + if (blob.data[blob.length-1] != '\0') { + /* Not NULL terminated, can't be a string */ + SAFE_FREE(blob.data); + return false; } - - if (blob) { - *blob = data_blob(blob_buf, blob_len); - if (!blob->data) { - goto out; - } + *value = SMB_STRDUP((char *)blob.data); + data_blob_free(&blob); + if (*value == NULL) { + return false; } - - ret = True; - out: - SAFE_FREE(blob_buf); - SAFE_FREE(databuf.dptr); - - return ret; + return true; } /** @@ -541,73 +515,17 @@ bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired) * one, then add it. * * @param keystr string that represents a key of this entry - * @param blob DATA_BLOB value being cached + * @param value text representation value being cached * @param timeout time when the value is expired * * @retval true when entry is successfuly stored * @retval false on failure **/ -bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout) +bool gencache_set(const char *keystr, const char *value, time_t timeout) { - bool ret = False; - int tdb_ret; - TDB_DATA databuf; - char *valstr = NULL; - unsigned char *buf = NULL; - int len = 0, buflen = 0; - - if ((keystr == NULL) || (blob == NULL)) { - return false; - } - - if (!gencache_init()) { - return False; - } - - if (asprintf(&valstr, "%12u/%s", (int)timeout, BLOB_TYPE) == -1) { - return False; - } - - again: - len = 0; - - len += tdb_pack(buf+len, buflen-len, "fB", - valstr, - blob->length, blob->data); - - if (len == -1) { - goto out; - } - - if (buflen < len) { - SAFE_FREE(buf); - buf = SMB_MALLOC_ARRAY(unsigned char, len); - if (!buf) { - goto out; - } - buflen = len; - goto again; - } - - databuf = make_tdb_data(buf, len); - - DEBUG(10,("Adding cache entry with key = %s; " - "blob size = %d and timeout = %s" - "(%d seconds %s)\n", keystr, (int)databuf.dsize, - ctime(&timeout), (int)(timeout - time(NULL)), - timeout > time(NULL) ? "ahead" : "in the past")); - - tdb_ret = tdb_store_bystring(cache, keystr, databuf, 0); - if (tdb_ret == 0) { - ret = True; - } - - out: - SAFE_FREE(valstr); - SAFE_FREE(buf); - - return ret; + DATA_BLOB blob = data_blob_const(value, strlen(value)+1); + return gencache_set_data_blob(keystr, &blob, timeout); } /** diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 9552ad1f22..3e0f4977aa 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -339,8 +339,7 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, struct GUID *domain_guid, uint32_t flags, const char *site_name, - struct netr_DsRGetDCNameInfo **info_p, - bool *expired) + struct netr_DsRGetDCNameInfo **info_p) { char *key; DATA_BLOB blob; @@ -354,8 +353,8 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - if (!gencache_get_data_blob(key, &blob, expired)) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + if (!gencache_get_data_blob(key, &blob, NULL)) { + return NT_STATUS_NOT_FOUND; } info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo); @@ -410,11 +409,11 @@ static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx, struct netr_DsRGetDCNameInfo **info) { NTSTATUS status; - bool expired = false; status = dsgetdcname_cache_fetch(mem_ctx, domain_name, domain_guid, - flags, site_name, info, &expired); - if (!NT_STATUS_IS_OK(status)) { + flags, site_name, info); + if (!NT_STATUS_IS_OK(status) + && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { DEBUG(10,("dsgetdcname_cached: cache fetch failed with: %s\n", nt_errstr(status))); return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; @@ -424,7 +423,7 @@ static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx, return status; } - if (expired) { + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { status = dsgetdcname_cache_refresh(mem_ctx, msg_ctx, domain_name, domain_guid, flags, -- cgit From 76705d10c626a66cc77f3ec294f4f98bef95aeb5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Jul 2009 18:31:28 +0200 Subject: Consolidate gencache also every 100 writes in a single process --- source3/lib/gencache.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source3') diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 6496ad3ed6..ee1f4b70b3 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -121,6 +121,7 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, TDB_DATA databuf; char* val; time_t last_stabilize; + static int writecount; if (tdb_data_cmp(string_term_tdb_data(keystr), last_stabilize_key()) == 0) { @@ -162,6 +163,18 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, return false; } + /* + * Every 100 writes within a single process, stabilize the cache with + * a transaction. This is done to prevent a single transaction to + * become huge and chew lots of memory. + */ + writecount += 1; + if (writecount > lp_parm_int(-1, "gencache", "stabilize_count", 100)) { + gencache_stabilize(); + writecount = 0; + goto done; + } + /* * Every 5 minutes, call gencache_stabilize() to not let grow * gencache_notrans.tdb too large. @@ -180,6 +193,7 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, gencache_stabilize(); } +done: return ret == 0; } -- cgit From b4abb190a97456e5176088d9ab555c93fd5ea731 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2009 11:54:07 +0200 Subject: s3:make test: smbtorture from s3 needs to take the config file path via the SMB_CONF_PATH envvar metze --- source3/script/tests/test_smbtorture_s3.sh | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3') diff --git a/source3/script/tests/test_smbtorture_s3.sh b/source3/script/tests/test_smbtorture_s3.sh index 2894d7e90a..602433bd91 100755 --- a/source3/script/tests/test_smbtorture_s3.sh +++ b/source3/script/tests/test_smbtorture_s3.sh @@ -21,6 +21,9 @@ incdir=`dirname $0` . $incdir/test_functions.sh } +SMB_CONF_PATH="$CONFFILE" +export SMB_CONF_PATH + tests="FDPASS LOCK1 LOCK2 LOCK3 LOCK4 LOCK5 LOCK6 LOCK7" #tests="$tests UNLINK BROWSE ATTR TRANS2 MAXFID TORTURE " tests="$tests UNLINK BROWSE ATTR TRANS2 TORTURE " -- cgit From fafe2589e684e1946431722c8845d0dadd9ab525 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2009 09:49:25 +0200 Subject: s3:lib: map ENOSYS to NT_STATUS_NOT_SUPPORTED instead of NT_STATUS_ACCESS_DENIED Jeremy: please check and decide if we want to backport this. metze --- source3/lib/errmap_unix.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3') diff --git a/source3/lib/errmap_unix.c b/source3/lib/errmap_unix.c index 0c39a572ad..00c5475394 100644 --- a/source3/lib/errmap_unix.c +++ b/source3/lib/errmap_unix.c @@ -40,6 +40,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = { { EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, { EMLINK, ERRDOS, ERRgeneral, NT_STATUS_TOO_MANY_LINKS }, { EINTR, ERRHRD, ERRgeneral, NT_STATUS_RETRY }, + { ENOSYS, ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED }, #ifdef ELOOP { ELOOP, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND }, #endif -- cgit From 9e2c50971ee309dfe2f36efa11f572e1d985d057 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2009 09:47:46 +0200 Subject: s3:smbd: check quota access against sec_initial_uid() instead of 0 And return an NTSTATUS mapped from errno. Instead of hardcoded values. metze --- source3/smbd/trans2.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index a862c1466f..d1f2e7ff18 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2952,17 +2952,17 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned fsp.fnum = -1; /* access check */ - if (conn->server_info->utok.uid != 0) { + if (conn->server_info->utok.uid != sec_initial_uid()) { DEBUG(0,("set_user_quota: access_denied " "service [%s] user [%s]\n", lp_servicename(SNUM(conn)), conn->server_info->unix_name)); - return NT_STATUS_DOS(ERRDOS, ERRnoaccess); + return NT_STATUS_ACCESS_DENIED; } if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); - return NT_STATUS_DOS(ERRSRV, ERRerror); + return map_nt_error_from_unix(errno); } data_len = 48; @@ -3446,12 +3446,12 @@ cap_low = 0x%x, cap_high = 0x%x\n", ZERO_STRUCT(quotas); /* access check */ - if ((conn->server_info->utok.uid != 0) + if ((conn->server_info->utok.uid != sec_initial_uid()) ||!CAN_WRITE(conn)) { DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n", lp_servicename(SNUM(conn)), conn->server_info->unix_name)); - reply_doserror(req, ERRSRV, ERRaccess); + reply_nterror(req, NT_STATUS_ACCESS_DENIED); return; } @@ -3520,7 +3520,7 @@ cap_low = 0x%x, cap_high = 0x%x\n", /* now set the quotas */ if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); - reply_doserror(req, ERRSRV, ERRerror); + reply_nterror(req, map_nt_error_from_unix(errno)); return; } -- cgit From 9df1c8f2ad25a1875f2ca98df8c600aecf058144 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 09:23:36 +0200 Subject: s3:smbd: return NT_STATUS_INVALID_INFO_CLASS in SMB2 GetInfo metze --- source3/smbd/smb2_getinfo.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index b6b7462e90..cba6da45ce 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -297,7 +297,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, if (INFO_LEVEL_IS_UNIX(file_info_level)) { /* Always do lstat for UNIX calls. */ if (SMB_VFS_LSTAT(conn, smb_fname)) { - DEBUG(3,("call_trans2qfilepathinfo: " + DEBUG(3,("smbd_smb2_getinfo_send: " "SMB_VFS_LSTAT of %s failed " "(%s)\n", smb_fname_str_dbg(smb_fname), @@ -307,7 +307,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } } else if (SMB_VFS_STAT(conn, smb_fname)) { - DEBUG(3,("call_trans2qfilepathinfo: " + DEBUG(3,("smbd_smb2_getinfo_send: " "SMB_VFS_STAT of %s failed (%s)\n", smb_fname_str_dbg(smb_fname), strerror(errno))); @@ -324,7 +324,8 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, */ if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { - DEBUG(3, ("fstat of fnum %d failed (%s)\n", + DEBUG(3, ("smbd_smb2_getinfo_send: " + "fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); status = map_nt_error_from_unix(errno); tevent_req_nterror(req, status); @@ -350,6 +351,9 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, &data_size); if (!NT_STATUS_IS_OK(status)) { SAFE_FREE(data); + if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) { + status = NT_STATUS_INVALID_INFO_CLASS; + } tevent_req_nterror(req, status); return tevent_req_post(req, ev); } -- cgit From d85cc986b85d3c8a6e40491f216c801a1cbde2ab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 12:08:20 +0200 Subject: s3:smbd: implement SMB2 GetInfo with Fs*Information metze --- source3/smbd/smb2_getinfo.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'source3') diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index cba6da45ce..f8c2d41e31 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -370,6 +370,53 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, break; } + case 0x02:/* SMB2_GETINFO_FS */ + { + uint16_t file_info_level; + char *data = NULL; + int data_size = 0; + NTSTATUS status; + SMB_STRUCT_STAT st; + + /* the levels directly map to the passthru levels */ + file_info_level = in_file_info_class + 1000; + + if (vfs_stat_smb_fname(conn,".",&st)!=0) { + DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", + strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + + status = smbd_do_qfsinfo(conn, state, + file_info_level, + st, + STR_UNICODE, + in_output_buffer_length, + &data, + &data_size); + if (!NT_STATUS_IS_OK(status)) { + SAFE_FREE(data); + if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) { + status = NT_STATUS_INVALID_INFO_CLASS; + } + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + if (data_size > 0) { + state->out_output_buffer = data_blob_talloc(state, + data, + data_size); + SAFE_FREE(data); + if (tevent_req_nomem(state->out_output_buffer.data, req)) { + return tevent_req_post(req, ev); + } + } + SAFE_FREE(data); + break; + } + default: tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return tevent_req_post(req, ev); -- cgit From 722cd5944f9b70c7f642ec1d510d54bf1592beb5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Jul 2009 09:23:57 +0200 Subject: s3:smbd: add support for SMB2 SetInfo File*Information metze --- source3/smbd/smb2_setinfo.c | 129 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c index 110ce6c64a..2974695c9f 100644 --- a/source3/smbd/smb2_setinfo.c +++ b/source3/smbd/smb2_setinfo.c @@ -200,7 +200,134 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED); + if (IS_IPC(conn)) { + tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); + return tevent_req_post(req, ev); + } + + switch (in_info_type) { + case 0x01:/* SMB2_SETINFO_FILE */ + { + uint16_t file_info_level; + struct smb_filename *smb_fname = NULL; + char *data; + int data_size; + int ret_size = 0; + NTSTATUS status; + + + file_info_level = in_file_info_class + 1000; + if (file_info_level == SMB_FILE_RENAME_INFORMATION) { + file_info_level = 0xFF00 + in_file_info_class; + } + + status = create_synthetic_smb_fname_split(state, + fsp->fsp_name, + NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + + if (fsp->is_directory || fsp->fh->fd == -1) { + /* + * This is actually a SETFILEINFO on a directory + * handle (returned from an NT SMB). NT5.0 seems + * to do this call. JRA. + */ + if (INFO_LEVEL_IS_UNIX(file_info_level)) { + /* Always do lstat for UNIX calls. */ + if (SMB_VFS_LSTAT(conn, smb_fname)) { + DEBUG(3,("smbd_smb2_setinfo_send: " + "SMB_VFS_LSTAT of %s failed " + "(%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + } else { + if (SMB_VFS_STAT(conn, smb_fname) != 0) { + DEBUG(3,("smbd_smb2_setinfo_send: " + "fileinfo of %s failed (%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + } + } else if (fsp->print_file) { + /* + * Doing a DELETE_ON_CLOSE should cancel a print job. + */ + if ((file_info_level == SMB_SET_FILE_DISPOSITION_INFO) + && in_input_buffer.length >= 1 + && CVAL(in_input_buffer.data,0)) { + fsp->fh->private_options |= FILE_DELETE_ON_CLOSE; + + DEBUG(3,("smbd_smb2_setinfo_send: " + "Cancelling print job (%s)\n", + fsp->fsp_name)); + + tevent_req_done(req); + return tevent_req_post(req, ev); + } else { + tevent_req_nterror(req, + NT_STATUS_OBJECT_PATH_INVALID); + return tevent_req_post(req, ev); + } + } else { + /* + * Original code - this is an open file. + */ + + if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + DEBUG(3,("smbd_smb2_setinfo_send: fstat " + "of fnum %d failed (%s)\n", fsp->fnum, + strerror(errno))); + status = map_nt_error_from_unix(errno); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + } + + data = NULL; + data_size = in_input_buffer.length; + if (data_size > 0) { + data = (char *)SMB_MALLOC_ARRAY(char, data_size); + if (tevent_req_nomem(data, req)) { + + } + memcpy(data, in_input_buffer.data, data_size); + } + + status = smbd_do_setfilepathinfo(conn, smbreq, state, + file_info_level, + fsp, + smb_fname, + &data, + data_size, + &ret_size); + SAFE_FREE(data); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) { + status = NT_STATUS_INVALID_INFO_CLASS; + } + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + break; + } + + default: + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + tevent_req_done(req); return tevent_req_post(req, ev); } -- cgit From 5b594c695884aebdfbb199549901fea954122929 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 15 Jul 2009 14:00:42 +0200 Subject: s3:dbwrap: add a wrapper dbwrap_trans_do() This function wraps the action() callback into a db transaction and the transaction is either committed or cancelled, depending on the return value of the action function. Michael --- source3/include/proto.h | 3 +++ source3/lib/dbwrap_util.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index df7815587c..74cedcec18 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -454,6 +454,9 @@ NTSTATUS dbwrap_trans_store_uint32(struct db_context *db, const char *keystr, NTSTATUS dbwrap_trans_store_bystring(struct db_context *db, const char *key, TDB_DATA data, int flags); NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key); +NTSTATUS dbwrap_trans_do(struct db_context *db, + NTSTATUS (*action)(struct db_context *, void *), + void *private_data); /* The following definitions come from lib/debug.c */ diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 3be3a49e7d..67471b5c96 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -307,3 +307,36 @@ NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key) { return dbwrap_trans_delete(db, string_term_tdb_data(key)); } + +/** + * Wrap db action(s) into a transaction. + */ +NTSTATUS dbwrap_trans_do(struct db_context *db, + NTSTATUS (*action)(struct db_context *, void *), + void *private_data) +{ + int res; + NTSTATUS status; + + res = db->transaction_start(db); + if (res != 0) { + DEBUG(5, ("transaction_start failed\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = action(db, private_data); + if (!NT_STATUS_IS_OK(status)) { + if (db->transaction_cancel(db) != 0) { + smb_panic("Cancelling transaction failed"); + } + return status; + } + + res = db->transaction_commit(db); + if (res == 0) { + return NT_STATUS_OK; + } + + DEBUG(2, ("transaction_commit failed\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; +} -- cgit From 804d3f897be01e9088deefe807cd06fe194c5d58 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 16:02:19 +0200 Subject: s3:dbwrap: add dbwrap_delete_bystring_upper() To delete a key whose name is not given in but stored in uppercase. Michael --- source3/include/proto.h | 1 + source3/lib/dbwrap_util.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 74cedcec18..4bc4cd197b 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -457,6 +457,7 @@ NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key); NTSTATUS dbwrap_trans_do(struct db_context *db, NTSTATUS (*action)(struct db_context *, void *), void *private_data); +NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key); /* The following definitions come from lib/debug.c */ diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 67471b5c96..aca4b52697 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -340,3 +340,19 @@ NTSTATUS dbwrap_trans_do(struct db_context *db, DEBUG(2, ("transaction_commit failed\n")); return NT_STATUS_INTERNAL_DB_CORRUPTION; } + +NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key) +{ + char *key_upper; + NTSTATUS status; + + key_upper = talloc_strdup_upper(talloc_tos(), key); + if (key_upper == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = dbwrap_delete_bystring(db, key_upper); + + talloc_free(key_upper); + return status; +} -- cgit From 32a3275344819cfcbcb4540a1909617b8db6dc63 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 16:08:41 +0200 Subject: s3:dbwrap: add dbwrap_store_bystring_upper(). This stores a key under the uppercase version of the given keyname. Michael --- source3/include/proto.h | 2 ++ source3/lib/dbwrap_util.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 4bc4cd197b..81892f294d 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -458,6 +458,8 @@ NTSTATUS dbwrap_trans_do(struct db_context *db, NTSTATUS (*action)(struct db_context *, void *), void *private_data); NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key); +NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key, + TDB_DATA data, int flags); /* The following definitions come from lib/debug.c */ diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index aca4b52697..154bf6b553 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -356,3 +356,20 @@ NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key) talloc_free(key_upper); return status; } + +NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key, + TDB_DATA data, int flags) +{ + char *key_upper; + NTSTATUS status; + + key_upper = talloc_strdup_upper(talloc_tos(), key); + if (key_upper == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = dbwrap_store_bystring(db, key_upper, data, flags); + + talloc_free(key_upper); + return status; +} -- cgit From 3b3125fc23dc4b7a403d17af2ad2d5c592d3d090 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 16:13:07 +0200 Subject: s3:dbwrap: add dbwrap_fetch_bystring_upper(). To fetch a key whose name is stored but not given in upper case. Michael --- source3/include/proto.h | 2 ++ source3/lib/dbwrap_util.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 81892f294d..56bffd5ce7 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -460,6 +460,8 @@ NTSTATUS dbwrap_trans_do(struct db_context *db, NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key); NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key, TDB_DATA data, int flags); +TDB_DATA dbwrap_fetch_bystring_upper(struct db_context *db, TALLOC_CTX *mem_ctx, + const char *key); /* The following definitions come from lib/debug.c */ diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 154bf6b553..01c18439c3 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -373,3 +373,20 @@ NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key, talloc_free(key_upper); return status; } + +TDB_DATA dbwrap_fetch_bystring_upper(struct db_context *db, TALLOC_CTX *mem_ctx, + const char *key) +{ + char *key_upper; + TDB_DATA result; + + key_upper = talloc_strdup_upper(talloc_tos(), key); + if (key_upper == NULL) { + return make_tdb_data(NULL, 0); + } + + result = dbwrap_fetch_bystring(db, mem_ctx, key_upper); + + talloc_free(key_upper); + return result; +} -- cgit From 3071b0712211b17b464f62d544fa16da5a128b01 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 15 Jul 2009 09:58:02 +0200 Subject: s3:dbwrap_util: add my C Michael --- source3/lib/dbwrap_util.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 01c18439c3..6c95672986 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. Utility functions for the dbwrap API Copyright (C) Volker Lendecke 2007 + Copyrithg (C) Michael Adam 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From d554c0d7a923f1194463481f0bd829042cee574a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 16:16:18 +0200 Subject: s3:registry: don't store differently cased entries for the same keys. This happened for instance during registry initialization, when entries for HKLM\Software and HKLM\SOFTWARE were created. Searching these entries was case insensitive though. But the entries ended up in the subkey-lists anyways. This is solved by making the subkeys_hash in the regsubkey_container structs case insensitive (using the new _bystring_upper() wrappers). Michael --- source3/registry/reg_objects.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index 5ae1cd8aa7..a592c76e1d 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -89,7 +89,7 @@ static WERROR regsubkey_ctr_hash_keyname(struct regsubkey_ctr *ctr, { WERROR werr; - werr = ntstatus_to_werror(dbwrap_store_bystring(ctr->subkeys_hash, + werr = ntstatus_to_werror(dbwrap_store_bystring_upper(ctr->subkeys_hash, keyname, make_tdb_data((uint8 *)&idx, sizeof(idx)), @@ -107,7 +107,7 @@ static WERROR regsubkey_ctr_unhash_keyname(struct regsubkey_ctr *ctr, { WERROR werr; - werr = ntstatus_to_werror(dbwrap_delete_bystring(ctr->subkeys_hash, + werr = ntstatus_to_werror(dbwrap_delete_bystring_upper(ctr->subkeys_hash, keyname)); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, ("error unhashing key '%s' in container: %s\n", @@ -127,7 +127,7 @@ static WERROR regsubkey_ctr_index_for_keyname(struct regsubkey_ctr *ctr, return WERR_INVALID_PARAM; } - data = dbwrap_fetch_bystring(ctr->subkeys_hash, ctr, keyname); + data = dbwrap_fetch_bystring_upper(ctr->subkeys_hash, ctr, keyname); if (data.dptr == NULL) { return WERR_NOT_FOUND; } -- cgit From 2b380c73a4796bdf69264e5ca6721ad0d67087e9 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 16:40:43 +0200 Subject: s3:registry: add db_context argument to regdb_delete_key_with_prefix() Michael --- source3/registry/reg_backend_db.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index e296d319e2..bdb237aafc 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -511,7 +511,8 @@ int regdb_get_seqnum(void) } -static WERROR regdb_delete_key_with_prefix(const char *keyname, +static WERROR regdb_delete_key_with_prefix(struct db_context *db, + const char *keyname, const char *prefix) { char *path; @@ -537,7 +538,7 @@ static WERROR regdb_delete_key_with_prefix(const char *keyname, goto done; } - werr = ntstatus_to_werror(dbwrap_delete_bystring(regdb, path)); + werr = ntstatus_to_werror(dbwrap_delete_bystring(db, path)); /* treat "not" found" as ok */ if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) { @@ -552,17 +553,17 @@ done: static WERROR regdb_delete_values(const char *keyname) { - return regdb_delete_key_with_prefix(keyname, REG_VALUE_PREFIX); + return regdb_delete_key_with_prefix(regdb, keyname, REG_VALUE_PREFIX); } static WERROR regdb_delete_secdesc(const char *keyname) { - return regdb_delete_key_with_prefix(keyname, REG_SECDESC_PREFIX); + return regdb_delete_key_with_prefix(regdb, keyname, REG_SECDESC_PREFIX); } static WERROR regdb_delete_subkeylist(const char *keyname) { - return regdb_delete_key_with_prefix(keyname, NULL); + return regdb_delete_key_with_prefix(regdb, keyname, NULL); } static WERROR regdb_delete_key_lists(const char *keyname) -- cgit From ec6b6727d824bea1b4a7b320e7a3c1de38df6724 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 16:42:20 +0200 Subject: s3:registry: add db_context argument to regdb_delete_values() Michael --- source3/registry/reg_backend_db.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index bdb237aafc..bcec77926b 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -551,9 +551,9 @@ done: } -static WERROR regdb_delete_values(const char *keyname) +static WERROR regdb_delete_values(struct db_context *db, const char *keyname) { - return regdb_delete_key_with_prefix(regdb, keyname, REG_VALUE_PREFIX); + return regdb_delete_key_with_prefix(db, keyname, REG_VALUE_PREFIX); } static WERROR regdb_delete_secdesc(const char *keyname) @@ -570,7 +570,7 @@ static WERROR regdb_delete_key_lists(const char *keyname) { WERROR werr; - werr = regdb_delete_values(keyname); + werr = regdb_delete_values(regdb, keyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", REG_VALUE_PREFIX, keyname, win_errstr(werr))); -- cgit From bd983dba6b308c28019c2e39f16de8b9e434e4f5 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 16:44:20 +0200 Subject: s3:registry: add db_context argument to regdb_delete_secdesc() Michael --- source3/registry/reg_backend_db.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index bcec77926b..1a6ae7bb45 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -556,9 +556,9 @@ static WERROR regdb_delete_values(struct db_context *db, const char *keyname) return regdb_delete_key_with_prefix(db, keyname, REG_VALUE_PREFIX); } -static WERROR regdb_delete_secdesc(const char *keyname) +static WERROR regdb_delete_secdesc(struct db_context *db, const char *keyname) { - return regdb_delete_key_with_prefix(regdb, keyname, REG_SECDESC_PREFIX); + return regdb_delete_key_with_prefix(db, keyname, REG_SECDESC_PREFIX); } static WERROR regdb_delete_subkeylist(const char *keyname) @@ -577,7 +577,7 @@ static WERROR regdb_delete_key_lists(const char *keyname) goto done; } - werr = regdb_delete_secdesc(keyname); + werr = regdb_delete_secdesc(regdb, keyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", REG_SECDESC_PREFIX, keyname, win_errstr(werr))); -- cgit From 86e927cb056b30be3b2eecc1375549de71419b1f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 16:48:36 +0200 Subject: s3:registry: add db_context argument to regdb_delete_subkeylist() Michael --- source3/registry/reg_backend_db.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 1a6ae7bb45..69676b19e6 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -561,9 +561,9 @@ static WERROR regdb_delete_secdesc(struct db_context *db, const char *keyname) return regdb_delete_key_with_prefix(db, keyname, REG_SECDESC_PREFIX); } -static WERROR regdb_delete_subkeylist(const char *keyname) +static WERROR regdb_delete_subkeylist(struct db_context *db, const char *keyname) { - return regdb_delete_key_with_prefix(regdb, keyname, NULL); + return regdb_delete_key_with_prefix(db, keyname, NULL); } static WERROR regdb_delete_key_lists(const char *keyname) @@ -584,7 +584,7 @@ static WERROR regdb_delete_key_lists(const char *keyname) goto done; } - werr = regdb_delete_subkeylist(keyname); + werr = regdb_delete_subkeylist(regdb, keyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, (__location__ " Deleting %s failed: %s\n", keyname, win_errstr(werr))); -- cgit From 528bf38875b9e5412da0a2810b17f05b2c376312 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 16:51:26 +0200 Subject: s3:registry: add db_context argument to regdb_delete_key_lists() Michael --- source3/registry/reg_backend_db.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 69676b19e6..700db0140f 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -566,25 +566,25 @@ static WERROR regdb_delete_subkeylist(struct db_context *db, const char *keyname return regdb_delete_key_with_prefix(db, keyname, NULL); } -static WERROR regdb_delete_key_lists(const char *keyname) +static WERROR regdb_delete_key_lists(struct db_context *db, const char *keyname) { WERROR werr; - werr = regdb_delete_values(regdb, keyname); + werr = regdb_delete_values(db, keyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", REG_VALUE_PREFIX, keyname, win_errstr(werr))); goto done; } - werr = regdb_delete_secdesc(regdb, keyname); + werr = regdb_delete_secdesc(db, keyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", REG_SECDESC_PREFIX, keyname, win_errstr(werr))); goto done; } - werr = regdb_delete_subkeylist(regdb, keyname); + werr = regdb_delete_subkeylist(db, keyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, (__location__ " Deleting %s failed: %s\n", keyname, win_errstr(werr))); @@ -810,7 +810,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - werr = regdb_delete_key_lists(path); + werr = regdb_delete_key_lists(regdb, path); W_ERROR_NOT_OK_GOTO(werr, cancel); TALLOC_FREE(path); @@ -984,7 +984,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) werr = regdb_transaction_start(); W_ERROR_NOT_OK_GOTO_DONE(werr); - werr = regdb_delete_key_lists(path); + werr = regdb_delete_key_lists(regdb, path); W_ERROR_NOT_OK_GOTO(werr, cancel); werr = regsubkey_ctr_init(mem_ctx, &subkeys); -- cgit From a18a10c07a3e32644c31f4742805795998227e44 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 17:00:44 +0200 Subject: s3:registry: add db_context argument to regdb_store_keys_internal() Michael --- source3/registry/reg_backend_db.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 700db0140f..f4a269ef46 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -601,7 +601,9 @@ done: fstrings ***********************************************************************/ -static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr) +static bool regdb_store_keys_internal(struct db_context *db, + const char *key, + struct regsubkey_ctr *ctr) { TDB_DATA dbuf; uint8 *buffer = NULL; @@ -675,7 +677,7 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr dbuf.dptr = buffer; dbuf.dsize = len; - status = dbwrap_store_bystring(regdb, keyname, dbuf, TDB_REPLACE); + status = dbwrap_store_bystring(db, keyname, dbuf, TDB_REPLACE); if (!NT_STATUS_IS_OK(status)) { ret = false; goto done; @@ -688,7 +690,7 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr keyname = talloc_asprintf(ctx, "%s/%s", REG_SORTED_SUBKEYS_PREFIX, keyname); if (keyname != NULL) { - dbwrap_delete_bystring(regdb, keyname); + dbwrap_delete_bystring(db, keyname); } done: @@ -820,7 +822,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) /* (2) store the subkey list for the parent */ - if (!regdb_store_keys_internal(key, ctr) ) { + if (!regdb_store_keys_internal(regdb, key, ctr)) { DEBUG(0,("regdb_store_keys: Failed to store new subkey list " "for parent [%s]\n", key)); goto cancel; @@ -837,7 +839,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - if (!regdb_store_keys_internal(key, subkeys)) { + if (!regdb_store_keys_internal(regdb, key, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]\n", key)); goto cancel; @@ -861,7 +863,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) if (regdb_fetch_keys( path, subkeys ) == -1) { /* create a record with 0 subkeys */ - if (!regdb_store_keys_internal(path, subkeys)) { + if (!regdb_store_keys_internal(regdb, path, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]\n", path)); goto cancel; @@ -931,7 +933,7 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_addkey(subkeys, subkey); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (!regdb_store_keys_internal(key, subkeys)) { + if (!regdb_store_keys_internal(regdb, key, subkeys)) { DEBUG(0, (__location__ " failed to store new subkey list for " "parent key %s\n", key)); werr = WERR_REG_IO_FAILURE; @@ -998,7 +1000,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_delkey(subkeys, subkey); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (!regdb_store_keys_internal(key, subkeys)) { + if (!regdb_store_keys_internal(regdb, key, subkeys)) { DEBUG(0, (__location__ " failed to store new subkey_list for " "parent key %s\n", key)); werr = WERR_REG_IO_FAILURE; -- cgit From c01d955ac0b6ef686cf026cc90074cd52a1a30ae Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 17:10:09 +0200 Subject: s3:registry: add db_context argument to regdb_fetch_key_internal() Michael --- source3/registry/reg_backend_db.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index f4a269ef46..165c0abf59 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1027,7 +1027,8 @@ done: return werr; } -static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key) +static TDB_DATA regdb_fetch_key_internal(struct db_context *db, + TALLOC_CTX *mem_ctx, const char *key) { char *path = NULL; TDB_DATA data; @@ -1037,7 +1038,7 @@ static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key) return make_tdb_data(NULL, 0); } - data = dbwrap_fetch_bystring(regdb, mem_ctx, path); + data = dbwrap_fetch_bystring(db, mem_ctx, path); TALLOC_FREE(path); return data; @@ -1325,7 +1326,7 @@ static bool regdb_key_exists(const char *key) p = strrchr(path, '/'); if (p == NULL) { /* this is a base key */ - value = regdb_fetch_key_internal(mem_ctx, path); + value = regdb_fetch_key_internal(regdb, mem_ctx, path); ret = (value.dptr != NULL); } else { *p = '\0'; @@ -1366,7 +1367,7 @@ int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) goto done; } - value = regdb_fetch_key_internal(frame, key); + value = regdb_fetch_key_internal(regdb, frame, key); if (value.dptr == NULL) { DEBUG(10, ("regdb_fetch_keys: no subkeys found for key [%s]\n", @@ -1501,7 +1502,7 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values) values->seqnum = regdb_get_seqnum(); - value = regdb_fetch_key_internal(ctx, keystr); + value = regdb_fetch_key_internal(regdb, ctx, keystr); if (!value.dptr) { /* all keys have zero values by default */ -- cgit From db4f797e3533b97df844a50a92e8a27a9248092b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 17:18:19 +0200 Subject: s3:registry: add db_context argument to scan_parent_subkeys() Michael --- source3/registry/reg_backend_db.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 165c0abf59..562e29742d 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1245,7 +1245,8 @@ static int parent_subkey_scanner(TDB_DATA key, TDB_DATA data, return 0; } -static bool scan_parent_subkeys(const char *parent, const char *name) +static bool scan_parent_subkeys(struct db_context *db, const char *parent, + const char *name) { char *path = NULL; char *key = NULL; @@ -1272,8 +1273,8 @@ static bool scan_parent_subkeys(const char *parent, const char *name) } state.scanned = false; - res = regdb->parse_record(regdb, string_term_tdb_data(key), - parent_subkey_scanner, &state); + res = db->parse_record(db, string_term_tdb_data(key), + parent_subkey_scanner, &state); if (state.scanned) { result = state.found; @@ -1281,8 +1282,8 @@ static bool scan_parent_subkeys(const char *parent, const char *name) if (!create_sorted_subkeys(path, key)) { goto fail; } - res = regdb->parse_record(regdb, string_term_tdb_data(key), - parent_subkey_scanner, &state); + res = db->parse_record(db, string_term_tdb_data(key), + parent_subkey_scanner, &state); if ((res == 0) && (state.scanned)) { result = state.found; } @@ -1330,7 +1331,7 @@ static bool regdb_key_exists(const char *key) ret = (value.dptr != NULL); } else { *p = '\0'; - ret = scan_parent_subkeys(path, p+1); + ret = scan_parent_subkeys(regdb, path, p+1); } done: -- cgit From 589bacfbdb7541be5d339fcaf08272520bf6a1ac Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 3 Jul 2009 17:39:17 +0200 Subject: s3:registry: create regdb_fetch_keys_internal() with db_context argument and let exported regdb_fetch_keys() just call regdb_fetch_keys_internal() with regdb as an argument. Internally, in reg_backend_db.c, always use the _internal version. Michael --- source3/registry/reg_backend_db.c | 62 ++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 27 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 562e29742d..efbd678437 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -27,8 +27,10 @@ static struct db_context *regdb = NULL; static int regdb_refcount; -static bool regdb_key_exists(const char *key); +static bool regdb_key_exists(struct db_context *db, const char *key); static bool regdb_key_is_base_key(const char *key); +static int regdb_fetch_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr); /* List the deepest path into the registry. All part components will be created.*/ @@ -173,7 +175,7 @@ static WERROR init_registry_key_internal(const char *add_path) goto fail; } - regdb_fetch_keys(base, subkeys); + regdb_fetch_keys_internal(regdb, base, subkeys); if (*subkeyname) { werr = regsubkey_ctr_addkey(subkeys, subkeyname); if (!W_ERROR_IS_OK(werr)) { @@ -202,7 +204,7 @@ WERROR init_registry_key(const char *add_path) { WERROR werr; - if (regdb_key_exists(add_path)) { + if (regdb_key_exists(regdb, add_path)) { return WERR_OK; } @@ -248,7 +250,7 @@ WERROR init_registry_data(void) * If all do already exist, we can save the writes. */ for (i=0; builtin_registry_paths[i] != NULL; i++) { - if (!regdb_key_exists(builtin_registry_paths[i])) { + if (!regdb_key_exists(regdb, builtin_registry_paths[i])) { goto do_init; } } @@ -294,7 +296,7 @@ do_init: /* loop over all of the predefined paths and add each component */ for (i=0; builtin_registry_paths[i] != NULL; i++) { - if (regdb_key_exists(builtin_registry_paths[i])) { + if (regdb_key_exists(regdb, builtin_registry_paths[i])) { continue; } werr = init_registry_key_internal(builtin_registry_paths[i]); @@ -713,7 +715,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) TALLOC_CTX *ctx = talloc_stackframe(); WERROR werr; - if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { + if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { goto fail; } @@ -728,7 +730,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) return false; } - regdb_fetch_keys(key, old_subkeys); + regdb_fetch_keys_internal(regdb, key, old_subkeys); num_subkeys = regsubkey_ctr_numkeys(ctr); old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys); @@ -770,7 +772,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - regdb_fetch_keys(key, old_subkeys); + regdb_fetch_keys_internal(regdb, key, old_subkeys); /* * Make the store operation as safe as possible without transactions: @@ -861,7 +863,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - if (regdb_fetch_keys( path, subkeys ) == -1) { + if (regdb_fetch_keys_internal(regdb, path, subkeys) == -1) { /* create a record with 0 subkeys */ if (!regdb_store_keys_internal(regdb, path, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " @@ -899,7 +901,7 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) struct regsubkey_ctr *subkeys; TALLOC_CTX *mem_ctx = talloc_stackframe(); - if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { + if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { werr = WERR_NOT_FOUND; goto done; } @@ -907,7 +909,7 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - if (regdb_fetch_keys(key, subkeys) < 0) { + if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { werr = WERR_REG_IO_FAILURE; goto done; } @@ -925,7 +927,7 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (regdb_fetch_keys(key, subkeys) < 0) { + if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { werr = WERR_REG_IO_FAILURE; goto cancel; } @@ -967,7 +969,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) char *path; TALLOC_CTX *mem_ctx = talloc_stackframe(); - if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { + if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { werr = WERR_NOT_FOUND; goto done; } @@ -978,7 +980,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) goto done; } - if (!regdb_key_exists(path)) { + if (!regdb_key_exists(regdb, path)) { werr = WERR_OK; goto done; } @@ -992,7 +994,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (regdb_fetch_keys(key, subkeys) < 0) { + if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { werr = WERR_REG_IO_FAILURE; goto cancel; } @@ -1128,7 +1130,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) goto fail; } - res = regdb_fetch_keys(key, ctr); + res = regdb_fetch_keys_internal(regdb, key, ctr); if (res == -1) { goto fail; } @@ -1303,7 +1305,7 @@ static bool scan_parent_subkeys(struct db_context *db, const char *parent, * The exeption of this are keys without a parent key, * i.e. the "base" keys (HKLM, HKCU, ...). */ -static bool regdb_key_exists(const char *key) +static bool regdb_key_exists(struct db_context *db, const char *key) { TALLOC_CTX *mem_ctx = talloc_stackframe(); TDB_DATA value; @@ -1327,11 +1329,11 @@ static bool regdb_key_exists(const char *key) p = strrchr(path, '/'); if (p == NULL) { /* this is a base key */ - value = regdb_fetch_key_internal(regdb, mem_ctx, path); + value = regdb_fetch_key_internal(db, mem_ctx, path); ret = (value.dptr != NULL); } else { *p = '\0'; - ret = scan_parent_subkeys(regdb, path, p+1); + ret = scan_parent_subkeys(db, path, p+1); } done: @@ -1345,7 +1347,8 @@ done: released by the caller. ***********************************************************************/ -int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) +static int regdb_fetch_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr) { WERROR werr; uint32 num_items; @@ -1359,16 +1362,16 @@ int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL")); - if (!regdb_key_exists(key)) { + if (!regdb_key_exists(db, key)) { goto done; } - werr = regsubkey_ctr_set_seqnum(ctr, regdb_get_seqnum()); + werr = regsubkey_ctr_set_seqnum(ctr, db->get_seqnum(db)); if (!W_ERROR_IS_OK(werr)) { goto done; } - value = regdb_fetch_key_internal(regdb, frame, key); + value = regdb_fetch_key_internal(db, frame, key); if (value.dptr == NULL) { DEBUG(10, ("regdb_fetch_keys: no subkeys found for key [%s]\n", @@ -1399,6 +1402,11 @@ done: return ret; } +int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) +{ + return regdb_fetch_keys_internal(regdb, key, ctr); +} + /**************************************************************************** Unpack a list of registry values frem the TDB ***************************************************************************/ @@ -1492,7 +1500,7 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values) DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key)); - if (!regdb_key_exists(key)) { + if (!regdb_key_exists(regdb, key)) { goto done; } @@ -1529,7 +1537,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values) DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key)); - if (!regdb_key_exists(key)) { + if (!regdb_key_exists(regdb, key)) { goto done; } @@ -1587,7 +1595,7 @@ static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key, DEBUG(10, ("regdb_get_secdesc: Getting secdesc of key [%s]\n", key)); - if (!regdb_key_exists(key)) { + if (!regdb_key_exists(regdb, key)) { err = WERR_BADFILE; goto done; } @@ -1627,7 +1635,7 @@ static WERROR regdb_set_secdesc(const char *key, WERROR err = WERR_NOMEM; TDB_DATA tdbdata; - if (!regdb_key_exists(key)) { + if (!regdb_key_exists(regdb, key)) { err = WERR_BADFILE; goto done; } -- cgit From eb1958ca3d6cd30e292d2d013ff1ea63e65563fb Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 11:11:10 +0200 Subject: s3:registry: rename regdb_store_keys_internal() to regdb_store_keys_internal2() Michael --- source3/registry/reg_backend_db.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index efbd678437..c29bd79525 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -603,9 +603,9 @@ done: fstrings ***********************************************************************/ -static bool regdb_store_keys_internal(struct db_context *db, - const char *key, - struct regsubkey_ctr *ctr) +static bool regdb_store_keys_internal2(struct db_context *db, + const char *key, + struct regsubkey_ctr *ctr) { TDB_DATA dbuf; uint8 *buffer = NULL; @@ -824,7 +824,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) /* (2) store the subkey list for the parent */ - if (!regdb_store_keys_internal(regdb, key, ctr)) { + if (!regdb_store_keys_internal2(regdb, key, ctr)) { DEBUG(0,("regdb_store_keys: Failed to store new subkey list " "for parent [%s]\n", key)); goto cancel; @@ -841,7 +841,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - if (!regdb_store_keys_internal(regdb, key, subkeys)) { + if (!regdb_store_keys_internal2(regdb, key, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]\n", key)); goto cancel; @@ -865,7 +865,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) if (regdb_fetch_keys_internal(regdb, path, subkeys) == -1) { /* create a record with 0 subkeys */ - if (!regdb_store_keys_internal(regdb, path, subkeys)) { + if (!regdb_store_keys_internal2(regdb, path, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]\n", path)); goto cancel; @@ -935,7 +935,7 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_addkey(subkeys, subkey); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (!regdb_store_keys_internal(regdb, key, subkeys)) { + if (!regdb_store_keys_internal2(regdb, key, subkeys)) { DEBUG(0, (__location__ " failed to store new subkey list for " "parent key %s\n", key)); werr = WERR_REG_IO_FAILURE; @@ -1002,7 +1002,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_delkey(subkeys, subkey); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (!regdb_store_keys_internal(regdb, key, subkeys)) { + if (!regdb_store_keys_internal2(regdb, key, subkeys)) { DEBUG(0, (__location__ " failed to store new subkey_list for " "parent key %s\n", key)); werr = WERR_REG_IO_FAILURE; @@ -1097,7 +1097,7 @@ done: * parent_subkey_scanner. The code uses parse_record() to avoid a memcpy of * the potentially large subkey record. * - * The sorted subkey record is deleted in regdb_store_keys_internal and + * The sorted subkey record is deleted in regdb_store_keys_internal2 and * recreated on demand. */ -- cgit From 1dfaa371fa027351a0af6e56a04bc045c3b0dc73 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 11:31:28 +0200 Subject: s3:registry: create regdb_store_keys_internal() with db_context argument and let exported regdb_store_keys() just call regdb_store_keys_internal() with regdb as an argument. Internally, in reg_backend_db.c, always use the _internal version. Michael --- source3/registry/reg_backend_db.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index c29bd79525..78ac64d5c1 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -31,6 +31,8 @@ static bool regdb_key_exists(struct db_context *db, const char *key); static bool regdb_key_is_base_key(const char *key); static int regdb_fetch_keys_internal(struct db_context *db, const char *key, struct regsubkey_ctr *ctr); +static bool regdb_store_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr); /* List the deepest path into the registry. All part components will be created.*/ @@ -182,7 +184,7 @@ static WERROR init_registry_key_internal(const char *add_path) goto fail; } } - if (!regdb_store_keys( base, subkeys)) { + if (!regdb_store_keys_internal(regdb, base, subkeys)) { werr = WERR_CAN_NOT_COMPLETE; goto fail; } @@ -706,7 +708,8 @@ done: do not currently exist ***********************************************************************/ -bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) +static bool regdb_store_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr) { int num_subkeys, old_num_subkeys, i; char *path = NULL; @@ -715,7 +718,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) TALLOC_CTX *ctx = talloc_stackframe(); WERROR werr; - if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { + if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) { goto fail; } @@ -730,7 +733,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) return false; } - regdb_fetch_keys_internal(regdb, key, old_subkeys); + regdb_fetch_keys_internal(db, key, old_subkeys); num_subkeys = regsubkey_ctr_numkeys(ctr); old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys); @@ -757,7 +760,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) TALLOC_FREE(old_subkeys); - if (regdb->transaction_start(regdb) != 0) { + if (db->transaction_start(db) != 0) { DEBUG(0, ("regdb_store_keys: transaction_start failed\n")); goto fail; } @@ -772,7 +775,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - regdb_fetch_keys_internal(regdb, key, old_subkeys); + regdb_fetch_keys_internal(db, key, old_subkeys); /* * Make the store operation as safe as possible without transactions: @@ -814,7 +817,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - werr = regdb_delete_key_lists(regdb, path); + werr = regdb_delete_key_lists(db, path); W_ERROR_NOT_OK_GOTO(werr, cancel); TALLOC_FREE(path); @@ -824,7 +827,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) /* (2) store the subkey list for the parent */ - if (!regdb_store_keys_internal2(regdb, key, ctr)) { + if (!regdb_store_keys_internal2(db, key, ctr)) { DEBUG(0,("regdb_store_keys: Failed to store new subkey list " "for parent [%s]\n", key)); goto cancel; @@ -841,7 +844,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - if (!regdb_store_keys_internal2(regdb, key, subkeys)) { + if (!regdb_store_keys_internal2(db, key, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]\n", key)); goto cancel; @@ -863,9 +866,9 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) goto cancel; } - if (regdb_fetch_keys_internal(regdb, path, subkeys) == -1) { + if (regdb_fetch_keys_internal(db, path, subkeys) == -1) { /* create a record with 0 subkeys */ - if (!regdb_store_keys_internal2(regdb, path, subkeys)) { + if (!regdb_store_keys_internal2(db, path, subkeys)) { DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]\n", path)); goto cancel; @@ -876,7 +879,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) TALLOC_FREE(path); } - if (regdb->transaction_commit(regdb) != 0) { + if (db->transaction_commit(db) != 0) { DEBUG(0, ("regdb_store_keys: Could not commit transaction\n")); goto fail; } @@ -885,7 +888,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) return true; cancel: - if (regdb->transaction_cancel(regdb) != 0) { + if (db->transaction_cancel(db) != 0) { smb_panic("regdb_store_keys: transaction_cancel failed\n"); } @@ -895,6 +898,11 @@ fail: return false; } +bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) +{ + return regdb_store_keys_internal(regdb, key, ctr); +} + static WERROR regdb_create_subkey(const char *key, const char *subkey) { WERROR werr; -- cgit From 3409a44da2ee6a0ca2caaf0455e0095f8e2f80a4 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 11:41:08 +0200 Subject: s3:registry: don't use exported transaction wrappers in regdb_create_subkey() So that the regdb handle is again explicit and the core of the function can be abstracted. Michael --- source3/registry/reg_backend_db.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 78ac64d5c1..6763558b0d 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -929,8 +929,10 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) talloc_free(subkeys); - werr = regdb_transaction_start(); - W_ERROR_NOT_OK_GOTO_DONE(werr); + if (regdb->transaction_start(regdb) != 0) { + werr = WERR_REG_IO_FAILURE; + goto done; + } werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO(werr, cancel); @@ -950,19 +952,17 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) goto cancel; } - werr = regdb_transaction_commit(); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0, (__location__ " failed to commit transaction: %s\n", - win_errstr(werr))); + if (regdb->transaction_commit(regdb) != 0) { + werr = WERR_REG_IO_FAILURE; + DEBUG(0, (__location__ " failed to commit transaction\n")); } goto done; cancel: - werr = regdb_transaction_cancel(); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0, (__location__ " failed to cancel transaction: %s\n", - win_errstr(werr))); + if (regdb->transaction_cancel(regdb) != 0) { + werr = WERR_REG_IO_FAILURE; + DEBUG(0, (__location__ " failed to cancel transaction\n")); } done: -- cgit From 355892c296f7f245e5a5dd9070e3e776bedbf09c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 12:20:23 +0200 Subject: s3:registry: panic upon failed transaction_cancel in regdb_create_subkey() Michael --- source3/registry/reg_backend_db.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 6763558b0d..880c84a1be 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -961,8 +961,7 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) cancel: if (regdb->transaction_cancel(regdb) != 0) { - werr = WERR_REG_IO_FAILURE; - DEBUG(0, (__location__ " failed to cancel transaction\n")); + smb_panic("regdb_create_subkey: transaction_cancel failed\n"); } done: -- cgit From 4eeacd6ef0e1bb813062c30ac280e542c6b007c8 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 12:24:25 +0200 Subject: s3:registry: in regdb_delete_subkey(), panic if transaction_cancel fails Michael --- source3/registry/reg_backend_db.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 880c84a1be..0c916a8df6 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1027,8 +1027,7 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) cancel: werr2 = regdb_transaction_cancel(); if (!W_ERROR_IS_OK(werr2)) { - DEBUG(0, (__location__ " failed to cancel transaction: %s\n", - win_errstr(werr2))); + smb_panic("regdb_delete_subkey: transaction_cancel failed\n"); } done: -- cgit From 6cb14409af5f708706f975143c7b40bb54c7a5c0 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 12:27:26 +0200 Subject: s3:registry: in regdb_delete_subkey(), don't use the transaction wrappers. This way, the db handle gets used explicitly and the core of the function can be abstracted. Michael --- source3/registry/reg_backend_db.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 0c916a8df6..979dc1867c 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -971,7 +971,7 @@ done: static WERROR regdb_delete_subkey(const char *key, const char *subkey) { - WERROR werr, werr2; + WERROR werr; struct regsubkey_ctr *subkeys; char *path; TALLOC_CTX *mem_ctx = talloc_stackframe(); @@ -992,8 +992,10 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) goto done; } - werr = regdb_transaction_start(); - W_ERROR_NOT_OK_GOTO_DONE(werr); + if (regdb->transaction_start(regdb) != 0) { + werr = WERR_REG_IO_FAILURE; + goto done; + } werr = regdb_delete_key_lists(regdb, path); W_ERROR_NOT_OK_GOTO(werr, cancel); @@ -1016,17 +1018,15 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) goto cancel; } - werr = regdb_transaction_commit(); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0, (__location__ " failed to commit transaction: %s\n", - win_errstr(werr))); + if (regdb->transaction_commit(regdb) != 0) { + DEBUG(0, (__location__ " failed to commit transaction\n")); + werr = WERR_REG_IO_FAILURE; } goto done; cancel: - werr2 = regdb_transaction_cancel(); - if (!W_ERROR_IS_OK(werr2)) { + if (regdb->transaction_cancel(regdb) != 0) { smb_panic("regdb_delete_subkey: transaction_cancel failed\n"); } -- cgit From 4c366a094693f050b2cadea771cd5c6eab29e278 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 12:39:32 +0200 Subject: s3:registry: don't loop transaction_commit in create_sorted_subkeys() upon error This would try to commit a higher level transaction upon commit-error. Michael --- source3/registry/reg_backend_db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 979dc1867c..dd9ca8b65c 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1203,7 +1203,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) if (regdb->transaction_commit(regdb) == -1) { DEBUG(0, ("create_sorted_subkeys: transaction_start " "failed\n")); - goto fail; + result = false; } TALLOC_FREE(ctr); -- cgit From 3189828087387686f63b3ae0b289c6e31f602a54 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 12:41:09 +0200 Subject: s3:registry: fix a comment in create_sorted_subkeys() Michael --- source3/registry/reg_backend_db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index dd9ca8b65c..245e14b6d4 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1201,7 +1201,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) * a transaction_commit for transactions that we might be wrapped in. */ if (regdb->transaction_commit(regdb) == -1) { - DEBUG(0, ("create_sorted_subkeys: transaction_start " + DEBUG(0, ("create_sorted_subkeys: transaction_commit " "failed\n")); result = false; } -- cgit From a00109e1e6c1063b560be85c43ef820d3446ae31 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 12:42:09 +0200 Subject: s3:registry: panic upon error at transaction_cancel in create_sorted_subkeys Michael --- source3/registry/reg_backend_db.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 245e14b6d4..8806a93735 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1184,8 +1184,8 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) * transaction. See below for an explanation. */ if (regdb->transaction_cancel(regdb) == -1) { - DEBUG(0, ("create_sorted_subkeys: transaction_cancel " - "failed\n")); + smb_panic("create_sorted_subkeys: transaction_cancel " + "failed\n"); } TALLOC_FREE(ctr); return false; -- cgit From 95ebf534d2bc9904cc7c02bccdf5c01cc595ad7c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 23:03:46 +0200 Subject: s3:registry: add db_context argument to init_registry_key_internal() Michael --- source3/registry/reg_backend_db.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 8806a93735..d19eac3ccd 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -98,7 +98,8 @@ static struct builtin_regkey_value builtin_registry_values[] = { * Initialize a key in the registry: * create each component key of the specified path. */ -static WERROR init_registry_key_internal(const char *add_path) +static WERROR init_registry_key_internal(struct db_context *db, + const char *add_path) { WERROR werr; TALLOC_CTX *frame = talloc_stackframe(); @@ -177,14 +178,14 @@ static WERROR init_registry_key_internal(const char *add_path) goto fail; } - regdb_fetch_keys_internal(regdb, base, subkeys); + regdb_fetch_keys_internal(db, base, subkeys); if (*subkeyname) { werr = regsubkey_ctr_addkey(subkeys, subkeyname); if (!W_ERROR_IS_OK(werr)) { goto fail; } } - if (!regdb_store_keys_internal(regdb, base, subkeys)) { + if (!regdb_store_keys_internal(db, base, subkeys)) { werr = WERR_CAN_NOT_COMPLETE; goto fail; } @@ -215,7 +216,7 @@ WERROR init_registry_key(const char *add_path) return WERR_REG_IO_FAILURE; } - werr = init_registry_key_internal(add_path); + werr = init_registry_key_internal(regdb, add_path); if (!W_ERROR_IS_OK(werr)) { goto fail; } @@ -301,7 +302,8 @@ do_init: if (regdb_key_exists(regdb, builtin_registry_paths[i])) { continue; } - werr = init_registry_key_internal(builtin_registry_paths[i]); + werr = init_registry_key_internal(regdb, + builtin_registry_paths[i]); if (!W_ERROR_IS_OK(werr)) { goto fail; } -- cgit From 8a5b164b20c3d51df2422c1402ef31384b31472e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2009 23:58:03 +0200 Subject: s3:registry: use transaction wrapper in init_registry_key(). Michael --- source3/registry/reg_backend_db.c | 42 ++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 23 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index d19eac3ccd..74671a0790 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -198,6 +198,20 @@ fail: return werr; } +struct init_registry_key_context { + const char *add_path; +}; + +static NTSTATUS init_registry_key_action(struct db_context *db, + void *private_data) +{ + struct init_registry_key_context *init_ctx = + (struct init_registry_key_context *)private_data; + + return werror_to_ntstatus(init_registry_key_internal( + db, init_ctx->add_path)); +} + /** * Initialize a key in the registry: * create each component key of the specified path, @@ -205,35 +219,17 @@ fail: */ WERROR init_registry_key(const char *add_path) { - WERROR werr; + struct init_registry_key_context init_ctx; if (regdb_key_exists(regdb, add_path)) { return WERR_OK; } - if (regdb->transaction_start(regdb) != 0) { - DEBUG(0, ("init_registry_key: transaction_start failed\n")); - return WERR_REG_IO_FAILURE; - } + init_ctx.add_path = add_path; - werr = init_registry_key_internal(regdb, add_path); - if (!W_ERROR_IS_OK(werr)) { - goto fail; - } - - if (regdb->transaction_commit(regdb) != 0) { - DEBUG(0, ("init_registry_key: Could not commit transaction\n")); - return WERR_REG_IO_FAILURE; - } - - return WERR_OK; - -fail: - if (regdb->transaction_cancel(regdb) != 0) { - smb_panic("init_registry_key: transaction_cancel failed\n"); - } - - return werr; + return ntstatus_to_werror(dbwrap_trans_do(regdb, + init_registry_key_action, + &init_ctx)); } /*********************************************************************** -- cgit From 302265aae1bc27244ffaa9d803a8be83947e0381 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 12:32:48 +0200 Subject: s3:registry: add a regdb_fetch_values_internal() that takes a db_context argument Michael --- source3/registry/reg_backend_db.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 74671a0790..a5e882e9dc 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -33,6 +33,8 @@ static int regdb_fetch_keys_internal(struct db_context *db, const char *key, struct regsubkey_ctr *ctr); static bool regdb_store_keys_internal(struct db_context *db, const char *key, struct regsubkey_ctr *ctr); +static int regdb_fetch_values_internal(struct db_context *db, const char* key, + struct regval_ctr *values); /* List the deepest path into the registry. All part components will be created.*/ @@ -261,7 +263,9 @@ WERROR init_registry_data(void) goto done; } - regdb_fetch_values(builtin_registry_values[i].path, values); + regdb_fetch_values_internal(regdb, + builtin_registry_values[i].path, + values); if (!regval_ctr_key_exists(values, builtin_registry_values[i].valuename)) { @@ -315,7 +319,9 @@ do_init: goto fail; } - regdb_fetch_values(builtin_registry_values[i].path, values); + regdb_fetch_values_internal(regdb, + builtin_registry_values[i].path, + values); /* preserve existing values across restarts. Only add new ones */ @@ -1495,7 +1501,8 @@ static int regdb_pack_values(struct regval_ctr *values, uint8 *buf, int buflen) released by the caller. ***********************************************************************/ -int regdb_fetch_values(const char* key, struct regval_ctr *values) +static int regdb_fetch_values_internal(struct db_context *db, const char* key, + struct regval_ctr *values) { char *keystr = NULL; TALLOC_CTX *ctx = talloc_stackframe(); @@ -1504,7 +1511,7 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values) DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key)); - if (!regdb_key_exists(regdb, key)) { + if (!regdb_key_exists(db, key)) { goto done; } @@ -1513,9 +1520,9 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values) goto done; } - values->seqnum = regdb_get_seqnum(); + values->seqnum = db->get_seqnum(db); - value = regdb_fetch_key_internal(regdb, ctx, keystr); + value = regdb_fetch_key_internal(db, ctx, keystr); if (!value.dptr) { /* all keys have zero values by default */ @@ -1530,6 +1537,11 @@ done: return ret; } +int regdb_fetch_values(const char* key, struct regval_ctr *values) +{ + return regdb_fetch_values_internal(regdb, key, values); +} + bool regdb_store_values(const char *key, struct regval_ctr *values) { TDB_DATA old_data, data; -- cgit From e6340963cf549cda261fc1ba9da4bc1b3a071241 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 12:38:41 +0200 Subject: s3:registry: add regdb_store_values_internal() that takes a db_context argument Michael --- source3/registry/reg_backend_db.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index a5e882e9dc..d2adc1ce08 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -35,6 +35,8 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, struct regsubkey_ctr *ctr); static int regdb_fetch_values_internal(struct db_context *db, const char* key, struct regval_ctr *values); +static bool regdb_store_values_internal(struct db_context *db, const char *key, + struct regval_ctr *values); /* List the deepest path into the registry. All part components will be created.*/ @@ -354,8 +356,9 @@ do_init: "[%d]\n", builtin_registry_values[i].type)); } - regdb_store_values(builtin_registry_values[i].path, - values); + regdb_store_values_internal(regdb, + builtin_registry_values[i].path, + values); } TALLOC_FREE(values); } @@ -1542,7 +1545,8 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values) return regdb_fetch_values_internal(regdb, key, values); } -bool regdb_store_values(const char *key, struct regval_ctr *values) +static bool regdb_store_values_internal(struct db_context *db, const char *key, + struct regval_ctr *values) { TDB_DATA old_data, data; char *keystr = NULL; @@ -1553,7 +1557,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values) DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key)); - if (!regdb_key_exists(regdb, key)) { + if (!regdb_key_exists(db, key)) { goto done; } @@ -1581,7 +1585,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values) goto done; } - old_data = dbwrap_fetch_bystring(regdb, ctx, keystr); + old_data = dbwrap_fetch_bystring(db, ctx, keystr); if ((old_data.dptr != NULL) && (old_data.dsize == data.dsize) @@ -1591,7 +1595,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values) goto done; } - status = dbwrap_trans_store_bystring(regdb, keystr, data, TDB_REPLACE); + status = dbwrap_trans_store_bystring(db, keystr, data, TDB_REPLACE); result = NT_STATUS_IS_OK(status); @@ -1600,6 +1604,11 @@ done: return result; } +bool regdb_store_values(const char *key, struct regval_ctr *values) +{ + return regdb_store_values_internal(regdb, key, values); +} + static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key, struct security_descriptor **psecdesc) { -- cgit From cf4f808b8b03c385b5b9e9f4a5e891ae92143001 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 13:10:37 +0200 Subject: s3:registry: use transaction wrapper in init_registry_data() Michael --- source3/registry/reg_backend_db.c | 141 +++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 72 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index d2adc1ce08..bed9535f17 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -240,74 +240,25 @@ WERROR init_registry_key(const char *add_path) Open the registry data in the tdb ***********************************************************************/ -WERROR init_registry_data(void) +static NTSTATUS init_registry_data_action(struct db_context *db, + void *private_data) { - WERROR werr; + NTSTATUS status; TALLOC_CTX *frame = talloc_stackframe(); struct regval_ctr *values; int i; UNISTR2 data; - /* - * First, check for the existence of the needed keys and values. - * If all do already exist, we can save the writes. - */ - for (i=0; builtin_registry_paths[i] != NULL; i++) { - if (!regdb_key_exists(regdb, builtin_registry_paths[i])) { - goto do_init; - } - } - - for (i=0; builtin_registry_values[i].path != NULL; i++) { - values = TALLOC_ZERO_P(frame, struct regval_ctr); - if (values == NULL) { - werr = WERR_NOMEM; - goto done; - } - - regdb_fetch_values_internal(regdb, - builtin_registry_values[i].path, - values); - if (!regval_ctr_key_exists(values, - builtin_registry_values[i].valuename)) - { - TALLOC_FREE(values); - goto do_init; - } - - TALLOC_FREE(values); - } - - werr = WERR_OK; - goto done; - -do_init: - - /* - * There are potentially quite a few store operations which are all - * indiviually wrapped in tdb transactions. Wrapping them in a single - * transaction gives just a single transaction_commit() to actually do - * its fsync()s. See tdb/common/transaction.c for info about nested - * transaction behaviour. - */ - - if (regdb->transaction_start(regdb) != 0) { - DEBUG(0, ("init_registry_data: tdb_transaction_start " - "failed\n")); - werr = WERR_REG_IO_FAILURE; - goto done; - } - /* loop over all of the predefined paths and add each component */ for (i=0; builtin_registry_paths[i] != NULL; i++) { - if (regdb_key_exists(regdb, builtin_registry_paths[i])) { + if (regdb_key_exists(db, builtin_registry_paths[i])) { continue; } - werr = init_registry_key_internal(regdb, - builtin_registry_paths[i]); - if (!W_ERROR_IS_OK(werr)) { - goto fail; + status = werror_to_ntstatus(init_registry_key_internal(db, + builtin_registry_paths[i])); + if (!NT_STATUS_IS_OK(status)) { + goto done; } } @@ -317,11 +268,11 @@ do_init: values = TALLOC_ZERO_P(frame, struct regval_ctr); if (values == NULL) { - werr = WERR_NOMEM; - goto fail; + status = NT_STATUS_NO_MEMORY; + goto done; } - regdb_fetch_values_internal(regdb, + regdb_fetch_values_internal(db, builtin_registry_values[i].path, values); @@ -356,29 +307,75 @@ do_init: "[%d]\n", builtin_registry_values[i].type)); } - regdb_store_values_internal(regdb, + regdb_store_values_internal(db, builtin_registry_values[i].path, values); } TALLOC_FREE(values); } - if (regdb->transaction_commit(regdb) != 0) { - DEBUG(0, ("init_registry_data: Could not commit " - "transaction\n")); - werr = WERR_REG_IO_FAILURE; - } else { - werr = WERR_OK; + status = NT_STATUS_OK; + +done: + + TALLOC_FREE(frame); + return status; +} + +WERROR init_registry_data(void) +{ + WERROR werr; + TALLOC_CTX *frame = talloc_stackframe(); + struct regval_ctr *values; + int i; + + /* + * First, check for the existence of the needed keys and values. + * If all do already exist, we can save the writes. + */ + for (i=0; builtin_registry_paths[i] != NULL; i++) { + if (!regdb_key_exists(regdb, builtin_registry_paths[i])) { + goto do_init; + } } - goto done; + for (i=0; builtin_registry_values[i].path != NULL; i++) { + values = TALLOC_ZERO_P(frame, struct regval_ctr); + if (values == NULL) { + werr = WERR_NOMEM; + goto done; + } -fail: - if (regdb->transaction_cancel(regdb) != 0) { - smb_panic("init_registry_data: tdb_transaction_cancel " - "failed\n"); + regdb_fetch_values_internal(regdb, + builtin_registry_values[i].path, + values); + if (!regval_ctr_key_exists(values, + builtin_registry_values[i].valuename)) + { + TALLOC_FREE(values); + goto do_init; + } + + TALLOC_FREE(values); } + werr = WERR_OK; + goto done; + +do_init: + + /* + * There are potentially quite a few store operations which are all + * indiviually wrapped in tdb transactions. Wrapping them in a single + * transaction gives just a single transaction_commit() to actually do + * its fsync()s. See tdb/common/transaction.c for info about nested + * transaction behaviour. + */ + + werr = ntstatus_to_werror(dbwrap_trans_do(regdb, + init_registry_data_action, + NULL)); + done: TALLOC_FREE(frame); return werr; -- cgit From 1c65c98f3350951fe9f87a942b4c8a8094c8b781 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 13:58:52 +0200 Subject: s3:registry: refactor adding of builtin reg values out into regdb_ctr_add_value(). For readability. Michael --- source3/registry/reg_backend_db.c | 54 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index bed9535f17..d04d34bac0 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -240,6 +240,31 @@ WERROR init_registry_key(const char *add_path) Open the registry data in the tdb ***********************************************************************/ +static void regdb_ctr_add_value(struct regval_ctr *ctr, + struct builtin_regkey_value *value) +{ + UNISTR2 data; + + switch(value->type) { + case REG_DWORD: + regval_ctr_addvalue(ctr, value->valuename, REG_DWORD, + (char*)&value->data.dw_value, + sizeof(uint32)); + break; + + case REG_SZ: + init_unistr2(&data, value->data.string, UNI_STR_TERMINATE); + regval_ctr_addvalue(ctr, value->valuename, REG_SZ, + (char*)data.buffer, + data.uni_str_len*sizeof(uint16)); + break; + + default: + DEBUG(0, ("regdb_ctr_add_value: invalid value type in " + "registry values [%d]\n", value->type)); + } +} + static NTSTATUS init_registry_data_action(struct db_context *db, void *private_data) { @@ -247,7 +272,6 @@ static NTSTATUS init_registry_data_action(struct db_context *db, TALLOC_CTX *frame = talloc_stackframe(); struct regval_ctr *values; int i; - UNISTR2 data; /* loop over all of the predefined paths and add each component */ @@ -281,32 +305,8 @@ static NTSTATUS init_registry_data_action(struct db_context *db, if (!regval_ctr_key_exists(values, builtin_registry_values[i].valuename)) { - switch(builtin_registry_values[i].type) { - case REG_DWORD: - regval_ctr_addvalue(values, - builtin_registry_values[i].valuename, - REG_DWORD, - (char*)&builtin_registry_values[i].data.dw_value, - sizeof(uint32)); - break; - - case REG_SZ: - init_unistr2(&data, - builtin_registry_values[i].data.string, - UNI_STR_TERMINATE); - regval_ctr_addvalue(values, - builtin_registry_values[i].valuename, - REG_SZ, - (char*)data.buffer, - data.uni_str_len*sizeof(uint16)); - break; - - default: - DEBUG(0, ("init_registry_data: invalid value " - "type in builtin_registry_values " - "[%d]\n", - builtin_registry_values[i].type)); - } + regdb_ctr_add_value(values, + &builtin_registry_values[i]); regdb_store_values_internal(db, builtin_registry_values[i].path, values); -- cgit From 14f593aa0f43127ab78aec848b0fe5933c0c28c9 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 8 Jul 2009 17:26:06 +0200 Subject: s3:registry: change regdb_store_keys_internal2() to return WERROR instead of bool for better error propagation. Michael --- source3/registry/reg_backend_db.c | 71 ++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 30 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index d04d34bac0..419bfd00f5 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -609,27 +609,26 @@ done: fstrings ***********************************************************************/ -static bool regdb_store_keys_internal2(struct db_context *db, - const char *key, - struct regsubkey_ctr *ctr) +static WERROR regdb_store_keys_internal2(struct db_context *db, + const char *key, + struct regsubkey_ctr *ctr) { TDB_DATA dbuf; uint8 *buffer = NULL; int i = 0; uint32 len, buflen; - bool ret = true; uint32 num_subkeys = regsubkey_ctr_numkeys(ctr); char *keyname = NULL; TALLOC_CTX *ctx = talloc_stackframe(); - NTSTATUS status; + WERROR werr; if (!key) { - return false; + return WERR_INVALID_PARAM; } keyname = talloc_strdup(ctx, key); if (!keyname) { - return false; + return WERR_NOMEM; } keyname = normalize_reg_path(ctx, keyname); @@ -637,7 +636,8 @@ static bool regdb_store_keys_internal2(struct db_context *db, buffer = (uint8 *)SMB_MALLOC(1024); if (buffer == NULL) { - return false; + werr = WERR_NOMEM; + goto done; } buflen = 1024; len = 0; @@ -665,7 +665,7 @@ static bool regdb_store_keys_internal2(struct db_context *db, DEBUG(0, ("regdb_store_keys: Failed to realloc " "memory of size [%u]\n", (unsigned int)(len+thistime)*2)); - ret = false; + werr = WERR_NOMEM; goto done; } buflen = (len+thistime)*2; @@ -674,7 +674,7 @@ static bool regdb_store_keys_internal2(struct db_context *db, regsubkey_ctr_specific_key(ctr, i)); if (thistime2 != thistime) { DEBUG(0, ("tdb_pack failed\n")); - ret = false; + werr = WERR_CAN_NOT_COMPLETE; goto done; } } @@ -685,11 +685,9 @@ static bool regdb_store_keys_internal2(struct db_context *db, dbuf.dptr = buffer; dbuf.dsize = len; - status = dbwrap_store_bystring(db, keyname, dbuf, TDB_REPLACE); - if (!NT_STATUS_IS_OK(status)) { - ret = false; - goto done; - } + werr = ntstatus_to_werror(dbwrap_store_bystring(db, keyname, dbuf, + TDB_REPLACE)); + W_ERROR_NOT_OK_GOTO_DONE(werr); /* * Delete a sorted subkey cache for regdb_key_exists, will be @@ -697,14 +695,22 @@ static bool regdb_store_keys_internal2(struct db_context *db, */ keyname = talloc_asprintf(ctx, "%s/%s", REG_SORTED_SUBKEYS_PREFIX, keyname); - if (keyname != NULL) { - dbwrap_delete_bystring(db, keyname); + if (keyname == NULL) { + werr = WERR_NOMEM; + goto done; + } + + werr = ntstatus_to_werror(dbwrap_delete_bystring(db, keyname)); + + /* don't treat WERR_NOT_FOUND as an error here */ + if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) { + werr = WERR_OK; } done: TALLOC_FREE(ctx); SAFE_FREE(buffer); - return ret; + return werr; } /*********************************************************************** @@ -831,9 +837,10 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, /* (2) store the subkey list for the parent */ - if (!regdb_store_keys_internal2(db, key, ctr)) { + werr = regdb_store_keys_internal2(db, key, ctr); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: Failed to store new subkey list " - "for parent [%s]\n", key)); + "for parent [%s]: %s\n", key, win_errstr(werr))); goto cancel; } @@ -848,9 +855,11 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, goto cancel; } - if (!regdb_store_keys_internal2(db, key, subkeys)) { + werr = regdb_store_keys_internal2(db, key, subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: Failed to store " - "new record for key [%s]\n", key)); + "new record for key [%s]: %s\n", key, + win_errstr(werr))); goto cancel; } TALLOC_FREE(subkeys); @@ -872,9 +881,11 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, if (regdb_fetch_keys_internal(db, path, subkeys) == -1) { /* create a record with 0 subkeys */ - if (!regdb_store_keys_internal2(db, path, subkeys)) { + werr = regdb_store_keys_internal2(db, path, subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: Failed to store " - "new record for key [%s]\n", path)); + "new record for key [%s]: %s\n", path, + win_errstr(werr))); goto cancel; } } @@ -949,10 +960,10 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_addkey(subkeys, subkey); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (!regdb_store_keys_internal2(regdb, key, subkeys)) { + werr = regdb_store_keys_internal2(regdb, key, subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0, (__location__ " failed to store new subkey list for " - "parent key %s\n", key)); - werr = WERR_REG_IO_FAILURE; + "parent key %s: %s\n", key, win_errstr(werr))); goto cancel; } @@ -1015,10 +1026,10 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_delkey(subkeys, subkey); W_ERROR_NOT_OK_GOTO(werr, cancel); - if (!regdb_store_keys_internal2(regdb, key, subkeys)) { + werr = regdb_store_keys_internal2(regdb, key, subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0, (__location__ " failed to store new subkey_list for " - "parent key %s\n", key)); - werr = WERR_REG_IO_FAILURE; + "parent key %s: %s\n", key, win_errstr(werr))); goto cancel; } -- cgit From 3eec829e2fa2106c8d52f31e3f3d7f45e6c81b24 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 00:10:08 +0200 Subject: s3:registry: unify exit logic and remove leaking to talloc_stack in regdb_store_keys_internal() Michael --- source3/registry/reg_backend_db.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 419bfd00f5..542f6dc7d0 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -727,9 +727,10 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, char *oldkeyname = NULL; TALLOC_CTX *ctx = talloc_stackframe(); WERROR werr; + bool ret = false; if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) { - goto fail; + goto done; } /* @@ -740,7 +741,7 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, werr = regsubkey_ctr_init(ctx, &old_subkeys); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - return false; + goto done; } regdb_fetch_keys_internal(db, key, old_subkeys); @@ -763,8 +764,9 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, * Nothing changed, no point to even start a tdb * transaction */ - TALLOC_FREE(old_subkeys); - return true; + + ret = true; + goto done; } } @@ -772,7 +774,7 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, if (db->transaction_start(db) != 0) { DEBUG(0, ("regdb_store_keys: transaction_start failed\n")); - goto fail; + goto done; } /* @@ -896,21 +898,22 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, if (db->transaction_commit(db) != 0) { DEBUG(0, ("regdb_store_keys: Could not commit transaction\n")); - goto fail; + goto done; } - TALLOC_FREE(ctx); - return true; + ret = true; + goto done; cancel: + ret = false; if (db->transaction_cancel(db) != 0) { smb_panic("regdb_store_keys: transaction_cancel failed\n"); } -fail: +done: TALLOC_FREE(ctx); - return false; + return ret; } bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) -- cgit From f93c9e0d415b5c2e2fd73bb370db7b7e17ede9aa Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 00:21:46 +0200 Subject: s3:registry: don't leak to talloc_stack in regdb_store_keys_internal2() and catch one potential talloc failure. Michael --- source3/registry/reg_backend_db.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 542f6dc7d0..6bf98d4c75 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -623,14 +623,21 @@ static WERROR regdb_store_keys_internal2(struct db_context *db, WERROR werr; if (!key) { - return WERR_INVALID_PARAM; + werr = WERR_INVALID_PARAM; + goto done; } keyname = talloc_strdup(ctx, key); if (!keyname) { - return WERR_NOMEM; + werr = WERR_NOMEM; + goto done; } + keyname = normalize_reg_path(ctx, keyname); + if (!keyname) { + werr = WERR_NOMEM; + goto done; + } /* allocate some initial memory */ -- cgit From 86d747e19f877c45ac32663ec2a3381ad03cdcf5 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 10:28:29 +0200 Subject: s3:registry: use transaction wrapper in regdb_store_keys_internal(). Michael --- source3/registry/reg_backend_db.c | 198 ++++++++++++++++++++------------------ 1 file changed, 102 insertions(+), 96 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 6bf98d4c75..5c714a40b4 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -725,76 +725,32 @@ done: do not currently exist ***********************************************************************/ -static bool regdb_store_keys_internal(struct db_context *db, const char *key, - struct regsubkey_ctr *ctr) +struct regdb_store_keys_context { + const char *key; + struct regsubkey_ctr *ctr; +}; + +static NTSTATUS regdb_store_keys_action(struct db_context *db, + void *private_data) { - int num_subkeys, old_num_subkeys, i; + struct regdb_store_keys_context *store_ctx; + WERROR werr; + int num_subkeys, i; char *path = NULL; struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL; char *oldkeyname = NULL; - TALLOC_CTX *ctx = talloc_stackframe(); - WERROR werr; - bool ret = false; - - if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) { - goto done; - } - - /* - * fetch a list of the old subkeys so we can determine if anything has - * changed - */ - - werr = regsubkey_ctr_init(ctx, &old_subkeys); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - goto done; - } - - regdb_fetch_keys_internal(db, key, old_subkeys); - - num_subkeys = regsubkey_ctr_numkeys(ctr); - old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys); - if ((num_subkeys && old_num_subkeys) && - (num_subkeys == old_num_subkeys)) { - - for (i = 0; i < num_subkeys; i++) { - if (strcmp(regsubkey_ctr_specific_key(ctr, i), - regsubkey_ctr_specific_key(old_subkeys, i)) - != 0) - { - break; - } - } - if (i == num_subkeys) { - /* - * Nothing changed, no point to even start a tdb - * transaction - */ - - ret = true; - goto done; - } - } - - TALLOC_FREE(old_subkeys); + TALLOC_CTX *mem_ctx = talloc_stackframe(); - if (db->transaction_start(db) != 0) { - DEBUG(0, ("regdb_store_keys: transaction_start failed\n")); - goto done; - } + store_ctx = (struct regdb_store_keys_context *)private_data; /* * Re-fetch the old keys inside the transaction */ - werr = regsubkey_ctr_init(ctx, &old_subkeys); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - goto cancel; - } + werr = regsubkey_ctr_init(mem_ctx, &old_subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); - regdb_fetch_keys_internal(db, key, old_subkeys); + regdb_fetch_keys_internal(db, store_ctx->key, old_subkeys); /* * Make the store operation as safe as possible without transactions: @@ -823,21 +779,22 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, for (i=0; ictr, oldkeyname)) { /* * It's still around, don't delete */ - continue; } - path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname); + path = talloc_asprintf(mem_ctx, "%s/%s", store_ctx->key, + oldkeyname); if (!path) { - goto cancel; + werr = WERR_NOMEM; + goto done; } werr = regdb_delete_key_lists(db, path); - W_ERROR_NOT_OK_GOTO(werr, cancel); + W_ERROR_NOT_OK_GOTO_DONE(werr); TALLOC_FREE(path); } @@ -846,47 +803,41 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, /* (2) store the subkey list for the parent */ - werr = regdb_store_keys_internal2(db, key, ctr); + werr = regdb_store_keys_internal2(db, store_ctx->key, store_ctx->ctr); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: Failed to store new subkey list " - "for parent [%s]: %s\n", key, win_errstr(werr))); - goto cancel; + "for parent [%s]: %s\n", store_ctx->key, + win_errstr(werr))); + goto done; } /* (3) now create records for any subkeys that don't already exist */ - num_subkeys = regsubkey_ctr_numkeys(ctr); + num_subkeys = regsubkey_ctr_numkeys(store_ctx->ctr); if (num_subkeys == 0) { - werr = regsubkey_ctr_init(ctx, &subkeys); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - goto cancel; - } + werr = regsubkey_ctr_init(mem_ctx, &subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); - werr = regdb_store_keys_internal2(db, key, subkeys); + werr = regdb_store_keys_internal2(db, store_ctx->key, subkeys); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: Failed to store " - "new record for key [%s]: %s\n", key, - win_errstr(werr))); - goto cancel; + "new record for key [%s]: %s\n", + store_ctx->key, win_errstr(werr))); + goto done; } TALLOC_FREE(subkeys); - } for (i=0; ikey, + regsubkey_ctr_specific_key(store_ctx->ctr, i)); if (!path) { - goto cancel; - } - werr = regsubkey_ctr_init(ctx, &subkeys); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - goto cancel; + werr = WERR_NOMEM; + goto done; } + werr = regsubkey_ctr_init(mem_ctx, &subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); if (regdb_fetch_keys_internal(db, path, subkeys) == -1) { /* create a record with 0 subkeys */ @@ -895,7 +846,7 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s]: %s\n", path, win_errstr(werr))); - goto cancel; + goto done; } } @@ -903,20 +854,75 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, TALLOC_FREE(path); } - if (db->transaction_commit(db) != 0) { - DEBUG(0, ("regdb_store_keys: Could not commit transaction\n")); + werr = WERR_OK; + +done: + talloc_free(mem_ctx); + return werror_to_ntstatus(werr); +} + +static bool regdb_store_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr) +{ + int num_subkeys, old_num_subkeys, i; + struct regsubkey_ctr *old_subkeys = NULL; + TALLOC_CTX *ctx = talloc_stackframe(); + WERROR werr; + bool ret = false; + struct regdb_store_keys_context store_ctx; + + if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) { goto done; } - ret = true; - goto done; + /* + * fetch a list of the old subkeys so we can determine if anything has + * changed + */ -cancel: - ret = false; - if (db->transaction_cancel(db) != 0) { - smb_panic("regdb_store_keys: transaction_cancel failed\n"); + werr = regsubkey_ctr_init(ctx, &old_subkeys); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("regdb_store_keys: talloc() failure!\n")); + goto done; } + regdb_fetch_keys_internal(db, key, old_subkeys); + + num_subkeys = regsubkey_ctr_numkeys(ctr); + old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys); + if ((num_subkeys && old_num_subkeys) && + (num_subkeys == old_num_subkeys)) { + + for (i = 0; i < num_subkeys; i++) { + if (strcmp(regsubkey_ctr_specific_key(ctr, i), + regsubkey_ctr_specific_key(old_subkeys, i)) + != 0) + { + break; + } + } + if (i == num_subkeys) { + /* + * Nothing changed, no point to even start a tdb + * transaction + */ + + ret = true; + goto done; + } + } + + TALLOC_FREE(old_subkeys); + + store_ctx.key = key; + store_ctx.ctr = ctr; + + werr = ntstatus_to_werror(dbwrap_trans_do(db, + regdb_store_keys_action, + &store_ctx)); + + ret = W_ERROR_IS_OK(werr); + done: TALLOC_FREE(ctx); -- cgit From 8c7b9604931a787107bc01b359a231d376ed92c0 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 10:41:59 +0200 Subject: s3:registry: use transaction wrapper in regdb_create_subkey() Michael --- source3/registry/reg_backend_db.c | 73 ++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 31 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 5c714a40b4..08d72c3215 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -934,66 +934,77 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) return regdb_store_keys_internal(regdb, key, ctr); } -static WERROR regdb_create_subkey(const char *key, const char *subkey) +struct regdb_create_subkey_context { + const char *key; + const char *subkey; +}; + +static NTSTATUS regdb_create_subkey_action(struct db_context *db, + void *private_data) { WERROR werr; + struct regdb_create_subkey_context *create_ctx; struct regsubkey_ctr *subkeys; TALLOC_CTX *mem_ctx = talloc_stackframe(); - if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { - werr = WERR_NOT_FOUND; - goto done; - } + create_ctx = (struct regdb_create_subkey_context *)private_data; werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { + if (regdb_fetch_keys_internal(db, create_ctx->key, subkeys) < 0) { werr = WERR_REG_IO_FAILURE; goto done; } - if (regsubkey_ctr_key_exists(subkeys, subkey)) { - werr = WERR_OK; - goto done; + werr = regsubkey_ctr_addkey(subkeys, create_ctx->subkey); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + werr = regdb_store_keys_internal2(db, create_ctx->key, subkeys); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, (__location__ " failed to store new subkey list for " + "parent key %s: %s\n", create_ctx->key, + win_errstr(werr))); } - talloc_free(subkeys); +done: + talloc_free(mem_ctx); + return werror_to_ntstatus(werr); +} - if (regdb->transaction_start(regdb) != 0) { - werr = WERR_REG_IO_FAILURE; +static WERROR regdb_create_subkey(const char *key, const char *subkey) +{ + WERROR werr; + struct regsubkey_ctr *subkeys; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + struct regdb_create_subkey_context create_ctx; + + if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { + werr = WERR_NOT_FOUND; goto done; } werr = regsubkey_ctr_init(mem_ctx, &subkeys); - W_ERROR_NOT_OK_GOTO(werr, cancel); + W_ERROR_NOT_OK_GOTO_DONE(werr); if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { werr = WERR_REG_IO_FAILURE; - goto cancel; + goto done; } - werr = regsubkey_ctr_addkey(subkeys, subkey); - W_ERROR_NOT_OK_GOTO(werr, cancel); - - werr = regdb_store_keys_internal2(regdb, key, subkeys); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0, (__location__ " failed to store new subkey list for " - "parent key %s: %s\n", key, win_errstr(werr))); - goto cancel; + if (regsubkey_ctr_key_exists(subkeys, subkey)) { + werr = WERR_OK; + goto done; } - if (regdb->transaction_commit(regdb) != 0) { - werr = WERR_REG_IO_FAILURE; - DEBUG(0, (__location__ " failed to commit transaction\n")); - } + talloc_free(subkeys); - goto done; + create_ctx.key = key; + create_ctx.subkey = subkey; -cancel: - if (regdb->transaction_cancel(regdb) != 0) { - smb_panic("regdb_create_subkey: transaction_cancel failed\n"); - } + werr = ntstatus_to_werror(dbwrap_trans_do(regdb, + regdb_create_subkey_action, + &create_ctx)); done: talloc_free(mem_ctx); -- cgit From 5640598cbb66fb0e65413e53a11ff82a553caad6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 10:52:40 +0200 Subject: s3:registry: add a comment header for the create_subkey set of functions Michael --- source3/registry/reg_backend_db.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 08d72c3215..f60ee1f7a6 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -934,6 +934,10 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) return regdb_store_keys_internal(regdb, key, ctr); } +/** + * create a subkey of a given key + */ + struct regdb_create_subkey_context { const char *key; const char *subkey; -- cgit From a48d8353c79685371dbd2cc73b6c9032c5166a5b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 10:54:18 +0200 Subject: s3:registry: add a comment header for the delete_subkey set of commands. Michael --- source3/registry/reg_backend_db.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index f60ee1f7a6..8cd79b15b2 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1015,6 +1015,10 @@ done: return werr; } +/** + * create a subkey of a given key + */ + static WERROR regdb_delete_subkey(const char *key, const char *subkey) { WERROR werr; -- cgit From 2d6dbcd0b13da469f8b7dc6ed65e51d91ce1ab9c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 11:04:20 +0200 Subject: s3:registry: use transaction wrapper in regdb_delete_subkey(). Michael --- source3/registry/reg_backend_db.c | 86 ++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 37 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 8cd79b15b2..095b0c5b22 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1019,11 +1019,53 @@ done: * create a subkey of a given key */ -static WERROR regdb_delete_subkey(const char *key, const char *subkey) +struct regdb_delete_subkey_context { + const char *key; + const char *subkey; + const char *path; +}; + +static NTSTATUS regdb_delete_subkey_action(struct db_context *db, + void *private_data) { WERROR werr; + struct regdb_delete_subkey_context *delete_ctx; struct regsubkey_ctr *subkeys; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + + delete_ctx = (struct regdb_delete_subkey_context *)private_data; + + werr = regdb_delete_key_lists(db, delete_ctx->path); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + werr = regsubkey_ctr_init(mem_ctx, &subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + if (regdb_fetch_keys_internal(db, delete_ctx->key, subkeys) < 0) { + werr = WERR_REG_IO_FAILURE; + goto done; + } + + werr = regsubkey_ctr_delkey(subkeys, delete_ctx->subkey); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + werr = regdb_store_keys_internal2(db, delete_ctx->key, subkeys); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, (__location__ " failed to store new subkey_list for " + "parent key %s: %s\n", delete_ctx->key, + win_errstr(werr))); + } + +done: + talloc_free(mem_ctx); + return werror_to_ntstatus(werr); +} + +static WERROR regdb_delete_subkey(const char *key, const char *subkey) +{ + WERROR werr; char *path; + struct regdb_delete_subkey_context delete_ctx; TALLOC_CTX *mem_ctx = talloc_stackframe(); if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) { @@ -1042,43 +1084,13 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey) goto done; } - if (regdb->transaction_start(regdb) != 0) { - werr = WERR_REG_IO_FAILURE; - goto done; - } - - werr = regdb_delete_key_lists(regdb, path); - W_ERROR_NOT_OK_GOTO(werr, cancel); - - werr = regsubkey_ctr_init(mem_ctx, &subkeys); - W_ERROR_NOT_OK_GOTO(werr, cancel); - - if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { - werr = WERR_REG_IO_FAILURE; - goto cancel; - } - - werr = regsubkey_ctr_delkey(subkeys, subkey); - W_ERROR_NOT_OK_GOTO(werr, cancel); - - werr = regdb_store_keys_internal2(regdb, key, subkeys); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0, (__location__ " failed to store new subkey_list for " - "parent key %s: %s\n", key, win_errstr(werr))); - goto cancel; - } - - if (regdb->transaction_commit(regdb) != 0) { - DEBUG(0, (__location__ " failed to commit transaction\n")); - werr = WERR_REG_IO_FAILURE; - } + delete_ctx.key = key; + delete_ctx.subkey = subkey; + delete_ctx.path = path; - goto done; - -cancel: - if (regdb->transaction_cancel(regdb) != 0) { - smb_panic("regdb_delete_subkey: transaction_cancel failed\n"); - } + werr = ntstatus_to_werror(dbwrap_trans_do(regdb, + regdb_delete_subkey_action, + &delete_ctx)); done: talloc_free(mem_ctx); -- cgit From 109ea29b2c1a3bc752f9afda2c0010b9e675aa83 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 9 Jul 2009 12:54:16 +0200 Subject: s3:registry: restructure logic of create_sorted_subkes() slightly This makes it clearer to me, and it also makes it easier to use the transaction retry wrapper in the next step. Michael --- source3/registry/reg_backend_db.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 095b0c5b22..e0e234f7c6 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1195,18 +1195,18 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) werr = regsubkey_ctr_init(talloc_tos(), &ctr); if (!W_ERROR_IS_OK(werr)) { - goto fail; + goto commit; } res = regdb_fetch_keys_internal(regdb, key, ctr); if (res == -1) { - goto fail; + goto commit; } num_subkeys = regsubkey_ctr_numkeys(ctr); sorted_subkeys = talloc_array(ctr, char *, num_subkeys); if (sorted_subkeys == NULL) { - goto fail; + goto commit; } len = 4 + 4*num_subkeys; @@ -1215,7 +1215,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys, regsubkey_ctr_specific_key(ctr, i)); if (sorted_subkeys[i] == NULL) { - goto fail; + goto commit; } len += strlen(sorted_subkeys[i])+1; } @@ -1224,7 +1224,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) buf = talloc_array(ctr, char, len); if (buf == NULL) { - goto fail; + goto commit; } p = buf + 4 + 4*num_subkeys; @@ -1242,21 +1242,17 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) TDB_REPLACE); if (!NT_STATUS_IS_OK(status)) { /* - * Don't use a "goto fail;" here, this would commit the broken + * Don't use a "goto commit;" here, this would commit the broken * transaction. See below for an explanation. */ - if (regdb->transaction_cancel(regdb) == -1) { - smb_panic("create_sorted_subkeys: transaction_cancel " - "failed\n"); - } - TALLOC_FREE(ctr); - return false; + goto cancel; } result = true; - fail: + +commit: /* - * We only get here via the "goto fail" when we did not write anything + * We only get here via the "goto commit" when we did not write anything * yet. Using transaction_commit even in a failure case is necessary * because this (disposable) call might be nested in other * transactions. Doing a cancel here would destroy the possibility of @@ -1267,7 +1263,16 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) "failed\n")); result = false; } + goto done; + +cancel: + if (regdb->transaction_cancel(regdb) == -1) { + smb_panic("create_sorted_subkeys: transaction_cancel " + "failed\n"); + } + result = false; +done: TALLOC_FREE(ctr); return result; } -- cgit From c52dd1d5b81ce71855a3215f1b23704ac450fdee Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 13 Jul 2009 17:15:14 +0200 Subject: s3:registry: use transaction wrapper in create_sorted_subkeys() Michael --- source3/registry/reg_backend_db.c | 99 ++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 48 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index e0e234f7c6..11e6f66760 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1174,39 +1174,55 @@ static int cmp_keynames(const void *p1, const void *p2) return StrCaseCmp(*((char **)p1), *((char **)p2)); } -static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) +struct create_sorted_subkeys_context { + const char *key; + const char *sorted_keyname; +}; + +static NTSTATUS create_sorted_subkeys_action(struct db_context *db, + void *private_data) { char **sorted_subkeys; struct regsubkey_ctr *ctr; - bool result = false; NTSTATUS status; char *buf; char *p; int i, res; size_t len; int num_subkeys; - WERROR werr; + struct create_sorted_subkeys_context *sorted_ctx; - if (regdb->transaction_start(regdb) != 0) { - DEBUG(0, ("create_sorted_subkeys: transaction_start " - "failed\n")); - return false; - } + sorted_ctx = (struct create_sorted_subkeys_context *)private_data; - werr = regsubkey_ctr_init(talloc_tos(), &ctr); - if (!W_ERROR_IS_OK(werr)) { - goto commit; + /* + * In this function, we only treat failing of the actual write to + * the db as a real error. All preliminary errors, at a stage when + * nothing has been written to the DB yet are treated as success + * to be committed (as an empty transaction). + * + * The reason is that this (disposable) call might be nested in other + * transactions. Doing a cancel here would destroy the possibility of + * a transaction_commit for transactions that we might be wrapped in. + */ + + status = werror_to_ntstatus(regsubkey_ctr_init(talloc_tos(), &ctr)); + if (!NT_STATUS_IS_OK(status)) { + /* don't treat this as an error */ + status = NT_STATUS_OK; + goto done; } - res = regdb_fetch_keys_internal(regdb, key, ctr); + res = regdb_fetch_keys_internal(db, sorted_ctx->key, ctr); if (res == -1) { - goto commit; + /* don't treat this as an error */ + goto done; } num_subkeys = regsubkey_ctr_numkeys(ctr); sorted_subkeys = talloc_array(ctr, char *, num_subkeys); if (sorted_subkeys == NULL) { - goto commit; + /* don't treat this as an error */ + goto done; } len = 4 + 4*num_subkeys; @@ -1215,7 +1231,8 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys, regsubkey_ctr_specific_key(ctr, i)); if (sorted_subkeys[i] == NULL) { - goto commit; + /* don't treat this as an error */ + goto done; } len += strlen(sorted_subkeys[i])+1; } @@ -1224,7 +1241,8 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) buf = talloc_array(ctr, char, len); if (buf == NULL) { - goto commit; + /* don't treat this as an error */ + goto done; } p = buf + 4 + 4*num_subkeys; @@ -1238,43 +1256,28 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) } status = dbwrap_store_bystring( - regdb, sorted_keyname, make_tdb_data((uint8_t *)buf, len), + db, sorted_ctx->sorted_keyname, make_tdb_data((uint8_t *)buf, + len), TDB_REPLACE); - if (!NT_STATUS_IS_OK(status)) { - /* - * Don't use a "goto commit;" here, this would commit the broken - * transaction. See below for an explanation. - */ - goto cancel; - } - result = true; +done: + talloc_free(ctr); + return status; +} -commit: - /* - * We only get here via the "goto commit" when we did not write anything - * yet. Using transaction_commit even in a failure case is necessary - * because this (disposable) call might be nested in other - * transactions. Doing a cancel here would destroy the possibility of - * a transaction_commit for transactions that we might be wrapped in. - */ - if (regdb->transaction_commit(regdb) == -1) { - DEBUG(0, ("create_sorted_subkeys: transaction_commit " - "failed\n")); - result = false; - } - goto done; +static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) +{ + NTSTATUS status; + struct create_sorted_subkeys_context sorted_ctx; -cancel: - if (regdb->transaction_cancel(regdb) == -1) { - smb_panic("create_sorted_subkeys: transaction_cancel " - "failed\n"); - } - result = false; + sorted_ctx.key = key; + sorted_ctx.sorted_keyname = sorted_keyname; -done: - TALLOC_FREE(ctr); - return result; + status = dbwrap_trans_do(regdb, + create_sorted_subkeys_action, + &sorted_ctx); + + return NT_STATUS_IS_OK(status); } struct scan_subkey_state { -- cgit From dc0bcfa188cb24c5a34f592ece946682d5fb8afe Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 15 Jul 2009 12:45:43 +0200 Subject: s3:registry: turn regdb_fetch_keys_internal() from int to WERROR return type This way, more error information is propagated to the callers. Michael --- source3/registry/reg_backend_db.c | 85 ++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 32 deletions(-) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 11e6f66760..7825edd5c2 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -29,8 +29,8 @@ static int regdb_refcount; static bool regdb_key_exists(struct db_context *db, const char *key); static bool regdb_key_is_base_key(const char *key); -static int regdb_fetch_keys_internal(struct db_context *db, const char *key, - struct regsubkey_ctr *ctr); +static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr); static bool regdb_store_keys_internal(struct db_context *db, const char *key, struct regsubkey_ctr *ctr); static int regdb_fetch_values_internal(struct db_context *db, const char* key, @@ -182,7 +182,13 @@ static WERROR init_registry_key_internal(struct db_context *db, goto fail; } - regdb_fetch_keys_internal(db, base, subkeys); + werr = regdb_fetch_keys_internal(db, base, subkeys); + if (!W_ERROR_IS_OK(werr) && + !W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) + { + goto fail; + } + if (*subkeyname) { werr = regsubkey_ctr_addkey(subkeys, subkeyname); if (!W_ERROR_IS_OK(werr)) { @@ -750,7 +756,12 @@ static NTSTATUS regdb_store_keys_action(struct db_context *db, werr = regsubkey_ctr_init(mem_ctx, &old_subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - regdb_fetch_keys_internal(db, store_ctx->key, old_subkeys); + werr = regdb_fetch_keys_internal(db, store_ctx->key, old_subkeys); + if (!W_ERROR_IS_OK(werr) && + !W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) + { + goto done; + } /* * Make the store operation as safe as possible without transactions: @@ -839,7 +850,8 @@ static NTSTATUS regdb_store_keys_action(struct db_context *db, werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - if (regdb_fetch_keys_internal(db, path, subkeys) == -1) { + werr = regdb_fetch_keys_internal(db, path, subkeys); + if (!W_ERROR_IS_OK(werr)) { /* create a record with 0 subkeys */ werr = regdb_store_keys_internal2(db, path, subkeys); if (!W_ERROR_IS_OK(werr)) { @@ -886,7 +898,12 @@ static bool regdb_store_keys_internal(struct db_context *db, const char *key, goto done; } - regdb_fetch_keys_internal(db, key, old_subkeys); + werr = regdb_fetch_keys_internal(db, key, old_subkeys); + if (!W_ERROR_IS_OK(werr) && + !W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) + { + goto done; + } num_subkeys = regsubkey_ctr_numkeys(ctr); old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys); @@ -956,10 +973,8 @@ static NTSTATUS regdb_create_subkey_action(struct db_context *db, werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - if (regdb_fetch_keys_internal(db, create_ctx->key, subkeys) < 0) { - werr = WERR_REG_IO_FAILURE; - goto done; - } + werr = regdb_fetch_keys_internal(db, create_ctx->key, subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); werr = regsubkey_ctr_addkey(subkeys, create_ctx->subkey); W_ERROR_NOT_OK_GOTO_DONE(werr); @@ -991,10 +1006,8 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey) werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - if (regdb_fetch_keys_internal(regdb, key, subkeys) < 0) { - werr = WERR_REG_IO_FAILURE; - goto done; - } + werr = regdb_fetch_keys_internal(regdb, key, subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); if (regsubkey_ctr_key_exists(subkeys, subkey)) { werr = WERR_OK; @@ -1041,10 +1054,8 @@ static NTSTATUS regdb_delete_subkey_action(struct db_context *db, werr = regsubkey_ctr_init(mem_ctx, &subkeys); W_ERROR_NOT_OK_GOTO_DONE(werr); - if (regdb_fetch_keys_internal(db, delete_ctx->key, subkeys) < 0) { - werr = WERR_REG_IO_FAILURE; - goto done; - } + werr = regdb_fetch_keys_internal(db, delete_ctx->key, subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); werr = regsubkey_ctr_delkey(subkeys, delete_ctx->subkey); W_ERROR_NOT_OK_GOTO_DONE(werr); @@ -1187,7 +1198,7 @@ static NTSTATUS create_sorted_subkeys_action(struct db_context *db, NTSTATUS status; char *buf; char *p; - int i, res; + int i; size_t len; int num_subkeys; struct create_sorted_subkeys_context *sorted_ctx; @@ -1212,9 +1223,12 @@ static NTSTATUS create_sorted_subkeys_action(struct db_context *db, goto done; } - res = regdb_fetch_keys_internal(db, sorted_ctx->key, ctr); - if (res == -1) { + status = werror_to_ntstatus(regdb_fetch_keys_internal(db, + sorted_ctx->key, + ctr)); + if (!NT_STATUS_IS_OK(status)) { /* don't treat this as an error */ + status = NT_STATUS_OK; goto done; } @@ -1423,36 +1437,36 @@ done: released by the caller. ***********************************************************************/ -static int regdb_fetch_keys_internal(struct db_context *db, const char *key, - struct regsubkey_ctr *ctr) +static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key, + struct regsubkey_ctr *ctr) { WERROR werr; - uint32 num_items; + uint32_t num_items; uint8 *buf; uint32 buflen, len; int i; fstring subkeyname; - int ret = -1; TALLOC_CTX *frame = talloc_stackframe(); TDB_DATA value; DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL")); + frame = talloc_stackframe(); + if (!regdb_key_exists(db, key)) { + DEBUG(10, ("key [%s] not found\n", key)); + werr = WERR_NOT_FOUND; goto done; } werr = regsubkey_ctr_set_seqnum(ctr, db->get_seqnum(db)); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } + W_ERROR_NOT_OK_GOTO_DONE(werr); value = regdb_fetch_key_internal(db, frame, key); if (value.dptr == NULL) { DEBUG(10, ("regdb_fetch_keys: no subkeys found for key [%s]\n", key)); - ret = 0; goto done; } @@ -1466,21 +1480,28 @@ static int regdb_fetch_keys_internal(struct db_context *db, const char *key, if (!W_ERROR_IS_OK(werr)) { DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey " "failed: %s\n", win_errstr(werr))); + num_items = 0; goto done; } } DEBUG(11,("regdb_fetch_keys: Exit [%d] items\n", num_items)); - ret = num_items; done: TALLOC_FREE(frame); - return ret; + return werr; } int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) { - return regdb_fetch_keys_internal(regdb, key, ctr); + WERROR werr; + + werr = regdb_fetch_keys_internal(regdb, key, ctr); + if (!W_ERROR_IS_OK(werr)) { + return -1; + } + + return regsubkey_ctr_numkeys(ctr); } /**************************************************************************** -- cgit From 92df5e4a0243bde6fbc5261bf6758090c4c35eee Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 15 Jul 2009 12:47:12 +0200 Subject: s3:registry: add function regsubkey_ctr_reinit() This reinitializes an already allocated regsubkey_ctr structure, emptying out the subkey array and hash table. Michael --- source3/include/proto.h | 1 + source3/registry/reg_objects.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 56bffd5ce7..7bbdc04ae7 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5097,6 +5097,7 @@ WERROR registry_init_smbconf(const char *keyname); /* The following definitions come from registry/reg_objects.c */ WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr); +WERROR regsubkey_ctr_reinit(struct regsubkey_ctr *ctr); WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum); int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr); WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ); diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index a592c76e1d..0c0455aada 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -63,6 +63,29 @@ WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr) return WERR_OK; } +/** + * re-initialize the list of subkeys (to the emtpy list) + * in an already allocated regsubkey_ctr + */ + +WERROR regsubkey_ctr_reinit(struct regsubkey_ctr *ctr) +{ + if (ctr == NULL) { + return WERR_INVALID_PARAM; + } + + talloc_free(ctr->subkeys_hash); + ctr->subkeys_hash = db_open_rbt(ctr); + W_ERROR_HAVE_NO_MEMORY(ctr->subkeys_hash); + + TALLOC_FREE(ctr->subkeys); + + ctr->num_subkeys = 0; + ctr->seqnum = 0; + + return WERR_OK; +} + WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum) { if (ctr == NULL) { -- cgit From 78576117eb4292e4e2750928d5f84c2edc94192f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 15 Jul 2009 12:50:55 +0200 Subject: s3:registry: flush the provided subkey_ctr in regdb_fetch_keys_internal() This way, we always return what has really been read from the db, and not more. The callers assume exactly this, but one could hand in an already pre-filled subkey container... Michael --- source3/registry/reg_backend_db.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 7825edd5c2..9fd5c3161b 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1474,6 +1474,9 @@ static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key, buflen = value.dsize; len = tdb_unpack( buf, buflen, "d", &num_items); + werr = regsubkey_ctr_reinit(ctr); + W_ERROR_NOT_OK_GOTO_DONE(werr); + for (i=0; i Date: Tue, 7 Jul 2009 17:16:21 +0200 Subject: s3:registry: db backend: add my C Michael --- source3/registry/reg_backend_db.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 9fd5c3161b..dec43ae741 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -2,6 +2,7 @@ * Unix SMB/CIFS implementation. * Virtual Windows Registry Layer * Copyright (C) Gerald Carter 2002-2005 + * Copyright (C) Michael Adam 2007-2009 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit From 7bd4699228a1975573cb62550043c05b48e66361 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 15 Jul 2009 16:59:07 +0200 Subject: s3:dbwrap: fix embarrassing typo :-) Michael --- source3/lib/dbwrap_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 6c95672986..7dbeb63927 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. Utility functions for the dbwrap API Copyright (C) Volker Lendecke 2007 - Copyrithg (C) Michael Adam 2009 + Copyright (C) Michael Adam 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From 2df4550aae1e326511fe4e7e0d2d98be3e578caf Mon Sep 17 00:00:00 2001 From: Peter Volkov Date: Wed, 15 Jul 2009 17:36:25 +0200 Subject: s3: make linking of cifs.upcall --as-needed safe See http://www.gentoo.org/proj/en/qa/asneeded.xml for details. --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index bc00f6a863..8b78984b8d 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1517,7 +1517,7 @@ bin/umount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UMOUNT_OBJ) bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ1) @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@ @echo Linking $@ @$(CC) -o $@ $(CIFS_UPCALL_OBJ) $(DYNEXP) $(LDFLAGS) \ - -lkeyutils $(LIBS) $(LIBSMBCLIENT_OBJ1) $(KRB5LIBS) \ + $(LIBSMBCLIENT_OBJ1) $(LIBS) -lkeyutils $(KRB5LIBS) \ $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBWBCLIENT_LIBS) \ $(LIBTDB_LIBS) $(NSCD_LIBS) $(ZLIB_LIBS) -- cgit From 5236b3699da2b5cc55d55310de76e4ab65a8bb46 Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Wed, 15 Jul 2009 17:24:14 +0200 Subject: s3: make linking of rpcclient --as-needed safe --- source3/Makefile.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 8b78984b8d..f6396ef157 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1476,10 +1476,10 @@ bin/swat@EXEEXT@: $(BINARY_PREREQS) $(SWAT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@ bin/rpcclient@EXEEXT@: $(BINARY_PREREQS) $(RPCCLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@ @echo Linking $@ - @$(CC) -o $@ $(LDFLAGS) $(PASSDB_LIBS) $(RPCCLIENT_OBJ) \ + @$(CC) -o $@ $(LDFLAGS) $(RPCCLIENT_OBJ) \ $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) $(POPT_LIBS) \ $(KRB5LIBS) $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \ - $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS) + $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS) $(PASSDB_LIBS) bin/smbclient@EXEEXT@: $(BINARY_PREREQS) $(CLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@ @echo Linking $@ -- cgit From 1f5aec877fc48ff96b14a0e95f01c68a29dd8718 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Jul 2009 11:49:33 -0700 Subject: Make cli_unlock and cli_unlock64 async. Fix POSIX lock test. Jeremy. --- source3/include/proto.h | 18 ++- source3/libsmb/clifile.c | 270 +++++++++++++++++++++++++++++++++----------- source3/torture/locktest.c | 4 +- source3/torture/locktest2.c | 2 +- source3/torture/torture.c | 44 ++++---- 5 files changed, 247 insertions(+), 91 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 7bbdc04ae7..15e3f325aa 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2518,10 +2518,24 @@ NTSTATUS cli_locktype(struct cli_state *cli, uint16_t fnum, int timeout, unsigned char locktype); bool cli_lock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len, int timeout, enum brl_type lock_type); -bool cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len); +struct tevent_req *cli_unlock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len); +NTSTATUS cli_unlock_recv(struct tevent_req *req); +NTSTATUS cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len); bool cli_lock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len, int timeout, enum brl_type lock_type); -bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len); +struct tevent_req *cli_unlock64_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len); +NTSTATUS cli_unlock64_recv(struct tevent_req *req); +NTSTATUS cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len); struct tevent_req *cli_posix_lock_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 0e2b3640f2..5ea0579839 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1893,7 +1893,6 @@ struct tevent_req *cli_nt_delete_on_close_send(TALLOC_CTX *mem_ctx, SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO); /* Setup param array. */ - memset(state->param, '\0', 6); SSVAL(state->param,0,fnum); SSVAL(state->param,2,SMB_SET_FILE_DISPOSITION_INFO); @@ -2010,6 +2009,7 @@ struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx, if (req == NULL) { return NULL; } + vwv = state->vwv; SCVAL(vwv+0, 0, 0xFF); @@ -2367,6 +2367,7 @@ struct tevent_req *cli_close_create(TALLOC_CTX *mem_ctx, if (req == NULL) { return NULL; } + SSVAL(state->vwv+0, 0, fnum); SIVALS(state->vwv+1, 0, -1); @@ -2708,42 +2709,114 @@ bool cli_lock(struct cli_state *cli, uint16_t fnum, Unlock a file. ****************************************************************************/ -bool cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len) +struct cli_unlock_state { + uint16_t vwv[8]; + uint8_t data[10]; +}; + +static void cli_unlock_done(struct tevent_req *subreq); + +struct tevent_req *cli_unlock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len) + { - char *p; + struct tevent_req *req = NULL, *subreq = NULL; + struct cli_unlock_state *state = NULL; + uint8_t additional_flags = 0; - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); + req = tevent_req_create(mem_ctx, &state, struct cli_unlock_state); + if (req == NULL) { + return NULL; + } - cli_set_message(cli->outbuf,8,0,True); + SCVAL(state->vwv+0, 0, 0xFF); + SSVAL(state->vwv+2, 0, fnum); + SCVAL(state->vwv+3, 0, 0); + SIVALS(state->vwv+4, 0, 0); + SSVAL(state->vwv+6, 0, 1); + SSVAL(state->vwv+7, 0, 0); - SCVAL(cli->outbuf,smb_com,SMBlockingX); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + SSVAL(state->data, 0, cli->pid); + SIVAL(state->data, 2, offset); + SIVAL(state->data, 6, len); - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,fnum); - SCVAL(cli->outbuf,smb_vwv3,0); - SIVALS(cli->outbuf, smb_vwv4, 0); - SSVAL(cli->outbuf,smb_vwv6,1); - SSVAL(cli->outbuf,smb_vwv7,0); + subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags, + 8, state->vwv, 10, state->data); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_unlock_done, req); + return req; +} - p = smb_buf(cli->outbuf); - SSVAL(p, 0, cli->pid); - SIVAL(p, 2, offset); - SIVAL(p, 6, len); - p += 10; - cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; +static void cli_unlock_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + NTSTATUS status; + + status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; } + tevent_req_done(req); +} - if (cli_is_error(cli)) { - return False; +NTSTATUS cli_unlock_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +NTSTATUS cli_unlock(struct cli_state *cli, + uint16_t fnum, + uint32_t offset, + uint32_t len) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; } - return True; + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_unlock_send(frame, ev, cli, + fnum, offset, len); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_unlock_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** @@ -2811,46 +2884,118 @@ bool cli_lock64(struct cli_state *cli, uint16_t fnum, Unlock a file with 64 bit offsets. ****************************************************************************/ -bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len) +struct cli_unlock64_state { + uint16_t vwv[8]; + uint8_t data[20]; +}; + +static void cli_unlock64_done(struct tevent_req *subreq); + +struct tevent_req *cli_unlock64_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len) + { - char *p; + struct tevent_req *req = NULL, *subreq = NULL; + struct cli_unlock64_state *state = NULL; + uint8_t additional_flags = 0; - if (! (cli->capabilities & CAP_LARGE_FILES)) { - return cli_unlock(cli, fnum, offset, len); + req = tevent_req_create(mem_ctx, &state, struct cli_unlock64_state); + if (req == NULL) { + return NULL; } - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); + SCVAL(state->vwv+0, 0, 0xff); + SSVAL(state->vwv+2, 0, fnum); + SCVAL(state->vwv+3, 0,LOCKING_ANDX_LARGE_FILES); + SIVALS(state->vwv+4, 0, 0); + SSVAL(state->vwv+6, 0, 1); + SSVAL(state->vwv+7, 0, 0); - cli_set_message(cli->outbuf,8,0,True); + SIVAL(state->data, 0, cli->pid); + SOFF_T_R(state->data, 4, offset); + SOFF_T_R(state->data, 12, len); - SCVAL(cli->outbuf,smb_com,SMBlockingX); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags, + 8, state->vwv, 20, state->data); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_unlock64_done, req); + return req; +} - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,fnum); - SCVAL(cli->outbuf,smb_vwv3,LOCKING_ANDX_LARGE_FILES); - SIVALS(cli->outbuf, smb_vwv4, 0); - SSVAL(cli->outbuf,smb_vwv6,1); - SSVAL(cli->outbuf,smb_vwv7,0); +static void cli_unlock64_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + NTSTATUS status; - p = smb_buf(cli->outbuf); - SIVAL(p, 0, cli->pid); - SOFF_T_R(p, 4, offset); - SOFF_T_R(p, 12, len); - p += 20; - cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; + status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; } + tevent_req_done(req); +} - if (cli_is_error(cli)) { - return False; +NTSTATUS cli_unlock64_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +NTSTATUS cli_unlock64(struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_OK; + + if (! (cli->capabilities & CAP_LARGE_FILES)) { + return cli_unlock(cli, fnum, offset, len); } - return True; + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_unlock64_send(frame, ev, cli, + fnum, offset, len); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_unlock64_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** @@ -3421,7 +3566,7 @@ NTSTATUS cli_getatr(struct cli_state *cli, static void cli_setattrE_done(struct tevent_req *subreq); struct cli_setattrE_state { - int dummy; + uint16_t vwv[7]; }; struct tevent_req *cli_setattrE_send(TALLOC_CTX *mem_ctx, @@ -3435,21 +3580,19 @@ struct tevent_req *cli_setattrE_send(TALLOC_CTX *mem_ctx, struct tevent_req *req = NULL, *subreq = NULL; struct cli_setattrE_state *state = NULL; uint8_t additional_flags = 0; - uint16_t vwv[7]; req = tevent_req_create(mem_ctx, &state, struct cli_setattrE_state); if (req == NULL) { return NULL; } - memset(vwv, '\0', sizeof(vwv)); - SSVAL(vwv+0, 0, fnum); - cli_put_dos_date2(cli, (char *)&vwv[1], 0, change_time); - cli_put_dos_date2(cli, (char *)&vwv[3], 0, access_time); - cli_put_dos_date2(cli, (char *)&vwv[5], 0, write_time); + SSVAL(state->vwv+0, 0, fnum); + cli_put_dos_date2(cli, (char *)&state->vwv[1], 0, change_time); + cli_put_dos_date2(cli, (char *)&state->vwv[3], 0, access_time); + cli_put_dos_date2(cli, (char *)&state->vwv[5], 0, write_time); subreq = cli_smb_send(state, ev, cli, SMBsetattrE, additional_flags, - 7, vwv, 0, NULL); + 7, state->vwv, 0, NULL); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -3556,7 +3699,6 @@ struct tevent_req *cli_setatr_send(TALLOC_CTX *mem_ctx, return NULL; } - memset(state->vwv, '\0', sizeof(state->vwv)); SSVAL(state->vwv+0, 0, attr); cli_put_dos_date3(cli, (char *)&state->vwv[1], 0, mtime); diff --git a/source3/torture/locktest.c b/source3/torture/locktest.c index 30b84c073d..a90c2e2dfe 100644 --- a/source3/torture/locktest.c +++ b/source3/torture/locktest.c @@ -341,9 +341,9 @@ static bool test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS], case OP_UNLOCK: /* unset a lock */ for (server=0;server Date: Wed, 15 Jul 2009 20:54:01 +0200 Subject: s3:tldap: fix the build - a void function should not return a value metze --- source3/lib/tldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c index 451bc18d2e..fa56763a33 100644 --- a/source3/lib/tldap.c +++ b/source3/lib/tldap.c @@ -1618,7 +1618,7 @@ struct tevent_req *tldap_add_send(TALLOC_CTX *mem_ctx, static void tldap_add_done(struct tevent_req *subreq) { - return tldap_simple_done(subreq, TLDAP_RES_ADD); + tldap_simple_done(subreq, TLDAP_RES_ADD); } int tldap_add_recv(struct tevent_req *req) @@ -1718,7 +1718,7 @@ struct tevent_req *tldap_modify_send(TALLOC_CTX *mem_ctx, static void tldap_modify_done(struct tevent_req *subreq) { - return tldap_simple_done(subreq, TLDAP_RES_MODIFY); + tldap_simple_done(subreq, TLDAP_RES_MODIFY); } int tldap_modify_recv(struct tevent_req *req) @@ -1795,7 +1795,7 @@ struct tevent_req *tldap_delete_send(TALLOC_CTX *mem_ctx, static void tldap_delete_done(struct tevent_req *subreq) { - return tldap_simple_done(subreq, TLDAP_RES_DELETE); + tldap_simple_done(subreq, TLDAP_RES_DELETE); } int tldap_delete_recv(struct tevent_req *req) -- cgit From 2fca950d68bff3641ed3ac4bdaee1d16f0cca88a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2009 20:58:11 +0200 Subject: s3:libsmb: we need to include "includes.h" as first header to let code build on all platforms This should fix the Tru64 build. metze --- source3/libsmb/libsmb_thread_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/libsmb/libsmb_thread_posix.c b/source3/libsmb/libsmb_thread_posix.c index 411ffbdfbb..6519659c25 100644 --- a/source3/libsmb/libsmb_thread_posix.c +++ b/source3/libsmb/libsmb_thread_posix.c @@ -17,8 +17,8 @@ along with this program. If not, see . */ -#include #include "includes.h" +#include #include "libsmbclient.h" #include "libsmb_internal.h" -- cgit From 377a97579bc9b733c5a6363c71498e2ecf894f02 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2009 21:02:42 +0200 Subject: s3:smbd: try to fix a compiler warning on i386 : left shift count >= width of type metze --- source3/smbd/trans2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index d1f2e7ff18..06536f9e21 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4105,7 +4105,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, I think this causes us to fail the IFSKIT BasicFileInformationTest. -tpot */ file_index = ((sbuf.st_ex_ino) & UINT32_MAX); /* FileIndexLow */ - file_index |= ((sbuf.st_ex_dev) & UINT32_MAX) << 32; /* FileIndexHigh */ + file_index |= ((uint64_t)((sbuf.st_ex_dev) & UINT32_MAX)) << 32; /* FileIndexHigh */ switch (info_level) { case SMB_INFO_STANDARD: -- cgit From 48a07321479c14a6618bb21302d27fd9606efbdd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Jul 2009 13:59:11 -0700 Subject: Fix bug #6551 - win98 clients cannot connect after server upgrade to samba-3.4.0. The values of vuid and tid were not being correctly updated in the struct smb_request when passed to chain_reply inside sessionsetupX and tconX. Jeremy. --- source3/smbd/reply.c | 2 ++ source3/smbd/sesssetup.c | 1 + 2 files changed, 3 insertions(+) (limited to 'source3') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 4d0a2b8c97..a6e35c7342 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -856,6 +856,7 @@ void reply_tcon_and_X(struct smb_request *req) END_PROFILE(SMBtconX); + req->tid = conn->cnum; chain_reply(req); return; } @@ -2076,6 +2077,7 @@ void reply_ulogoffX(struct smb_request *req) DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) ); END_PROFILE(SMBulogoffX); + req->vuid = UID_FIELD_INVALID; chain_reply(req); } diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 3988105fa4..2d2e5141ee 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1807,6 +1807,7 @@ void reply_sesssetup_and_X(struct smb_request *req) SSVAL(req->outbuf,smb_uid,sess_vuid); SSVAL(req->inbuf,smb_uid,sess_vuid); + req->vuid = sess_vuid; if (!sconn->smb1.sessions.done_sesssetup) { sconn->smb1.sessions.max_send = -- cgit From 33768fea073fb24763728c1da3424465ebabc1f0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 15 Jul 2009 21:59:05 +0200 Subject: s3-spoolss: make some of the command hooks static. Guenther --- source3/include/proto.h | 3 --- source3/rpc_server/srv_spoolss_nt.c | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 15e3f325aa..740cc4198b 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5906,7 +5906,6 @@ void copy_id26_to_sam_passwd(struct samu *to, /* The following definitions come from rpc_server/srv_spoolss_nt.c */ -WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename ); void do_drv_upgrade_printer(struct messaging_context *msg, void *private_data, uint32_t msg_type, @@ -5995,9 +5994,7 @@ void construct_info_data(struct spoolss_Notify *info_data, int id); struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx, const char *servicename); -WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri ); bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer); -WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines ); /* The following definitions come from rpc_server/srv_srvsvc_nt.c */ diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 9d72168202..48ac103667 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -261,7 +261,7 @@ static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd) Delete a printer given a handle. ****************************************************************************/ -WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename ) +static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename) { char *cmd = lp_deleteprinter_cmd(); char *command = NULL; @@ -5920,7 +5920,7 @@ static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum) /**************************************************************************** ****************************************************************************/ -WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri ) +static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri) { char *cmd = lp_addport_cmd(); char *command = NULL; @@ -7316,7 +7316,7 @@ static WERROR fill_port_2(TALLOC_CTX *mem_ctx, wrapper around the enumer ports command ****************************************************************************/ -WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines ) +static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines) { char *cmd = lp_enumports_cmd(); char **qlines = NULL; -- cgit From f982c912f47d5bfd00b4736573c7e4219a31a6c8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 15 Jul 2009 23:16:19 +0200 Subject: s3-rpc_parse: remove more unused code. Guenther --- source3/include/proto.h | 16 --- source3/rpc_parse/parse_prs.c | 318 ------------------------------------------ 2 files changed, 334 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 740cc4198b..d68aa4b619 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5676,32 +5676,16 @@ void prs_switch_type(prs_struct *ps, bool io); void prs_force_dynamic(prs_struct *ps); void prs_set_session_key(prs_struct *ps, const char sess_key[16]); bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8); -bool prs_pointer( const char *name, prs_struct *ps, int depth, - void *dta, size_t data_size, - bool (*prs_fn)(const char*, prs_struct*, int, void*) ); bool prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16); bool prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32); bool prs_int32(const char *name, prs_struct *ps, int depth, int32 *data32); bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64); -bool prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status); bool prs_dcerpc_status(const char *name, prs_struct *ps, int depth, NTSTATUS *status); -bool prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status); bool prs_uint8s(bool charmode, const char *name, prs_struct *ps, int depth, uint8 *data8s, int len); bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len); -bool prs_uint16uni(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len); bool prs_uint32s(bool charmode, const char *name, prs_struct *ps, int depth, uint32 *data32s, int len); bool prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str); bool prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_buf_size); -bool prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **str); -bool prs_uint16_pre(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset); -bool prs_uint16_post(const char *name, prs_struct *ps, int depth, uint16 *data16, - uint32 ptr_uint16, uint32 start_offset); -bool prs_uint32_pre(const char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset); -bool prs_uint32_post(const char *name, prs_struct *ps, int depth, uint32 *data32, - uint32 ptr_uint32, uint32 data_size); -int tdb_prs_store(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps); -int tdb_prs_fetch(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps, TALLOC_CTX *mem_ctx); -bool prs_hash1(prs_struct *ps, uint32 offset, int len); void schannel_encode(struct schannel_auth_struct *a, enum pipe_auth_level auth_level, enum schannel_direction direction, RPC_AUTH_SCHANNEL_CHK * verf, diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index 0f4829dec3..621ccf4bc9 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -636,42 +636,6 @@ bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8) return True; } -/******************************************************************* - Stream a uint16* (allocate memory if unmarshalling) - ********************************************************************/ - -bool prs_pointer( const char *name, prs_struct *ps, int depth, - void *dta, size_t data_size, - bool (*prs_fn)(const char*, prs_struct*, int, void*) ) -{ - void ** data = (void **)dta; - uint32 data_p; - - /* output f000baaa to stream if the pointer is non-zero. */ - - data_p = *data ? 0xf000baaa : 0; - - if ( !prs_uint32("ptr", ps, depth, &data_p )) - return False; - - /* we're done if there is no data */ - - if ( !data_p ) - return True; - - if (UNMARSHALLING(ps)) { - if (data_size) { - if ( !(*data = PRS_ALLOC_MEM(ps, char, data_size)) ) - return False; - } else { - *data = NULL; - } - } - - return prs_fn(name, ps, depth, *data); -} - - /******************************************************************* Stream a uint16. ********************************************************************/ @@ -783,36 +747,6 @@ bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64) } } -/******************************************************************* - Stream a NTSTATUS - ********************************************************************/ - -bool prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status) -{ - char *q = prs_mem_get(ps, sizeof(uint32)); - if (q == NULL) - return False; - - if (UNMARSHALLING(ps)) { - if (ps->bigendian_data) - *status = NT_STATUS(RIVAL(q,0)); - else - *status = NT_STATUS(IVAL(q,0)); - } else { - if (ps->bigendian_data) - RSIVAL(q,0,NT_STATUS_V(*status)); - else - SIVAL(q,0,NT_STATUS_V(*status)); - } - - DEBUGADD(5,("%s%04x %s: %s\n", tab_depth(5,depth), ps->data_offset, name, - nt_errstr(*status))); - - ps->data_offset += sizeof(uint32); - - return True; -} - /******************************************************************* Stream a DCE error code ********************************************************************/ @@ -843,38 +777,6 @@ bool prs_dcerpc_status(const char *name, prs_struct *ps, int depth, NTSTATUS *st return True; } - -/******************************************************************* - Stream a WERROR - ********************************************************************/ - -bool prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status) -{ - char *q = prs_mem_get(ps, sizeof(uint32)); - if (q == NULL) - return False; - - if (UNMARSHALLING(ps)) { - if (ps->bigendian_data) - *status = W_ERROR(RIVAL(q,0)); - else - *status = W_ERROR(IVAL(q,0)); - } else { - if (ps->bigendian_data) - RSIVAL(q,0,W_ERROR_V(*status)); - else - SIVAL(q,0,W_ERROR_V(*status)); - } - - DEBUGADD(5,("%s%04x %s: %s\n", tab_depth(5,depth), ps->data_offset, name, - win_errstr(*status))); - - ps->data_offset += sizeof(uint32); - - return True; -} - - /****************************************************************** Stream an array of uint8s. Length is number of uint8s. ********************************************************************/ @@ -951,60 +853,6 @@ bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uin return True; } -/****************************************************************** - Start using a function for streaming unicode chars. If unmarshalling, - output must be little-endian, if marshalling, input must be little-endian. - ********************************************************************/ - -static void dbg_rw_punival(bool charmode, const char *name, int depth, prs_struct *ps, - char *in_buf, char *out_buf, int len) -{ - int i; - - if (UNMARSHALLING(ps)) { - if (ps->bigendian_data) { - for (i = 0; i < len; i++) - SSVAL(out_buf,2*i,RSVAL(in_buf, 2*i)); - } else { - for (i = 0; i < len; i++) - SSVAL(out_buf, 2*i, SVAL(in_buf, 2*i)); - } - } else { - if (ps->bigendian_data) { - for (i = 0; i < len; i++) - RSSVAL(in_buf, 2*i, SVAL(out_buf,2*i)); - } else { - for (i = 0; i < len; i++) - SSVAL(in_buf, 2*i, SVAL(out_buf,2*i)); - } - } - - DEBUGADD(5,("%s%04x %s: ", tab_depth(5,depth), ps->data_offset, name)); - if (charmode) - print_asc(5, (unsigned char*)out_buf, 2*len); - else { - for (i = 0; i < len; i++) - DEBUGADD(5,("%04x ", out_buf[i])); - } - DEBUGADD(5,("\n")); -} - -/****************************************************************** - Stream a unistr. Always little endian. - ********************************************************************/ - -bool prs_uint16uni(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len) -{ - char *q = prs_mem_get(ps, len * sizeof(uint16)); - if (q == NULL) - return False; - - dbg_rw_punival(charmode, name, depth, ps, q, (char *)data16s, len); - ps->data_offset += (len * sizeof(uint16)); - - return True; -} - /****************************************************************** Stream an array of uint32s. Length is number of uint32s. ********************************************************************/ @@ -1216,172 +1064,6 @@ bool prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_ return True; } -bool prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **str) -{ - size_t len; - char *tmp_str; - - if (UNMARSHALLING(ps)) { - len = strlen(&ps->data_p[ps->data_offset]); - } else { - len = strlen(*str); - } - - tmp_str = PRS_ALLOC_MEM(ps, char, len+1); - - if (tmp_str == NULL) { - return False; - } - - if (MARSHALLING(ps)) { - strncpy(tmp_str, *str, len); - } - - if (!prs_string(name, ps, depth, tmp_str, len+1)) { - return False; - } - - *str = tmp_str; - return True; -} - -/******************************************************************* - prs_uint16 wrapper. Call this and it sets up a pointer to where the - uint16 should be stored, or gets the size if reading. - ********************************************************************/ - -bool prs_uint16_pre(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset) -{ - *offset = ps->data_offset; - if (UNMARSHALLING(ps)) { - /* reading. */ - return prs_uint16(name, ps, depth, data16); - } else { - char *q = prs_mem_get(ps, sizeof(uint16)); - if(q ==NULL) - return False; - ps->data_offset += sizeof(uint16); - } - return True; -} - -/******************************************************************* - prs_uint16 wrapper. call this and it retrospectively stores the size. - does nothing on reading, as that is already handled by ...._pre() - ********************************************************************/ - -bool prs_uint16_post(const char *name, prs_struct *ps, int depth, uint16 *data16, - uint32 ptr_uint16, uint32 start_offset) -{ - if (MARSHALLING(ps)) { - /* - * Writing - temporarily move the offset pointer. - */ - uint16 data_size = ps->data_offset - start_offset; - uint32 old_offset = ps->data_offset; - - ps->data_offset = ptr_uint16; - if(!prs_uint16(name, ps, depth, &data_size)) { - ps->data_offset = old_offset; - return False; - } - ps->data_offset = old_offset; - } else { - ps->data_offset = start_offset + (uint32)(*data16); - } - return True; -} - -/******************************************************************* - prs_uint32 wrapper. Call this and it sets up a pointer to where the - uint32 should be stored, or gets the size if reading. - ********************************************************************/ - -bool prs_uint32_pre(const char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset) -{ - *offset = ps->data_offset; - if (UNMARSHALLING(ps) && (data32 != NULL)) { - /* reading. */ - return prs_uint32(name, ps, depth, data32); - } else { - ps->data_offset += sizeof(uint32); - } - return True; -} - -/******************************************************************* - prs_uint32 wrapper. call this and it retrospectively stores the size. - does nothing on reading, as that is already handled by ...._pre() - ********************************************************************/ - -bool prs_uint32_post(const char *name, prs_struct *ps, int depth, uint32 *data32, - uint32 ptr_uint32, uint32 data_size) -{ - if (MARSHALLING(ps)) { - /* - * Writing - temporarily move the offset pointer. - */ - uint32 old_offset = ps->data_offset; - ps->data_offset = ptr_uint32; - if(!prs_uint32(name, ps, depth, &data_size)) { - ps->data_offset = old_offset; - return False; - } - ps->data_offset = old_offset; - } - return True; -} - -/* useful function to store a structure in rpc wire format */ -int tdb_prs_store(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps) -{ - TDB_DATA dbuf; - dbuf.dptr = (uint8 *)ps->data_p; - dbuf.dsize = prs_offset(ps); - return tdb_trans_store(tdb, kbuf, dbuf, TDB_REPLACE); -} - -/* useful function to fetch a structure into rpc wire format */ -int tdb_prs_fetch(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps, TALLOC_CTX *mem_ctx) -{ - TDB_DATA dbuf; - - prs_init_empty(ps, mem_ctx, UNMARSHALL); - - dbuf = tdb_fetch(tdb, kbuf); - if (!dbuf.dptr) - return -1; - - prs_give_memory(ps, (char *)dbuf.dptr, dbuf.dsize, True); - - return 0; -} - -/******************************************************************* - hash a stream. - ********************************************************************/ - -bool prs_hash1(prs_struct *ps, uint32 offset, int len) -{ - char *q; - - q = ps->data_p; - q = &q[offset]; - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("prs_hash1\n")); - dump_data(100, (uint8 *)ps->sess_key, 16); - dump_data(100, (uint8 *)q, len); -#endif - arcfour_crypt((uchar *) q, (const unsigned char *)ps->sess_key, len); - -#ifdef DEBUG_PASSWORD - dump_data(100, (uint8 *)q, len); -#endif - - return True; -} - /******************************************************************* Create a digest over the entire packet (including the data), and MD5 it with the session key. -- cgit From 74c405db406d0971ba4fe2abae4ebd950d27ab1c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Jul 2009 09:54:14 -0700 Subject: Tidyup prompted by #6554 - Wrong deallocation in sam_account_ok. Jeremy. --- source3/auth/auth_sam.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index a2634feb6c..26b45e47e5 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -226,10 +226,10 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx, if (*workstation_list) { bool invalid_ws = True; - char *tok; + char *tok = NULL; const char *s = workstation_list; + char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->wksta_name); - const char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->wksta_name); if (machine_name == NULL) return NT_STATUS_NO_MEMORY; @@ -251,6 +251,7 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx, TALLOC_FREE(tok); } TALLOC_FREE(tok); + TALLOC_FREE(machine_name); if (invalid_ws) return NT_STATUS_INVALID_WORKSTATION; -- cgit From 3b899af422075949f3c2f0d14787c7e11a3b16df Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 02:25:43 +0200 Subject: s3-lsa: implement _lsa_EnumAccountsWithUserRight(). Guenther --- source3/rpc_server/srv_lsa_nt.c | 63 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index c62991ee01..f5cfc53840 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -2246,6 +2246,63 @@ NTSTATUS _lsa_LookupPrivValue(pipes_struct *p, return NT_STATUS_OK; } +/*************************************************************************** + _lsa_EnumAccountsWithUserRight + ***************************************************************************/ + +NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, + struct lsa_EnumAccountsWithUserRight *r) +{ + NTSTATUS status; + struct lsa_info *info = NULL; + struct dom_sid *sids = NULL; + int num_sids = 0; + uint32_t i; + SE_PRIV mask; + + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) { + return NT_STATUS_INVALID_HANDLE; + } + + if (info->type != LSA_HANDLE_POLICY_TYPE) { + return NT_STATUS_INVALID_HANDLE; + } + + if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) { + return NT_STATUS_ACCESS_DENIED; + } + + if (!r->in.name || !r->in.name->string) { + return NT_STATUS_NO_SUCH_PRIVILEGE; + } + + if (!se_priv_from_name(r->in.name->string, &mask)) { + return NT_STATUS_NO_SUCH_PRIVILEGE; + } + + status = privilege_enum_sids(&mask, p->mem_ctx, + &sids, &num_sids); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + r->out.sids->num_sids = num_sids; + r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr, + r->out.sids->num_sids); + + for (i=0; i < r->out.sids->num_sids; i++) { + r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids, + &sids[i]); + if (!r->out.sids->sids[i].sid) { + TALLOC_FREE(r->out.sids->sids); + r->out.sids->num_sids = 0; + return NT_STATUS_NO_MEMORY; + } + } + + return NT_STATUS_OK; +} + /* * From here on the server routines are just dummy ones to make smbd link with * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are @@ -2318,12 +2375,6 @@ NTSTATUS _lsa_LookupPrivName(pipes_struct *p, struct lsa_LookupPrivName *r) return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, struct lsa_EnumAccountsWithUserRight *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r) { p->rng_fault_state = True; -- cgit From 35e45fb841e0c36ec2f8b2a8d7216700cc9af691 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 18:32:53 +0200 Subject: s3-lsa: implement _lsa_LookupPrivName(). Guenther --- source3/rpc_server/srv_lsa_nt.c | 51 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index f5cfc53840..1243787503 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -1916,6 +1916,51 @@ NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p, return NT_STATUS_OK; } +/*************************************************************************** + _lsa_LookupPrivName + ***************************************************************************/ + +NTSTATUS _lsa_LookupPrivName(pipes_struct *p, + struct lsa_LookupPrivName *r) +{ + struct lsa_info *info = NULL; + const char *name; + struct lsa_StringLarge *lsa_name; + + /* find the connection policy handle. */ + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) { + return NT_STATUS_INVALID_HANDLE; + } + + if (info->type != LSA_HANDLE_POLICY_TYPE) { + return NT_STATUS_INVALID_HANDLE; + } + + if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) { + return NT_STATUS_ACCESS_DENIED; + } + + name = luid_to_privilege_name((LUID *)r->in.luid); + if (!name) { + return NT_STATUS_NO_SUCH_PRIVILEGE; + } + + lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge); + if (!lsa_name) { + return NT_STATUS_NO_MEMORY; + } + + lsa_name->string = talloc_strdup(lsa_name, name); + if (!lsa_name->string) { + TALLOC_FREE(lsa_name); + return NT_STATUS_NO_MEMORY; + } + + *r->out.name = lsa_name; + + return NT_STATUS_OK; +} + /*************************************************************************** _lsa_QuerySecurity ***************************************************************************/ @@ -2369,12 +2414,6 @@ NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r) return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_LookupPrivName(pipes_struct *p, struct lsa_LookupPrivName *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r) { p->rng_fault_state = True; -- cgit From 4faef0da762fc1689ae9a3bc657fc6b5e77beb94 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 18:37:19 +0200 Subject: s3-lsa: Fix pointless check for sec_info flags in _lsa_QuerySecurity(). Guenther --- source3/rpc_server/srv_lsa_nt.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 1243787503..1a6d3bae16 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -1992,19 +1992,9 @@ NTSTATUS _lsa_QuerySecurity(pipes_struct *p, return status; } - switch (r->in.sec_info) { - case 1: - /* SD contains only the owner */ - if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL) - return NT_STATUS_NO_MEMORY; - break; - case 4: - /* SD contains only the ACL */ - if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL) - return NT_STATUS_NO_MEMORY; - break; - default: - return NT_STATUS_INVALID_LEVEL; + *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd); + if (!*r->out.sdbuf) { + return NT_STATUS_NO_MEMORY; } return status; -- cgit From 9f0bdd4e17ef5fe0b28a8ec4676d19eb4ffe6786 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Jul 2009 18:12:17 -0700 Subject: Remove an unused talloc context. Jeremy. --- source3/auth/auth.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'source3') diff --git a/source3/auth/auth.c b/source3/auth/auth.c index fd4c503752..ce8722a1b4 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -82,7 +82,6 @@ static void get_ntlm_challenge(struct auth_context *auth_context, DATA_BLOB challenge = data_blob_null; const char *challenge_set_by = NULL; auth_methods *auth_method; - TALLOC_CTX *mem_ctx; if (auth_context->challenge.length) { DEBUG(5, ("get_ntlm_challenge (auth subsystem): returning previous challenge by module %s (normal)\n", @@ -106,12 +105,8 @@ static void get_ntlm_challenge(struct auth_context *auth_context, continue; } - mem_ctx = talloc_init("auth_get_challenge for module %s", auth_method->name); - if (!mem_ctx) { - smb_panic("talloc_init() failed!"); - } - - challenge = auth_method->get_chal(auth_context, &auth_method->private_data, mem_ctx); + challenge = auth_method->get_chal(auth_context, &auth_method->private_data, + auth_context->mem_ctx); if (!challenge.length) { DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n", auth_method->name)); @@ -121,7 +116,6 @@ static void get_ntlm_challenge(struct auth_context *auth_context, challenge_set_by = auth_method->name; auth_context->challenge_set_method = auth_method; } - talloc_destroy(mem_ctx); } if (!challenge_set_by) { -- cgit From d5c20c072b464b675fbd5f37a94ae8a6ad403d49 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Jul 2009 18:13:46 -0700 Subject: Replace short-lived NULL talloc contexts with talloc_tos(). Jeremy. --- source3/lib/charcnv.c | 8 ++++---- source3/lib/dbwrap_tdb.c | 2 +- source3/lib/util_str.c | 34 +++++++++++++++++----------------- 3 files changed, 22 insertions(+), 22 deletions(-) (limited to 'source3') diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index a1663c1f38..272f107138 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -753,7 +753,7 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen) size_t size; smb_ucs2_t *buffer; - if (!push_ucs2_talloc(NULL, &buffer, src, &size)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) { return (size_t)-1; } @@ -837,7 +837,7 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) size_t size; smb_ucs2_t *buffer = NULL; - if (!convert_string_talloc(NULL, CH_UNIX, CH_UTF16LE, src, srclen, + if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen, (void **)(void *)&buffer, &size, True)) { @@ -951,7 +951,7 @@ size_t push_ascii_nstring(void *dest, const char *src) smb_ucs2_t *buffer; conv_silent = True; - if (!push_ucs2_talloc(NULL, &buffer, src, &buffer_len)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &buffer_len)) { smb_panic("failed to create UCS2 buffer"); } @@ -1268,7 +1268,7 @@ static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags) } if (flags & STR_UPPER) { - tmpbuf = strupper_talloc(NULL, src); + tmpbuf = strupper_talloc(talloc_tos(), src); if (!tmpbuf) { return (size_t)-1; } diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c index c71e073b41..297a351764 100644 --- a/source3/lib/dbwrap_tdb.c +++ b/source3/lib/dbwrap_tdb.c @@ -94,7 +94,7 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db, /* Do not accidently allocate/deallocate w/o need when debug level is lower than needed */ if(DEBUGLEVEL >= 10) { - char *keystr = hex_encode_talloc(NULL, (unsigned char*)key.dptr, key.dsize); + char *keystr = hex_encode_talloc(talloc_tos(), (unsigned char*)key.dptr, key.dsize); DEBUG(10, (DEBUGLEVEL > 10 ? "Locking key %s\n" : "Locking key %.20s\n", keystr)); diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 0aff9439e9..c197fd7515 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -96,14 +96,14 @@ int StrCaseCmp(const char *s, const char *t) return +1; } - if (!push_ucs2_talloc(NULL, &buffer_s, ps, &size)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) { return strcmp(ps, pt); /* Not quite the right answer, but finding the right one under this failure case is expensive, and it's pretty close */ } - if (!push_ucs2_talloc(NULL, &buffer_t, pt, &size)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) { TALLOC_FREE(buffer_s); return strcmp(ps, pt); /* Not quite the right answer, but finding the right one @@ -157,14 +157,14 @@ int StrnCaseCmp(const char *s, const char *t, size_t len) return 0; } - if (!push_ucs2_talloc(NULL, &buffer_s, ps, &size)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) { return strncmp(ps, pt, len-n); /* Not quite the right answer, but finding the right one under this failure case is expensive, and it's pretty close */ } - if (!push_ucs2_talloc(NULL, &buffer_t, pt, &size)) { + if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) { TALLOC_FREE(buffer_s); return strncmp(ps, pt, len-n); /* Not quite the right answer, but finding the right one @@ -366,7 +366,7 @@ size_t str_charnum(const char *s) { size_t ret, converted_size; smb_ucs2_t *tmpbuf2 = NULL; - if (!push_ucs2_talloc(NULL, &tmpbuf2, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) { return 0; } ret = strlen_w(tmpbuf2); @@ -384,7 +384,7 @@ size_t str_ascii_charnum(const char *s) { size_t ret, converted_size; char *tmpbuf2 = NULL; - if (!push_ascii_talloc(NULL, &tmpbuf2, s, &converted_size)) { + if (!push_ascii_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) { return 0; } ret = strlen(tmpbuf2); @@ -455,7 +455,7 @@ bool strhasupper(const char *s) bool ret; size_t converted_size; - if (!push_ucs2_talloc(NULL, &tmp, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) { return false; } @@ -480,7 +480,7 @@ bool strhaslower(const char *s) bool ret; size_t converted_size; - if (!push_ucs2_talloc(NULL, &tmp, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) { return false; } @@ -1177,7 +1177,7 @@ char *strchr_m(const char *src, char c) s = src; #endif - if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) { /* Wrong answer, but what can we do... */ return strchr(src, c); } @@ -1187,7 +1187,7 @@ char *strchr_m(const char *src, char c) return NULL; } *p = 0; - if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) { + if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) { SAFE_FREE(ws); /* Wrong answer, but what can we do... */ return strchr(src, c); @@ -1248,7 +1248,7 @@ char *strrchr_m(const char *s, char c) char *ret; size_t converted_size; - if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) { /* Wrong answer, but what can we do. */ return strrchr(s, c); } @@ -1258,7 +1258,7 @@ char *strrchr_m(const char *s, char c) return NULL; } *p = 0; - if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) { + if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) { TALLOC_FREE(ws); /* Wrong answer, but what can we do. */ return strrchr(s, c); @@ -1283,7 +1283,7 @@ char *strnrchr_m(const char *s, char c, unsigned int n) char *ret; size_t converted_size; - if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) { /* Too hard to try and get right. */ return NULL; } @@ -1293,7 +1293,7 @@ char *strnrchr_m(const char *s, char c, unsigned int n) return NULL; } *p = 0; - if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) { + if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) { TALLOC_FREE(ws); /* Too hard to try and get right. */ return NULL; @@ -1352,12 +1352,12 @@ char *strstr_m(const char *src, const char *findstr) s = src; #endif - if (!push_ucs2_talloc(NULL, &src_w, src, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &src_w, src, &converted_size)) { DEBUG(0,("strstr_m: src malloc fail\n")); return NULL; } - if (!push_ucs2_talloc(NULL, &find_w, findstr, &converted_size)) { + if (!push_ucs2_talloc(talloc_tos(), &find_w, findstr, &converted_size)) { TALLOC_FREE(src_w); DEBUG(0,("strstr_m: find malloc fail\n")); return NULL; @@ -1372,7 +1372,7 @@ char *strstr_m(const char *src, const char *findstr) } *p = 0; - if (!pull_ucs2_talloc(NULL, &s2, src_w, &converted_size)) { + if (!pull_ucs2_talloc(talloc_tos(), &s2, src_w, &converted_size)) { TALLOC_FREE(src_w); TALLOC_FREE(find_w); DEBUG(0,("strstr_m: dest malloc fail\n")); -- cgit From d4a87ee966adb9205169507fca5c07faefc4513e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Jul 2009 18:14:56 -0700 Subject: Replace more long-lived contexts with talloc_autofree_context(). Jeremy. --- source3/lib/ctdbd_conn.c | 2 +- source3/libsmb/spnego.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c index dde377581b..449e049ffa 100644 --- a/source3/lib/ctdbd_conn.c +++ b/source3/lib/ctdbd_conn.c @@ -358,7 +358,7 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid, goto next_pkt; } - if (!(msg_state = TALLOC_P(NULL, struct deferred_msg_state))) { + if (!(msg_state = TALLOC_P(talloc_autofree_context(), struct deferred_msg_state))) { DEBUG(0, ("talloc failed\n")); TALLOC_FREE(hdr); goto next_pkt; diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index ee2c3c3d5a..3fa9559cfb 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -41,7 +41,7 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) asn1_start_tag(asn1, ASN1_CONTEXT(0)); asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - token->mechTypes = TALLOC_P(NULL, const char *); + token->mechTypes = TALLOC_P(talloc_autofree_context(), const char *); for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { const char *p_oid = NULL; -- cgit From 5f295eb6f5fe60394b764a2e0bc76b77f6160664 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Jul 2009 18:28:58 -0700 Subject: More conversions of NULL -> talloc_autofree_context() so we at least know when we're using a long-lived context. Jeremy. --- source3/libsmb/clikrb5.c | 4 ++-- source3/libsmb/clispnego.c | 18 +++++++++--------- source3/libsmb/spnego.c | 21 +++++++++++++-------- 3 files changed, 24 insertions(+), 19 deletions(-) (limited to 'source3') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 8a567dc751..152c23bd15 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -346,7 +346,7 @@ bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx, } asn1_start_tag(data, ASN1_CONTEXT(2)); - asn1_read_OctetString(data, NULL, &edata_contents); + asn1_read_OctetString(data, talloc_autofree_context(), &edata_contents); asn1_end_tag(data); asn1_end_tag(data); asn1_end_tag(data); @@ -389,7 +389,7 @@ bool unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ asn1_end_tag(data); asn1_start_tag(data, ASN1_CONTEXT(1)); - asn1_read_OctetString(data, NULL, &pac_contents); + asn1_read_OctetString(data, talloc_autofree_context(), &pac_contents); asn1_end_tag(data); asn1_end_tag(data); asn1_end_tag(data); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index fb95d71925..e586d976cf 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -151,7 +151,7 @@ bool spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(data,ASN1_SEQUENCE(0)); for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) { const char *oid_str = NULL; - asn1_read_OID(data,NULL,&oid_str); + asn1_read_OID(data,talloc_autofree_context(),&oid_str); OIDs[i] = CONST_DISCARD(char *, oid_str); } OIDs[i] = NULL; @@ -163,7 +163,7 @@ bool spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(data, ASN1_CONTEXT(3)); asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_start_tag(data, ASN1_CONTEXT(0)); - asn1_read_GeneralString(data,NULL,principal); + asn1_read_GeneralString(data,talloc_autofree_context(),principal); asn1_end_tag(data); asn1_end_tag(data); asn1_end_tag(data); @@ -256,7 +256,7 @@ bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se asn1_start_tag(data, ASN1_SEQUENCE(0)); for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) { const char *oid_str = NULL; - asn1_read_OID(data,NULL,&oid_str); + asn1_read_OID(data,talloc_autofree_context(),&oid_str); OIDs[i] = CONST_DISCARD(char *, oid_str); } OIDs[i] = NULL; @@ -276,7 +276,7 @@ bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se } asn1_start_tag(data, ASN1_CONTEXT(2)); - asn1_read_OctetString(data,NULL,secblob); + asn1_read_OctetString(data,talloc_autofree_context(),secblob); asn1_end_tag(data); asn1_end_tag(data); @@ -436,13 +436,13 @@ bool spnego_parse_challenge(const DATA_BLOB blob, asn1_end_tag(data); asn1_start_tag(data,ASN1_CONTEXT(2)); - asn1_read_OctetString(data, NULL, chal1); + asn1_read_OctetString(data, talloc_autofree_context(), chal1); asn1_end_tag(data); /* the second challenge is optional (XP doesn't send it) */ if (asn1_tag_remaining(data)) { asn1_start_tag(data,ASN1_CONTEXT(3)); - asn1_read_OctetString(data, NULL, chal2); + asn1_read_OctetString(data, talloc_autofree_context(), chal2); asn1_end_tag(data); } @@ -505,7 +505,7 @@ bool spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) asn1_start_tag(data, ASN1_CONTEXT(1)); asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_start_tag(data, ASN1_CONTEXT(2)); - asn1_read_OctetString(data, NULL, auth); + asn1_read_OctetString(data, talloc_autofree_context(), auth); asn1_end_tag(data); asn1_end_tag(data); asn1_end_tag(data); @@ -609,7 +609,7 @@ bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, if (asn1_tag_remaining(data)) { asn1_start_tag(data,ASN1_CONTEXT(2)); - asn1_read_OctetString(data, NULL, auth); + asn1_read_OctetString(data, talloc_autofree_context(), auth); asn1_end_tag(data); } } else if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { @@ -623,7 +623,7 @@ bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, if (asn1_tag_remaining(data)) { DATA_BLOB mechList = data_blob_null; asn1_start_tag(data, ASN1_CONTEXT(3)); - asn1_read_OctetString(data, NULL, &mechList); + asn1_read_OctetString(data, talloc_autofree_context(), &mechList); asn1_end_tag(data); data_blob_free(&mechList); DEBUG(5,("spnego_parse_auth_response received mechListMIC, " diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index 3fa9559cfb..528c7f4009 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -46,12 +46,13 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) 0 < asn1_tag_remaining(asn1); i++) { const char *p_oid = NULL; token->mechTypes = - TALLOC_REALLOC_ARRAY(NULL, token->mechTypes, const char *, i + 2); + TALLOC_REALLOC_ARRAY(talloc_autofree_context(), + token->mechTypes, const char *, i + 2); if (!token->mechTypes) { asn1->has_error = True; return False; } - asn1_read_OID(asn1, NULL, &p_oid); + asn1_read_OID(asn1, talloc_autofree_context(), &p_oid); token->mechTypes[i] = p_oid; } token->mechTypes[i] = NULL; @@ -69,14 +70,15 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) /* Read mechToken */ case ASN1_CONTEXT(2): asn1_start_tag(asn1, ASN1_CONTEXT(2)); - asn1_read_OctetString(asn1, NULL, &token->mechToken); + asn1_read_OctetString(asn1, + talloc_autofree_context(), &token->mechToken); asn1_end_tag(asn1); break; /* Read mecListMIC */ case ASN1_CONTEXT(3): asn1_start_tag(asn1, ASN1_CONTEXT(3)); if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) { - asn1_read_OctetString(asn1, NULL, + asn1_read_OctetString(asn1, talloc_autofree_context(), &token->mechListMIC); } else { /* RFC 2478 says we have an Octet String here, @@ -84,7 +86,8 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) char *mechListMIC; asn1_push_tag(asn1, ASN1_SEQUENCE(0)); asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_read_GeneralString(asn1, NULL, &mechListMIC); + asn1_read_GeneralString(asn1, + talloc_autofree_context(), &mechListMIC); asn1_pop_tag(asn1); asn1_pop_tag(asn1); @@ -188,19 +191,21 @@ static bool read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) case ASN1_CONTEXT(1): { const char *mech = NULL; asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_read_OID(asn1, NULL, &mech); + asn1_read_OID(asn1, talloc_autofree_context(), &mech); asn1_end_tag(asn1); token->supportedMech = CONST_DISCARD(char *, mech); } break; case ASN1_CONTEXT(2): asn1_start_tag(asn1, ASN1_CONTEXT(2)); - asn1_read_OctetString(asn1, NULL, &token->responseToken); + asn1_read_OctetString(asn1, + talloc_autofree_context(), &token->responseToken); asn1_end_tag(asn1); break; case ASN1_CONTEXT(3): asn1_start_tag(asn1, ASN1_CONTEXT(3)); - asn1_read_OctetString(asn1, NULL, &token->mechListMIC); + asn1_read_OctetString(asn1, + talloc_autofree_context(), &token->mechListMIC); asn1_end_tag(asn1); break; default: -- cgit From 20f40d1c5065d909f4274b86de20fa941fa20405 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Sat, 18 Jul 2009 08:01:56 +0800 Subject: s3: Fix crsh in net usershare list Signed-off-by: Bo Yang --- source3/utils/net_usershare.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3') diff --git a/source3/utils/net_usershare.c b/source3/utils/net_usershare.c index d82d30bc2d..6eacb1386c 100644 --- a/source3/utils/net_usershare.c +++ b/source3/utils/net_usershare.c @@ -974,6 +974,7 @@ static int net_usershare_list(struct net_context *c, int argc, pi.ctx = ctx; pi.op = US_LIST_OP; + pi.c = c; ret = process_share_list(info_fn, &pi); talloc_destroy(ctx); -- cgit From e7daa0d7049933e5a743f7e6db886f624490c53d Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Sat, 18 Jul 2009 08:03:57 +0800 Subject: s3: don't do this, upper callbacks will check it Signed-off-by: Bo Yang --- source3/winbindd/winbindd_dual.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3') diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 92f0d60817..ab07c9767d 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -179,10 +179,6 @@ int wb_child_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, if (tevent_req_is_unix_error(req, err)) { return -1; } - if (state->response->result != WINBINDD_OK) { - *err = EIO; /* EIO doesn't fit, but what would be better? */ - return -1; - } *presponse = talloc_move(mem_ctx, &state->response); return 0; } -- cgit From b180fe34a71a595d0dea8e72877149361b531e02 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Sat, 18 Jul 2009 10:46:11 +0800 Subject: s3: compile warning and upn handling Signed-off-by: Bo Yang --- source3/winbindd/winbindd_sid.c | 5 +++++ source3/winbindd/winbindd_util.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/winbindd/winbindd_sid.c b/source3/winbindd/winbindd_sid.c index c091cd7f53..f8cf7db920 100644 --- a/source3/winbindd/winbindd_sid.c +++ b/source3/winbindd/winbindd_sid.c @@ -93,6 +93,11 @@ void winbindd_lookupname(struct winbindd_cli_state *state) *p = 0; name_domain = state->request->data.name.name; name_user = p+1; + } else if ((p = strchr(state->request->data.name.name, '@')) != NULL) { + /* upn */ + name_domain = p + 1; + *p = 0; + name_user = state->request->data.name.name; } else { name_domain = state->request->data.name.dom_name; name_user = state->request->data.name.name; diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 283eee09af..44ae814ae9 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -996,7 +996,8 @@ bool parse_domain_user(const char *domuser, fstring domain, fstring user) if ( assume_domain(lp_workgroup())) { fstrcpy(domain, lp_workgroup()); } else if ((p = strchr(domuser, '@')) != NULL) { - fstrcpy(domain, ""); + fstrcpy(domain, p + 1); + user[PTR_DIFF(p, domuser)] = 0; } else { return False; } -- cgit From dee787cb774452525fe10b13e3d5210f31dcb3eb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 11:54:49 +0200 Subject: s3-rpcclient: add LSA createsecret command. Guenther --- source3/rpcclient/cmd_lsarpc.c | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'source3') diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index ef3187579a..f1e28d5d8f 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1356,6 +1356,48 @@ static NTSTATUS cmd_lsa_del_priv(struct rpc_pipe_client *cli, return result; } +static NTSTATUS cmd_lsa_create_secret(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle, sec_handle; + struct lsa_String name; + + if (argc < 2) { + printf("Usage: %s name\n", argv[0]); + return NT_STATUS_OK; + } + + status = rpccli_lsa_open_policy2(cli, mem_ctx, + true, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + init_lsa_String(&name, argv[1]); + + status = rpccli_lsa_CreateSecret(cli, mem_ctx, + &handle, + name, + SEC_FLAG_MAXIMUM_ALLOWED, + &sec_handle); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + done: + if (is_valid_policy_hnd(&sec_handle)) { + rpccli_lsa_Close(cli, mem_ctx, &sec_handle); + } + if (is_valid_policy_hnd(&handle)) { + rpccli_lsa_Close(cli, mem_ctx, &handle); + } + + return status; +} /* List of commands exported by this module */ @@ -1384,6 +1426,7 @@ struct cmd_set lsarpc_commands[] = { { "lsaquerytrustdominfobyname",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobyname, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query LSA trusted domains info (given a name), only works for Windows > 2k", "" }, { "lsaquerytrustdominfobysid",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobysid, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query LSA trusted domains info (given a SID)", "" }, { "getusername", RPC_RTYPE_NTSTATUS, cmd_lsa_get_username, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Get username", "" }, + { "createsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_create_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Create Secret", "" }, { NULL } }; -- cgit From f848f4f4d3e3d3920ea1c6b94bb28ce7e7cdb73d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 11:58:10 +0200 Subject: s3-rpcclient: add LSA deletesecret command. Guenther --- source3/rpcclient/cmd_lsarpc.c | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'source3') diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index f1e28d5d8f..5fa30c2445 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1399,6 +1399,55 @@ static NTSTATUS cmd_lsa_create_secret(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_lsa_delete_secret(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle, sec_handle; + struct lsa_String name; + + if (argc < 2) { + printf("Usage: %s name\n", argv[0]); + return NT_STATUS_OK; + } + + status = rpccli_lsa_open_policy2(cli, mem_ctx, + true, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + init_lsa_String(&name, argv[1]); + + status = rpccli_lsa_OpenSecret(cli, mem_ctx, + &handle, + name, + SEC_FLAG_MAXIMUM_ALLOWED, + &sec_handle); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpccli_lsa_DeleteObject(cli, mem_ctx, + &sec_handle); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + done: + if (is_valid_policy_hnd(&sec_handle)) { + rpccli_lsa_Close(cli, mem_ctx, &sec_handle); + } + if (is_valid_policy_hnd(&handle)) { + rpccli_lsa_Close(cli, mem_ctx, &handle); + } + + return status; +} + /* List of commands exported by this module */ struct cmd_set lsarpc_commands[] = { @@ -1427,6 +1476,7 @@ struct cmd_set lsarpc_commands[] = { { "lsaquerytrustdominfobysid",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobysid, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query LSA trusted domains info (given a SID)", "" }, { "getusername", RPC_RTYPE_NTSTATUS, cmd_lsa_get_username, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Get username", "" }, { "createsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_create_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Create Secret", "" }, + { "deletesecret", RPC_RTYPE_NTSTATUS, cmd_lsa_delete_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Delete Secret", "" }, { NULL } }; -- cgit From 1a862349e153250c7bad540f584bceea19738021 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 12:03:58 +0200 Subject: s3-rpcclient: add LSA querysecret command. Guenther --- source3/rpcclient/cmd_lsarpc.c | 86 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'source3') diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 5fa30c2445..724ecf44d4 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1448,6 +1448,91 @@ static NTSTATUS cmd_lsa_delete_secret(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_lsa_query_secret(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle, sec_handle; + struct lsa_String name; + struct lsa_DATA_BUF_PTR new_val; + NTTIME new_mtime = 0; + struct lsa_DATA_BUF_PTR old_val; + NTTIME old_mtime = 0; + DATA_BLOB session_key; + DATA_BLOB new_blob = data_blob_null; + DATA_BLOB old_blob = data_blob_null; + char *new_secret, *old_secret; + + if (argc < 2) { + printf("Usage: %s name\n", argv[0]); + return NT_STATUS_OK; + } + + status = rpccli_lsa_open_policy2(cli, mem_ctx, + true, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + init_lsa_String(&name, argv[1]); + + status = rpccli_lsa_OpenSecret(cli, mem_ctx, + &handle, + name, + SEC_FLAG_MAXIMUM_ALLOWED, + &sec_handle); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + ZERO_STRUCT(new_val); + ZERO_STRUCT(old_val); + + status = rpccli_lsa_QuerySecret(cli, mem_ctx, + &sec_handle, + &new_val, + &new_mtime, + &old_val, + &old_mtime); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = cli_get_session_key(mem_ctx, cli, &session_key); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + if (new_val.buf) { + new_blob = data_blob_const(new_val.buf->data, new_val.buf->length); + } + if (old_val.buf) { + old_blob = data_blob_const(old_val.buf->data, old_val.buf->length); + } + + new_secret = sess_decrypt_string(mem_ctx, &new_blob, &session_key); + old_secret = sess_decrypt_string(mem_ctx, &old_blob, &session_key); + if (new_secret) { + d_printf("new secret: %s\n", new_secret); + } + if (old_secret) { + d_printf("old secret: %s\n", old_secret); + } + + done: + if (is_valid_policy_hnd(&sec_handle)) { + rpccli_lsa_Close(cli, mem_ctx, &sec_handle); + } + if (is_valid_policy_hnd(&handle)) { + rpccli_lsa_Close(cli, mem_ctx, &handle); + } + + return status; +} + /* List of commands exported by this module */ struct cmd_set lsarpc_commands[] = { @@ -1477,6 +1562,7 @@ struct cmd_set lsarpc_commands[] = { { "getusername", RPC_RTYPE_NTSTATUS, cmd_lsa_get_username, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Get username", "" }, { "createsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_create_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Create Secret", "" }, { "deletesecret", RPC_RTYPE_NTSTATUS, cmd_lsa_delete_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Delete Secret", "" }, + { "querysecret", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query Secret", "" }, { NULL } }; -- cgit From 7194fc6a690722e5c896ee367bcba659d131fa85 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 12:56:30 +0200 Subject: s3-rpcclient: add LSA setsecret command. Guenther --- source3/rpcclient/cmd_lsarpc.c | 71 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'source3') diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 724ecf44d4..5000255c84 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1533,6 +1533,76 @@ static NTSTATUS cmd_lsa_query_secret(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_lsa_set_secret(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle, sec_handle; + struct lsa_String name; + struct lsa_DATA_BUF new_val; + struct lsa_DATA_BUF old_val; + DATA_BLOB enc_key; + DATA_BLOB session_key; + + if (argc < 3) { + printf("Usage: %s name secret\n", argv[0]); + return NT_STATUS_OK; + } + + status = rpccli_lsa_open_policy2(cli, mem_ctx, + true, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + init_lsa_String(&name, argv[1]); + + status = rpccli_lsa_OpenSecret(cli, mem_ctx, + &handle, + name, + SEC_FLAG_MAXIMUM_ALLOWED, + &sec_handle); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + ZERO_STRUCT(new_val); + ZERO_STRUCT(old_val); + + status = cli_get_session_key(mem_ctx, cli, &session_key); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + enc_key = sess_encrypt_string(argv[2], &session_key); + + new_val.length = enc_key.length; + new_val.size = enc_key.length; + new_val.data = enc_key.data; + + status = rpccli_lsa_SetSecret(cli, mem_ctx, + &sec_handle, + &new_val, + NULL); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + done: + if (is_valid_policy_hnd(&sec_handle)) { + rpccli_lsa_Close(cli, mem_ctx, &sec_handle); + } + if (is_valid_policy_hnd(&handle)) { + rpccli_lsa_Close(cli, mem_ctx, &handle); + } + + return status; +} + + /* List of commands exported by this module */ struct cmd_set lsarpc_commands[] = { @@ -1563,6 +1633,7 @@ struct cmd_set lsarpc_commands[] = { { "createsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_create_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Create Secret", "" }, { "deletesecret", RPC_RTYPE_NTSTATUS, cmd_lsa_delete_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Delete Secret", "" }, { "querysecret", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query Secret", "" }, + { "setsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_set_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Set Secret", "" }, { NULL } }; -- cgit From 27c39a280460a1ae94bd2936535263c77729af5a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 13:30:37 +0200 Subject: s3-rpcclient: add LSA retrieveprivatedata command. Guenther --- source3/rpcclient/cmd_lsarpc.c | 60 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'source3') diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 5000255c84..c4f8e2654b 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1602,6 +1602,65 @@ static NTSTATUS cmd_lsa_set_secret(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_lsa_retrieve_private_data(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle; + struct lsa_String name; + struct lsa_DATA_BUF *val; + DATA_BLOB session_key; + DATA_BLOB blob; + char *secret; + + if (argc < 2) { + printf("Usage: %s name\n", argv[0]); + return NT_STATUS_OK; + } + + status = rpccli_lsa_open_policy2(cli, mem_ctx, + true, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + init_lsa_String(&name, argv[1]); + + ZERO_STRUCT(val); + + status = rpccli_lsa_RetrievePrivateData(cli, mem_ctx, + &handle, + &name, + &val); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = cli_get_session_key(mem_ctx, cli, &session_key); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + if (val) { + blob = data_blob_const(val->data, val->length); + } + + secret = sess_decrypt_string(mem_ctx, &blob, &session_key); + if (secret) { + d_printf("secret: %s\n", secret); + } + + done: + if (is_valid_policy_hnd(&handle)) { + rpccli_lsa_Close(cli, mem_ctx, &handle); + } + + return status; +} + /* List of commands exported by this module */ @@ -1634,6 +1693,7 @@ struct cmd_set lsarpc_commands[] = { { "deletesecret", RPC_RTYPE_NTSTATUS, cmd_lsa_delete_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Delete Secret", "" }, { "querysecret", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query Secret", "" }, { "setsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_set_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Set Secret", "" }, + { "retrieveprivatedata", RPC_RTYPE_NTSTATUS, cmd_lsa_retrieve_private_data, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Retrieve Private Data", "" }, { NULL } }; -- cgit From 7e9f8f0f951912943208af8cdb47c6b733b0d82c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 13:37:08 +0200 Subject: s3-rpcclient: add LSA storeprivatedata command. Guenther --- source3/rpcclient/cmd_lsarpc.c | 56 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'source3') diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index c4f8e2654b..d7f8041779 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1661,6 +1661,61 @@ static NTSTATUS cmd_lsa_retrieve_private_data(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_lsa_store_private_data(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle; + struct lsa_String name; + struct lsa_DATA_BUF val; + DATA_BLOB session_key; + DATA_BLOB enc_key; + + if (argc < 3) { + printf("Usage: %s name secret\n", argv[0]); + return NT_STATUS_OK; + } + + status = rpccli_lsa_open_policy2(cli, mem_ctx, + true, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + init_lsa_String(&name, argv[1]); + + ZERO_STRUCT(val); + + status = cli_get_session_key(mem_ctx, cli, &session_key); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + enc_key = sess_encrypt_string(argv[2], &session_key); + + val.length = enc_key.length; + val.size = enc_key.length; + val.data = enc_key.data; + + status = rpccli_lsa_StorePrivateData(cli, mem_ctx, + &handle, + &name, + &val); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + done: + if (is_valid_policy_hnd(&handle)) { + rpccli_lsa_Close(cli, mem_ctx, &handle); + } + + return status; +} + /* List of commands exported by this module */ @@ -1694,6 +1749,7 @@ struct cmd_set lsarpc_commands[] = { { "querysecret", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query Secret", "" }, { "setsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_set_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Set Secret", "" }, { "retrieveprivatedata", RPC_RTYPE_NTSTATUS, cmd_lsa_retrieve_private_data, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Retrieve Private Data", "" }, + { "storeprivatedata", RPC_RTYPE_NTSTATUS, cmd_lsa_store_private_data, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Store Private Data", "" }, { NULL } }; -- cgit From d1903cb7f2269c3eeb27ae05f734cbd8a542ee7f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 13:44:55 +0200 Subject: s3-lsa: Fix policy handle memleak and handle type check in _lsa_DeleteObject(). Guenther --- source3/rpc_server/srv_lsa_nt.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 1a6d3bae16..50bafc9349 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -1304,12 +1304,22 @@ NTSTATUS _lsa_DeleteObject(pipes_struct *p, return NT_STATUS_ACCESS_DENIED; } - status = privilege_delete_account(&info->sid); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n", - nt_errstr(status))); + switch (info->type) { + case LSA_HANDLE_ACCOUNT_TYPE: + status = privilege_delete_account(&info->sid); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n", + nt_errstr(status))); + return status; + } + break; + default: + return NT_STATUS_INVALID_HANDLE; } + close_policy_hnd(p, r->in.handle); + ZERO_STRUCTP(r->out.handle); + return status; } -- cgit From 864e8097525c2f4b05e139e78dd40dea42ab2c39 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 16:28:11 +0200 Subject: s3-lsa: also implement level 13 in lsa_QueryInfoPolicy. Guenther --- source3/rpc_server/srv_lsa_nt.c | 43 +++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 19 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 50bafc9349..c3eea6fe50 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -620,7 +620,8 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, break; } break; - case LSA_POLICY_INFO_DNS: { + case LSA_POLICY_INFO_DNS: + case LSA_POLICY_INFO_DNS_INT: { struct pdb_domain_info *dominfo; if ((pdb_capabilities() & PDB_CAP_ADS) == 0) { @@ -658,6 +659,28 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, return status; } +/*************************************************************************** + _lsa_QueryInfoPolicy2 + ***************************************************************************/ + +NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p, + struct lsa_QueryInfoPolicy2 *r2) +{ + struct lsa_QueryInfoPolicy r; + + if ((pdb_capabilities() & PDB_CAP_ADS) == 0) { + p->rng_fault_state = True; + return NT_STATUS_NOT_IMPLEMENTED; + } + + ZERO_STRUCT(r); + r.in.handle = r2->in.handle; + r.in.level = r2->in.level; + r.out.info = r2->out.info; + + return _lsa_QueryInfoPolicy(p, &r); +} + /*************************************************************************** _lsa_lookup_sids_internal ***************************************************************************/ @@ -2444,24 +2467,6 @@ NTSTATUS _lsa_RetrievePrivateData(pipes_struct *p, struct lsa_RetrievePrivateDat return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p, - struct lsa_QueryInfoPolicy2 *r2) -{ - struct lsa_QueryInfoPolicy r; - - if ((pdb_capabilities() & PDB_CAP_ADS) == 0) { - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; - } - - ZERO_STRUCT(r); - r.in.handle = r2->in.handle; - r.in.level = r2->in.level; - r.out.info = r2->out.info; - - return _lsa_QueryInfoPolicy(p, &r); -} - NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r) { p->rng_fault_state = True; -- cgit From 3eea254e5bfacdac1d7bb2b72863a31e0c850968 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 16:32:04 +0200 Subject: s3-lsa: add (not yet activate) level specific access checks for _lsa_QueryInfoPolicy. Guenther --- source3/rpc_server/srv_lsa_nt.c | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'source3') diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index c3eea6fe50..bbad9b18d2 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -505,6 +505,7 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, const char *name; DOM_SID *sid = NULL; union lsa_PolicyInformation *info = NULL; + uint32_t acc_required = 0; if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) return NT_STATUS_INVALID_HANDLE; @@ -513,6 +514,47 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; } + switch (r->in.level) { + case LSA_POLICY_INFO_AUDIT_LOG: + case LSA_POLICY_INFO_AUDIT_EVENTS: + acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION; + break; + case LSA_POLICY_INFO_DOMAIN: + acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION; + break; + case LSA_POLICY_INFO_PD: + acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION; + break; + case LSA_POLICY_INFO_ACCOUNT_DOMAIN: + acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION; + break; + case LSA_POLICY_INFO_ROLE: + case LSA_POLICY_INFO_REPLICA: + acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION; + break; + case LSA_POLICY_INFO_QUOTA: + acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION; + break; + case LSA_POLICY_INFO_MOD: + case LSA_POLICY_INFO_AUDIT_FULL_SET: + /* according to MS-LSAD 3.1.4.4.3 */ + return NT_STATUS_INVALID_PARAMETER; + case LSA_POLICY_INFO_AUDIT_FULL_QUERY: + acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION; + break; + case LSA_POLICY_INFO_DNS: + case LSA_POLICY_INFO_DNS_INT: + case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN: + acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION; + break; + default: + break; + } + + if (!(handle->access & acc_required)) { + /* return NT_STATUS_ACCESS_DENIED; */ + } + info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation); if (!info) { return NT_STATUS_NO_MEMORY; -- cgit From 2a26b2ac87b3a07a29ec1db128f42059ef2e4998 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 18:45:29 +0200 Subject: s3-lsa: Fix access_mask calculation for new handle in _lsa_CreateAccount(). Guenther --- source3/rpc_server/srv_lsa_nt.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index bbad9b18d2..6fb8327576 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -1637,8 +1637,12 @@ NTSTATUS _lsa_GetUserName(pipes_struct *p, NTSTATUS _lsa_CreateAccount(pipes_struct *p, struct lsa_CreateAccount *r) { + NTSTATUS status; struct lsa_info *handle; struct lsa_info *info; + uint32_t acc_granted; + struct security_descriptor *psd; + uint32_t sd_size; /* find the connection policy handle. */ if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) @@ -1650,12 +1654,26 @@ NTSTATUS _lsa_CreateAccount(pipes_struct *p, /* check if the user has enough rights */ - /* - * I don't know if it's the right one. not documented. - * but guessed with rpcclient. - */ - if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) + if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) { return NT_STATUS_ACCESS_DENIED; + } + + /* map the generic bits to the lsa policy ones */ + se_map_generic(&r->in.access_mask, &lsa_account_mapping); + + status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, + &lsa_account_mapping, + r->in.sid, LSA_POLICY_ALL_ACCESS); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = access_check_object(psd, p->server_info->ptok, + NULL, 0, r->in.access_mask, + &acc_granted, "_lsa_CreateAccount"); + if (!NT_STATUS_IS_OK(status)) { + return status; + } if ( is_privileged_sid( r->in.sid ) ) return NT_STATUS_OBJECT_NAME_COLLISION; @@ -1668,7 +1686,7 @@ NTSTATUS _lsa_CreateAccount(pipes_struct *p, } info->sid = *r->in.sid; - info->access = r->in.access_mask; + info->access = acc_granted; info->type = LSA_HANDLE_ACCOUNT_TYPE; /* get a (unique) handle. open a policy on it. */ -- cgit From 3e661d4c8e1846d8f64fe029981fb7628e6211d8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 16 Jul 2009 01:05:25 +0200 Subject: s3-lsa: let _lsa_Delete return NT_STATUS_NOT_SUPPORTED as w2k3 does. Guenther --- source3/rpc_server/srv_lsa_nt.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 6fb8327576..ace045cfa5 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -2431,18 +2431,22 @@ NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, return NT_STATUS_OK; } +/*************************************************************************** + _lsa_Delete + ***************************************************************************/ + +NTSTATUS _lsa_Delete(pipes_struct *p, + struct lsa_Delete *r) +{ + return NT_STATUS_NOT_SUPPORTED; +} + /* * From here on the server routines are just dummy ones to make smbd link with * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are * pulling the server stubs across one by one. */ -NTSTATUS _lsa_Delete(pipes_struct *p, struct lsa_Delete *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r) { p->rng_fault_state = True; -- cgit From ffbcf3b491293db92141f7936e3fefc81066e730 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Jul 2009 15:39:40 +0200 Subject: s3-rpcclient: add createprinteric command. Guenther --- source3/rpcclient/cmd_spoolss.c | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'source3') diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index cbff69ff17..48f9df3cac 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -3430,6 +3430,48 @@ static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli, return werror; } +static WERROR cmd_spoolss_create_printer_ic(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + WERROR result; + NTSTATUS status; + struct policy_handle handle, gdi_handle; + const char *printername; + struct spoolss_DevmodeContainer devmode_ctr; + + RPCCLIENT_PRINTERNAME(printername, cli, argv[1]); + + result = rpccli_spoolss_openprinter_ex(cli, mem_ctx, + printername, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle); + if (!W_ERROR_IS_OK(result)) { + return result; + } + + ZERO_STRUCT(devmode_ctr); + + status = rpccli_spoolss_CreatePrinterIC(cli, mem_ctx, + &handle, + &gdi_handle, + &devmode_ctr, + &result); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + done: + if (is_valid_policy_hnd(&gdi_handle)) { + rpccli_spoolss_DeletePrinterIC(cli, mem_ctx, &gdi_handle, NULL); + } + if (is_valid_policy_hnd(&handle)) { + rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); + } + + return result; +} + /* List of commands exported by this module */ struct cmd_set spoolss_commands[] = { @@ -3469,6 +3511,7 @@ struct cmd_set spoolss_commands[] = { { "enumprocs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors", "" }, { "enumprocdatatypes", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" }, { "enummonitors", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" }, + { "createprinteric", RPC_RTYPE_WERROR, NULL, cmd_spoolss_create_printer_ic, &ndr_table_spoolss.syntax_id, NULL, "Create Printer IC", "" }, { NULL } }; -- cgit From 6a9e0039100b57f9626e87defec6720c476b9789 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 17:36:26 -0700 Subject: Fix bug #6564 - SetPrinter fails (panics) as non root. Missing become_root()/unbecome_root() around reload_services. Jeremy. --- source3/rpc_server/srv_spoolss_nt.c | 4 ++++ source3/smbd/server.c | 1 + 2 files changed, 5 insertions(+) (limited to 'source3') diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 48ac103667..9dc1a26e3b 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -309,7 +309,9 @@ static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const c return WERR_BADFID; /* What to return here? */ /* go ahead and re-read the services immediately */ + become_root(); reload_services(false); + unbecome_root(); if ( lp_servicenumber( sharename ) < 0 ) return WERR_ACCESS_DENIED; @@ -6034,7 +6036,9 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV } /* reload our services immediately */ + become_root(); reload_services(false); + unbecome_root(); numlines = 0; /* Get lines and convert them back to dos-codepage */ diff --git a/source3/smbd/server.c b/source3/smbd/server.c index a1dec0327c..4b1c803d75 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -94,6 +94,7 @@ static void smb_conf_updated(struct messaging_context *msg, { DEBUG(10,("smb_conf_updated: Got message saying smb.conf was " "updated. Reloading.\n")); + change_to_root_user(); reload_services(False); } -- cgit From 55b4231c773ef17b8e628f33d6c3c9d5335df9da Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 17:57:48 -0700 Subject: Move the initialization of smbd_server_conn from smbd/process, after the accept and fork, to smbd_init_globals(), so it's done immediately on server startup. This is needed as some messages are sent to all active smbd processes (including the master listening daemon). If it gets a message that forces it to scan it's current connections (ie. conn_find()) then it discovers that sconn->smb1.tcons.Connections dereferences null (as sconn == NULL in the parent) and crashes. Yes, I could fix all cases where sconn is used and explicitly check for NULL but this fix is easier. It means that the smbd_event_context() is initialized in the master daemon and then re-initialized after fork, but that should be being done correctly in every fork call anyway. Without this change the previous fix 6a9e0039100b57f9626e87defec6720c476b9789 still panics in the reproducible test case for bug 6564, as this is one case where such a message (MSG_SMB_CONF_UPDATED) is sent to the parent. Metze please check. This change passes valgrind. Jeremy. --- source3/smbd/globals.c | 5 +++++ source3/smbd/process.c | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source3') diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c index 15550ed455..317304a86d 100644 --- a/source3/smbd/globals.c +++ b/source3/smbd/globals.c @@ -153,4 +153,9 @@ void smbd_init_globals(void) ZERO_STRUCT(conn_ctx_stack); ZERO_STRUCT(sec_ctx_stack); + + smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection); + if (!smbd_server_conn) { + exit_server("failed to create smbd_server_connection"); + } } diff --git a/source3/smbd/process.c b/source3/smbd/process.c index b26bc150db..c2065caf79 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -2015,11 +2015,6 @@ void smbd_process(void) TALLOC_CTX *frame = talloc_stackframe(); char remaddr[INET6_ADDRSTRLEN]; - smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection); - if (!smbd_server_conn) { - exit_server("failed to create smbd_server_connection"); - } - if (lp_maxprotocol() == PROTOCOL_SMB2 && lp_security() != SEC_SHARE) { smbd_server_conn->allow_smb2 = true; -- cgit From eba2eb45e208e6b3091c01ff1d40fd966e72a044 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 18:05:10 -0700 Subject: Fix a typo reading uninitialized memory. Caught by valgrind. Jeremy. --- source3/lib/system.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/lib/system.c b/source3/lib/system.c index ffc236e93b..6a4f5d5413 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -458,8 +458,6 @@ static struct timespec calc_create_time_stat_ex(const struct stat_ex *st) static void get_create_timespec(const struct stat *pst, struct stat_ex *dst) { - struct timespec ret; - if (S_ISDIR(pst->st_mode) && lp_fake_dir_create_times()) { dst->st_ex_btime.tv_sec = 315493200L; /* 1/1/1980 */ dst->st_ex_btime.tv_nsec = 0; @@ -483,7 +481,7 @@ static void get_create_timespec(const struct stat *pst, struct stat_ex *dst) /* Deal with systems that don't initialize birthtime correctly. * Pointed out by SATOH Fumiyasu . */ - if (null_timespec(ret)) { + if (null_timespec(dst->st_ex_btime)) { dst->st_ex_btime = calc_create_time_stat(pst); dst->st_ex_calculated_birthtime = true; } -- cgit From 7254898bc760984357f068926cb4504c154d5cae Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 21:26:16 -0700 Subject: Fix coverity CID 931. This check is redundent as smb_fname can never be null in this function. Jeremy. --- source3/smbd/trans2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 06536f9e21..561c18a29d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -7244,7 +7244,7 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, case SMB_SET_FILE_UNIX_HLINK: { - if (fsp || smb_fname == NULL) { + if (fsp) { /* We must have a pathname for this. */ return NT_STATUS_INVALID_LEVEL; } -- cgit From d654782806af37ba0d249f695ebecaad2a6ad3a7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 21:29:28 -0700 Subject: Fix coverity CID 930. Pointer check can never be null here. Jeremy --- source3/smbd/trans2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 561c18a29d..cb76deb90a 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4806,7 +4806,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, /* We know this name is ok, it's already passed the checks. */ - } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) { + } else if(fsp->is_directory || fsp->fh->fd == -1) { /* * This is actually a QFILEINFO on a directory * handle (returned from an NT SMB). NT5.0 seems -- cgit From 3036a9c7c12d382b925a1f0e2d6265a3817bd3c4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 21:36:55 -0700 Subject: Fix Coverity CID 929. Potential NULL deref after code refactoring. Jeremy. --- source3/smbd/trans2.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index cb76deb90a..7a0feea291 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4649,6 +4649,11 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, uint32 lock_pid; enum brl_type lock_type; + /* We need an open file with a real fd for this. */ + if (!fsp || fsp->is_directory || fsp->fh->fd == -1) { + return NT_STATUS_INVALID_LEVEL; + } + if (lock_data_count != POSIX_LOCK_DATA_SIZE) { return NT_STATUS_INVALID_PARAMETER; } -- cgit From 0bd13fda76d8cb4f345411b847d5be233e12bcc0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 21:40:23 -0700 Subject: Fix Coverity CID 928. Removed check as this can never be null. Jeremy. --- source3/smbd/trans2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 7a0feea291..122114c24f 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4088,7 +4088,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, file_size = get_file_size_stat(&sbuf); } - if (fsp && fsp->fh) { + if (fsp) { pos = fsp->fh->position_information; } -- cgit From 0259a303f4cd69b2db0b059335421f8d0dbc74f5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 2009 21:50:33 -0700 Subject: Fix Coverity CIDs 887, 888. Don't pass NULL's to functions that deref them. Jeremy. --- source3/passdb/pdb_wbc_sam.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3') diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c index 2161d2ff5c..df80411a7a 100644 --- a/source3/passdb/pdb_wbc_sam.c +++ b/source3/passdb/pdb_wbc_sam.c @@ -316,13 +316,12 @@ static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map const char *name) { NTSTATUS result = NT_STATUS_OK; - char *user_name = NULL; - char *domain = NULL; + const char *domain = ""; DOM_SID sid; gid_t gid; enum lsa_SidType name_type; - if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) { + if (!winbind_lookup_name(domain, name, &sid, &name_type)) { result = NT_STATUS_NO_SUCH_GROUP; goto done; } @@ -340,7 +339,7 @@ static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map goto done; } - if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) { + if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { result = NT_STATUS_NO_SUCH_GROUP; goto done; } -- cgit From ce378e7c51913c1b110e62dc35c205d8d2fad58a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 19 Jul 2009 02:32:44 +0200 Subject: Fix a few type errors in VFS modules --- source3/modules/vfs_cap.c | 10 +++++++--- source3/modules/vfs_catia.c | 3 ++- source3/modules/vfs_default.c | 5 +++-- source3/modules/vfs_dirsort.c | 3 ++- source3/modules/vfs_full_audit.c | 4 ++-- source3/modules/vfs_shadow_copy2.c | 3 ++- 6 files changed, 18 insertions(+), 10 deletions(-) (limited to 'source3') diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index 7e363b6be7..aa77da7cd7 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -53,7 +53,9 @@ static SMB_STRUCT_DIR *cap_opendir(vfs_handle_struct *handle, const char *fname, return SMB_VFS_NEXT_OPENDIR(handle, capname, mask, attr); } -static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, + SMB_STRUCT_DIR *dirp, + SMB_STRUCT_STAT *sbuf) { SMB_STRUCT_DIRENT *result; SMB_STRUCT_DIRENT *newdirent; @@ -334,7 +336,8 @@ static int cap_ntimes(vfs_handle_struct *handle, } -static bool cap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath) +static int cap_symlink(vfs_handle_struct *handle, const char *oldpath, + const char *newpath) { char *capold = capencode(talloc_tos(), oldpath); char *capnew = capencode(talloc_tos(), newpath); @@ -346,7 +349,8 @@ static bool cap_symlink(vfs_handle_struct *handle, const char *oldpath, const ch return SMB_VFS_NEXT_SYMLINK(handle, capold, capnew); } -static bool cap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz) +static int cap_readlink(vfs_handle_struct *handle, const char *path, + char *buf, size_t bufsiz) { char *cappath = capencode(talloc_tos(), path); diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index 1fd101282c..3b691c0350 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -103,7 +103,8 @@ static SMB_STRUCT_DIR *catia_opendir(vfs_handle_struct *handle, } static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle, - SMB_STRUCT_DIR *dirp) + SMB_STRUCT_DIR *dirp, + SMB_STRUCT_STAT *sbuf) { SMB_STRUCT_DIRENT *result = NULL; SMB_STRUCT_DIRENT *newdirent = NULL; diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index c4db8fa393..bb7853b926 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1102,7 +1102,8 @@ static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle, return NT_STATUS_OK; } -static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flags) +static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, + unsigned int flags) { #ifdef HAVE_CHFLAGS return chflags(path, flags); @@ -1113,7 +1114,7 @@ static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flag } static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle, - SMB_STRUCT_STAT *sbuf) + const SMB_STRUCT_STAT *sbuf) { struct file_id key; diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c index 53d1820c11..f6fc9256d0 100644 --- a/source3/modules/vfs_dirsort.c +++ b/source3/modules/vfs_dirsort.c @@ -113,7 +113,8 @@ static SMB_STRUCT_DIR *dirsort_opendir(vfs_handle_struct *handle, } static SMB_STRUCT_DIRENT *dirsort_readdir(vfs_handle_struct *handle, - SMB_STRUCT_DIR *dirp) + SMB_STRUCT_DIR *dirp, + SMB_STRUCT_STAT *sbuf) { struct dirsort_privates *data = NULL; time_t current_mtime; diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index e8702aa2c8..bf53ae269c 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -561,7 +561,7 @@ static int smb_full_audit_statvfs(struct vfs_handle_struct *handle, return result; } -static int smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle) +static uint32_t smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle) { int result; @@ -897,7 +897,7 @@ static int smb_full_audit_lstat(vfs_handle_struct *handle, return result; } -static int smb_full_audit_get_alloc_size(vfs_handle_struct *handle, +static uint64_t smb_full_audit_get_alloc_size(vfs_handle_struct *handle, files_struct *fsp, const SMB_STRUCT_STAT *sbuf) { int result; diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 1f300a055c..29247ac7c2 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -549,7 +549,8 @@ static int shadow_copy2_rmdir(vfs_handle_struct *handle, const char *fname) SHADOW2_NEXT(RMDIR, (handle, name), int, -1); } -static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname, int flags) +static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname, + unsigned int flags) { SHADOW2_NEXT(CHFLAGS, (handle, name, flags), int, -1); } -- cgit From 93570491712bf42b5c8dba825e7d2a40e71c0378 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 20 Jul 2009 15:15:08 -0700 Subject: Make cli_send_mailslot() static. Preparing to do away with unexpected.tdb.... Jeremy. --- source3/include/proto.h | 7 ------- source3/libsmb/clidgram.c | 3 +-- 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index d68aa4b619..695e14b53c 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2270,13 +2270,6 @@ bool cli_resolve_path(TALLOC_CTX *ctx, /* The following definitions come from libsmb/clidgram.c */ -bool cli_send_mailslot(struct messaging_context *msg_ctx, - bool unique, const char *mailslot, - uint16 priority, - char *buf, int len, - const char *srcname, int src_type, - const char *dstname, int dest_type, - const struct sockaddr_storage *dest_ss); bool send_getdc_request(TALLOC_CTX *mem_ctx, struct messaging_context *msg_ctx, struct sockaddr_storage *dc_ss, diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 349a8331b4..f5dbd72f22 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -25,7 +25,7 @@ * cli_send_mailslot, send a mailslot for client code ... */ -bool cli_send_mailslot(struct messaging_context *msg_ctx, +static bool cli_send_mailslot(struct messaging_context *msg_ctx, bool unique, const char *mailslot, uint16 priority, char *buf, int len, @@ -309,4 +309,3 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, return True; } - -- cgit From 12a5db45e2814b6992210d8f30908ab3e8b6bc65 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 10:38:56 -0700 Subject: s3: Change file_structs to be allocated with talloc instead of malloc --- source3/smbd/files.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'source3') diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 0e6dd7e457..48d2288468 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -65,21 +65,26 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn, return NT_STATUS_TOO_MANY_OPENED_FILES; } - fsp = SMB_MALLOC_P(files_struct); + /* + * Make a child of the connection_struct as an fsp can't exist + * indepenedent of a connection. + */ + fsp = talloc_zero(conn, struct files_struct); if (!fsp) { return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(fsp); - - fsp->fh = SMB_MALLOC_P(struct fd_handle); + /* + * This can't be a child of fsp because the file_handle can be ref'd + * when doing a dos/fcb open, which will then share the file_handle + * across multiple fsps. + */ + fsp->fh = talloc_zero(conn, struct fd_handle); if (!fsp->fh) { - SAFE_FREE(fsp); + TALLOC_FREE(fsp); return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(fsp->fh); - fsp->fh->ref_count = 1; fsp->fh->fd = -1; @@ -449,7 +454,7 @@ void file_free(struct smb_request *req, files_struct *fsp) TALLOC_FREE(fsp->fake_file_handle); if (fsp->fh->ref_count == 1) { - SAFE_FREE(fsp->fh); + TALLOC_FREE(fsp->fh); } else { fsp->fh->ref_count--; } @@ -495,7 +500,7 @@ void file_free(struct smb_request *req, files_struct *fsp) information */ ZERO_STRUCTP(fsp); - SAFE_FREE(fsp); + TALLOC_FREE(fsp); } /**************************************************************************** @@ -545,7 +550,7 @@ void dup_file_fsp(struct smb_request *req, files_struct *from, uint32 access_mask, uint32 share_access, uint32 create_options, files_struct *to) { - SAFE_FREE(to->fh); + TALLOC_FREE(to->fh); to->fh = from->fh; to->fh->ref_count++; -- cgit From 635e5e7ff038378d28c52bd5f81d24db99a77a76 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 11:50:30 -0700 Subject: s3 onefs oplocks: Replace static fstring with talloc'd dbg_ctx() --- source3/smbd/oplock_onefs.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'source3') diff --git a/source3/smbd/oplock_onefs.c b/source3/smbd/oplock_onefs.c index d359f9c6f2..497cfc7b54 100644 --- a/source3/smbd/oplock_onefs.c +++ b/source3/smbd/oplock_onefs.c @@ -60,29 +60,29 @@ struct onefs_callback_record { struct onefs_callback_record *callback_recs; /** - * Convert a onefs_callback_record to a string. + * Convert a onefs_callback_record to a debug string using the dbg_ctx(). */ -static char *onefs_callback_record_str_static(const struct onefs_callback_record *r) +const char *onefs_cb_record_str_dbg(const struct onefs_callback_record *r) { - static fstring result; + char *result; if (r == NULL) { - fstrcpy(result, "NULL callback record"); + result = talloc_strdup(dbg_ctx(), "NULL callback record"); return result; } switch (r->state) { case ONEFS_OPEN_FILE: - fstr_sprintf(result, "cb record %llu for file %s", - r->id, r->data.fsp->fsp_name); - break; + result = talloc_asprintf(dbg_ctx(), "cb record %llu for file " + "%s", r->id, r->data.fsp->fsp_name); case ONEFS_WAITING_FOR_OPLOCK: - fstr_sprintf(result, "cb record %llu for pending mid %d", - r->id, (int)r->data.mid); + result = talloc_asprintf(dbg_ctx(), "cb record %llu for " + "pending mid %d", r->id, + (int)r->data.mid); break; default: - fstr_sprintf(result, "cb record %llu unknown state %d", - r->id, r->state); + result = talloc_asprintf(dbg_ctx(), "cb record %llu unknown " + "state %d", r->id, r->state); break; } @@ -102,7 +102,7 @@ static void debug_cb_records(const char *fn) DEBUG(10, ("cb records (%s):\n", fn)); for (rec = callback_recs; rec; rec = rec->next) { - DEBUGADD(10, ("%s\n", onefs_callback_record_str_static(rec))); + DEBUGADD(10, ("%s\n", onefs_cb_record_dbg_str(rec))); } } @@ -127,7 +127,7 @@ static struct onefs_callback_record *onefs_find_cb(uint64_t id, for (rec = callback_recs; rec; rec = rec->next) { if (rec->id == id) { DEBUG(10, ("found %s\n", - onefs_callback_record_str_static(rec))); + onefs_cb_record_dbg_str(rec))); break; } } @@ -139,7 +139,7 @@ static struct onefs_callback_record *onefs_find_cb(uint64_t id, if (rec->state != expected_state) { DEBUG(0, ("Expected cb type %d, got %s", expected_state, - onefs_callback_record_str_static(rec))); + onefs_cb_record_dbg_str(rec))); SMB_ASSERT(0); return NULL; } @@ -413,7 +413,7 @@ static void semlock_available_handler(uint64_t id) char *msg; if (asprintf(&msg, "Semlock available on an open that wasn't " "deferred: %s\n", - onefs_callback_record_str_static(cb)) != -1) { + onefs_cb_record_dbg_str(cb)) != -1) { smb_panic(msg); } smb_panic("Semlock available on an open that wasn't " @@ -457,7 +457,7 @@ static void semlock_async_failure_handler(uint64_t id) char *msg; if (asprintf(&msg, "Semlock failure on an open that wasn't " "deferred: %s\n", - onefs_callback_record_str_static(cb)) != -1) { + onefs_cb_record_dbg_str(cb)) != -1) { smb_panic(msg); } smb_panic("Semlock failure on an open that wasn't deferred\n"); -- cgit From 5a8d70d465f28ae02f4df7a3c2905e028c2e3142 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 14:50:37 -0700 Subject: s3: Change fsp->fsp_name to be an smb_filename struct! --- source3/include/proto.h | 5 +- source3/include/smb.h | 2 +- source3/locking/brlock.c | 4 +- source3/locking/locking.c | 29 +++--- source3/locking/posix.c | 37 ++++--- source3/smbd/aio.c | 28 ++--- source3/smbd/blocking.c | 15 +-- source3/smbd/close.c | 163 +++++++++++++---------------- source3/smbd/dosmode.c | 2 +- source3/smbd/fileio.c | 57 +++++----- source3/smbd/files.c | 73 ++++++++++--- source3/smbd/ipc.c | 2 +- source3/smbd/notify.c | 7 +- source3/smbd/nttrans.c | 20 ++-- source3/smbd/open.c | 74 +++++++------ source3/smbd/oplock.c | 24 +++-- source3/smbd/oplock_irix.c | 13 ++- source3/smbd/oplock_linux.c | 9 +- source3/smbd/oplock_onefs.c | 11 +- source3/smbd/pipes.c | 19 +++- source3/smbd/posix_acls.c | 247 ++++++++++++++++++++------------------------ source3/smbd/reply.c | 139 ++++++++++--------------- source3/smbd/smb2_close.c | 2 +- source3/smbd/smb2_create.c | 19 ++-- source3/smbd/smb2_flush.c | 2 +- source3/smbd/smb2_getinfo.c | 29 ++---- source3/smbd/smb2_notify.c | 2 +- source3/smbd/smb2_read.c | 4 +- source3/smbd/smb2_setinfo.c | 25 ++--- source3/smbd/smb2_write.c | 6 +- source3/smbd/trans2.c | 70 ++++++------- source3/smbd/vfs.c | 36 ++++--- 32 files changed, 585 insertions(+), 590 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 695e14b53c..830d2284c4 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6365,9 +6365,12 @@ void file_sync_all(connection_struct *conn); void file_free(struct smb_request *req, files_struct *fsp); files_struct *file_fnum(uint16 fnum); files_struct *file_fsp(struct smb_request *req, uint16 fid); -void dup_file_fsp(struct smb_request *req, files_struct *from, +NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from, uint32 access_mask, uint32 share_access, uint32 create_options, files_struct *to); +const char *fsp_str_dbg(const struct files_struct *fsp); +NTSTATUS fsp_set_smb_fname(struct files_struct *fsp, + const struct smb_filename *smb_fname_in); /* The following definitions come from smbd/ipc.c */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 2e9cf1b54a..94ed2186fb 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -452,7 +452,7 @@ typedef struct files_struct { bool lockdb_clean; bool initial_delete_on_close; /* Only set at NTCreateX if file was created. */ bool posix_open; - char *fsp_name; + struct smb_filename *fsp_name; struct vfs_fsp_data *vfs_extension; struct fake_file_handle *fake_file_handle; diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index be2948c531..e238ec959b 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1196,7 +1196,7 @@ bool brl_locktest(struct byte_range_lock *br_lck, DEBUG(10,("brl_locktest: posix start=%.0f len=%.0f %s for fnum %d file %s\n", (double)start, (double)size, ret ? "locked" : "unlocked", - fsp->fnum, fsp->fsp_name )); + fsp->fnum, fsp_str_dbg(fsp))); /* We need to return the inverse of is_posix_locked. */ ret = !ret; @@ -1262,7 +1262,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, DEBUG(10,("brl_lockquery: posix start=%.0f len=%.0f %s for fnum %d file %s\n", (double)*pstart, (double)*psize, ret ? "locked" : "unlocked", - fsp->fnum, fsp->fsp_name )); + fsp->fnum, fsp_str_dbg(fsp))); if (ret) { /* Hmmm. No clue what to set smbpid to - use -1. */ diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 91fe137fdc..fba871c704 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -109,11 +109,11 @@ bool strict_lock_default(files_struct *fsp, struct lock_struct *plock) if (strict_locking == Auto) { if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) { - DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name )); + DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp))); ret = True; } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) && (plock->lock_type == READ_LOCK)) { - DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); + DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp))); ret = True; } else { struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp); @@ -149,7 +149,7 @@ bool strict_lock_default(files_struct *fsp, struct lock_struct *plock) lock_flav_name(plock->lock_flav), (double)plock->start, (double)plock->size, ret ? "unlocked" : "locked", - plock->fnum, fsp->fsp_name )); + plock->fnum, fsp_str_dbg(fsp))); return ret; } @@ -259,7 +259,7 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, "blocking_lock=%s requested for fnum %d file %s\n", lock_flav_name(lock_flav), lock_type_name(lock_type), (double)offset, (double)count, blocking_lock ? "true" : - "false", fsp->fnum, fsp->fsp_name)); + "false", fsp->fnum, fsp_str_dbg(fsp))); br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { @@ -308,7 +308,8 @@ NTSTATUS do_unlock(struct messaging_context *msg_ctx, } DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n", - (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); + (double)offset, (double)count, fsp->fnum, + fsp_str_dbg(fsp))); br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { @@ -358,7 +359,8 @@ NTSTATUS do_lock_cancel(files_struct *fsp, } DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n", - (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); + (double)offset, (double)count, fsp->fnum, + fsp_str_dbg(fsp))); br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { @@ -1311,7 +1313,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close, !lp_delete_readonly(SNUM(fsp->conn))) { DEBUG(10,("can_set_delete_on_close: file %s delete on close " "flag set but file attribute is readonly.\n", - fsp->fsp_name )); + fsp_str_dbg(fsp))); return NT_STATUS_CANNOT_DELETE; } @@ -1322,7 +1324,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close, if (!CAN_WRITE(fsp->conn)) { DEBUG(10,("can_set_delete_on_close: file %s delete on " "close flag set but write access denied on share.\n", - fsp->fsp_name )); + fsp_str_dbg(fsp))); return NT_STATUS_ACCESS_DENIED; } @@ -1334,13 +1336,15 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close, if (!(fsp->access_mask & DELETE_ACCESS)) { DEBUG(10,("can_set_delete_on_close: file %s delete on " "close flag set but delete access denied.\n", - fsp->fsp_name )); + fsp_str_dbg(fsp))); return NT_STATUS_ACCESS_DENIED; } /* Don't allow delete on close for non-empty directories. */ if (fsp->is_directory) { - return can_delete_directory(fsp->conn, fsp->fsp_name); + SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name)); + return can_delete_directory(fsp->conn, + fsp->fsp_name->base_name); } return NT_STATUS_OK; @@ -1422,7 +1426,7 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USE DEBUG(10,("set_delete_on_close: %s delete on close flag for " "fnum = %d, file %s\n", delete_on_close ? "Adding" : "Removing", fsp->fnum, - fsp->fsp_name )); + fsp_str_dbg(fsp))); lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, NULL); @@ -1443,7 +1447,8 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USE set_delete_on_close_lck(lck, delete_on_close, tok); if (fsp->is_directory) { - send_stat_cache_delete_message(fsp->fsp_name); + SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name)); + send_stat_cache_delete_message(fsp->fsp_name->base_name); } TALLOC_FREE(lck); diff --git a/source3/locking/posix.c b/source3/locking/posix.c index 9b51c3aa6a..33ffaf95ca 100644 --- a/source3/locking/posix.c +++ b/source3/locking/posix.c @@ -280,8 +280,9 @@ bool is_posix_locked(files_struct *fsp, SMB_OFF_T count; int posix_lock_type = map_posix_lock_type(fsp,*plock_type); - DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, type = %s\n", - fsp->fsp_name, (double)*pu_offset, (double)*pu_count, posix_lock_type_name(*plock_type) )); + DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, " + "type = %s\n", fsp_str_dbg(fsp), (double)*pu_offset, + (double)*pu_count, posix_lock_type_name(*plock_type))); /* * If the requested lock won't fit in the POSIX range, we will @@ -424,7 +425,7 @@ static void increment_windows_lock_ref_count(files_struct *fsp) TALLOC_FREE(rec); DEBUG(10,("increment_windows_lock_ref_count for file now %s = %d\n", - fsp->fsp_name, lock_ref_count )); + fsp_str_dbg(fsp), lock_ref_count)); } /**************************************************************************** @@ -460,7 +461,7 @@ void reduce_windows_lock_ref_count(files_struct *fsp, unsigned int dcount) TALLOC_FREE(rec); DEBUG(10,("reduce_windows_lock_ref_count for file now %s = %d\n", - fsp->fsp_name, lock_ref_count )); + fsp_str_dbg(fsp), lock_ref_count)); } static void decrement_windows_lock_ref_count(files_struct *fsp) @@ -492,7 +493,7 @@ static int get_windows_lock_ref_count(files_struct *fsp) } DEBUG(10,("get_windows_lock_count for file %s = %d\n", - fsp->fsp_name, lock_ref_count )); + fsp_str_dbg(fsp), lock_ref_count)); return lock_ref_count; } @@ -518,7 +519,7 @@ static void delete_windows_lock_ref_count(files_struct *fsp) TALLOC_FREE(rec); DEBUG(10,("delete_windows_lock_ref_count for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); } /**************************************************************************** @@ -555,7 +556,7 @@ static void add_fd_to_close_entry(files_struct *fsp) TALLOC_FREE(rec); DEBUG(10,("add_fd_to_close_entry: added fd %d file %s\n", - fsp->fh->fd, fsp->fsp_name )); + fsp->fh->fd, fsp_str_dbg(fsp))); } /**************************************************************************** @@ -945,8 +946,10 @@ bool set_posix_lock_windows_flavour(files_struct *fsp, struct lock_list *llist = NULL; struct lock_list *ll = NULL; - DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n", - fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) )); + DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, " + "count = %.0f, type = %s\n", fsp_str_dbg(fsp), + (double)u_offset, (double)u_count, + posix_lock_type_name(lock_type))); /* * If the requested lock won't fit in the POSIX range, we will @@ -1079,8 +1082,9 @@ bool release_posix_lock_windows_flavour(files_struct *fsp, struct lock_list *ulist = NULL; struct lock_list *ul = NULL; - DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f\n", - fsp->fsp_name, (double)u_offset, (double)u_count )); + DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, " + "count = %.0f\n", fsp_str_dbg(fsp), + (double)u_offset, (double)u_count)); /* Remember the number of Windows locks we have on this dev/ino pair. */ decrement_windows_lock_ref_count(fsp); @@ -1197,8 +1201,10 @@ bool set_posix_lock_posix_flavour(files_struct *fsp, SMB_OFF_T count; int posix_lock_type = map_posix_lock_type(fsp,lock_type); - DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n", - fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) )); + DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count " + "= %.0f, type = %s\n", fsp_str_dbg(fsp), + (double)u_offset, (double)u_count, + posix_lock_type_name(lock_type))); /* * If the requested lock won't fit in the POSIX range, we will @@ -1241,8 +1247,9 @@ bool release_posix_lock_posix_flavour(files_struct *fsp, struct lock_list *ulist = NULL; struct lock_list *ul = NULL; - DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f\n", - fsp->fsp_name, (double)u_offset, (double)u_count )); + DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, " + "count = %.0f\n", fsp_str_dbg(fsp), + (double)u_offset, (double)u_count)); /* * If the requested lock won't fit in the POSIX range, we will diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index c6f700f17a..ed415c5e13 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -188,7 +188,7 @@ bool schedule_aio_read_and_X(connection_struct *conn, DEBUG(10,("schedule_aio_read_and_X: scheduled aio_read for file %s, " "offset %.0f, len = %u (mid = %u)\n", - fsp->fsp_name, (double)startpos, (unsigned int)smb_maxcnt, + fsp_str_dbg(fsp), (double)startpos, (unsigned int)smb_maxcnt, (unsigned int)aio_ex->req->mid )); outstanding_aio_calls++; @@ -241,7 +241,7 @@ bool schedule_aio_write_and_X(connection_struct *conn, DEBUG(10,("schedule_aio_write_and_X: failed to schedule " "aio_write for file %s, offset %.0f, len = %u " "(mid = %u)\n", - fsp->fsp_name, (double)startpos, + fsp_str_dbg(fsp), (double)startpos, (unsigned int)numtowrite, (unsigned int)req->mid )); return False; @@ -300,14 +300,14 @@ bool schedule_aio_write_and_X(connection_struct *conn, "failed."); } DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write " - "behind for file %s\n", fsp->fsp_name )); + "behind for file %s\n", fsp_str_dbg(fsp))); } outstanding_aio_calls++; DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write for file " "%s, offset %.0f, len = %u (mid = %u) " "outstanding_aio_calls = %d\n", - fsp->fsp_name, (double)startpos, (unsigned int)numtowrite, + fsp_str_dbg(fsp), (double)startpos, (unsigned int)numtowrite, (unsigned int)aio_ex->req->mid, outstanding_aio_calls )); return True; @@ -341,7 +341,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex) DEBUG( 3,( "handle_aio_read_complete: file %s nread == -1. " "Error = %s\n", - aio_ex->fsp->fsp_name, strerror(errno) )); + fsp_str_dbg(aio_ex->fsp), strerror(errno))); ret = errno; ERROR_NT(map_nt_error_from_unix(ret)); @@ -359,7 +359,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex) DEBUG( 3, ( "handle_aio_read_complete file %s max=%d " "nread=%d\n", - aio_ex->fsp->fsp_name, + fsp_str_dbg(aio_ex->fsp), (int)aio_ex->acb.aio_nbytes, (int)nread ) ); } @@ -374,7 +374,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex) DEBUG(10,("handle_aio_read_complete: scheduled aio_read completed " "for file %s, offset %.0f, len = %u\n", - aio_ex->fsp->fsp_name, (double)aio_ex->acb.aio_offset, + fsp_str_dbg(aio_ex->fsp), (double)aio_ex->acb.aio_offset, (unsigned int)nread )); return ret; @@ -399,13 +399,13 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) DEBUG(5,("handle_aio_write_complete: " "aio_write_behind failed ! File %s " "is corrupt ! Error %s\n", - fsp->fsp_name, strerror(errno) )); + fsp_str_dbg(fsp), strerror(errno))); ret = errno; } else { DEBUG(0,("handle_aio_write_complete: " "aio_write_behind failed ! File %s " "is corrupt ! Wanted %u bytes but " - "only wrote %d\n", fsp->fsp_name, + "only wrote %d\n", fsp_str_dbg(fsp), (unsigned int)numtowrite, (int)nwritten )); ret = EIO; @@ -413,7 +413,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) } else { DEBUG(10,("handle_aio_write_complete: " "aio_write_behind completed for file %s\n", - fsp->fsp_name )); + fsp_str_dbg(fsp))); } return 0; } @@ -424,7 +424,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) if(nwritten == -1) { DEBUG( 3,( "handle_aio_write: file %s wanted %u bytes. " "nwritten == %d. Error = %s\n", - fsp->fsp_name, (unsigned int)numtowrite, + fsp_str_dbg(fsp), (unsigned int)numtowrite, (int)nwritten, strerror(errno) )); /* If errno is ECANCELED then don't return anything to the @@ -456,7 +456,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) ERRHRD, ERRdiskfull); srv_set_message(outbuf,0,0,true); DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); } aio_ex->fsp->fh->pos = aio_ex->acb.aio_offset + nwritten; @@ -472,7 +472,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) DEBUG(10,("handle_aio_write_complete: scheduled aio_write completed " "for file %s, offset %.0f, requested %u, written = %u\n", - fsp->fsp_name, (double)aio_ex->acb.aio_offset, + fsp_str_dbg(fsp), (double)aio_ex->acb.aio_offset, (unsigned int)numtowrite, (unsigned int)nwritten )); return ret; @@ -496,7 +496,7 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr) if (SMB_VFS_AIO_ERROR(aio_ex->fsp, &aio_ex->acb) == EINPROGRESS) { DEBUG(10,( "handle_aio_completed: operation mid %u still in " "process for file %s\n", - aio_ex->req->mid, aio_ex->fsp->fsp_name )); + aio_ex->req->mid, fsp_str_dbg(aio_ex->fsp))); return False; } diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 4c61428692..e752194ca5 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -202,7 +202,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, "expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n", (unsigned int)blr->expire_time.tv_sec, (unsigned int)blr->expire_time.tv_usec, lock_timeout, - blr->fsp->fnum, blr->fsp->fsp_name )); + blr->fsp->fnum, fsp_str_dbg(blr->fsp))); return True; } @@ -418,8 +418,9 @@ static bool process_lockingX(struct blocking_lock_record *blr) * Success - we got all the locks. */ - DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d num_locks=%d\n", - fsp->fsp_name, fsp->fnum, (unsigned int)locktype, num_locks) ); + DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d " + "num_locks=%d\n", fsp_str_dbg(fsp), fsp->fnum, + (unsigned int)locktype, num_locks)); reply_lockingX_success(blr); return True; @@ -442,7 +443,7 @@ static bool process_lockingX(struct blocking_lock_record *blr) DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \ Waiting....\n", - blr->lock_num, num_locks, fsp->fsp_name, fsp->fnum)); + blr->lock_num, num_locks, fsp_str_dbg(fsp), fsp->fnum)); return False; } @@ -533,7 +534,7 @@ void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lo DEBUG(10, ("remove_pending_lock_requests_by_fid - removing " "request type %d for file %s fnum = %d\n", - blr->req->cmd, fsp->fsp_name, fsp->fnum)); + blr->req->cmd, fsp_str_dbg(fsp), fsp->fnum)); blr_cancelled = blocking_lock_cancel(fsp, blr->lock_pid, @@ -583,7 +584,7 @@ void remove_pending_lock_requests_by_mid(int mid) if (br_lck) { DEBUG(10, ("remove_pending_lock_requests_by_mid - " "removing request type %d for file %s fnum " - "= %d\n", blr->req->cmd, fsp->fsp_name, + "= %d\n", blr->req->cmd, fsp_str_dbg(fsp), fsp->fnum )); brl_lock_cancel(br_lck, @@ -703,7 +704,7 @@ void process_blocking_lock_queue(void) DEBUG(5,("process_blocking_lock_queue: " "pending lock fnum = %d for file %s " "timed out.\n", blr->fsp->fnum, - blr->fsp->fsp_name )); + fsp_str_dbg(blr->fsp))); brl_lock_cancel(br_lck, blr->lock_pid, diff --git a/source3/smbd/close.c b/source3/smbd/close.c index a0672f3949..f878aaa056 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -36,90 +36,102 @@ static NTSTATUS check_magic(struct files_struct *fsp) TALLOC_CTX *ctx = NULL; const char *p; struct connection_struct *conn = fsp->conn; + char *fname = NULL; + NTSTATUS status; if (!*lp_magicscript(SNUM(conn))) { return NT_STATUS_OK; } - DEBUG(5,("checking magic for %s\n",fsp->fsp_name)); + DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp))); + + ctx = talloc_stackframe(); + + status = get_full_smb_filename(ctx, fsp->fsp_name, &fname); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } - if (!(p = strrchr_m(fsp->fsp_name,'/'))) { - p = fsp->fsp_name; + if (!(p = strrchr_m(fname,'/'))) { + p = fname; } else { p++; } if (!strequal(lp_magicscript(SNUM(conn)),p)) { - return NT_STATUS_OK; + status = NT_STATUS_OK; + goto out; } - ctx = talloc_stackframe(); - if (*lp_magicoutput(SNUM(conn))) { magic_output = lp_magicoutput(SNUM(conn)); } else { magic_output = talloc_asprintf(ctx, "%s.out", - fsp->fsp_name); + fname); } if (!magic_output) { - TALLOC_FREE(ctx); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto out; } /* Ensure we don't depend on user's PATH. */ - p = talloc_asprintf(ctx, "./%s", fsp->fsp_name); + p = talloc_asprintf(ctx, "./%s", fname); if (!p) { - TALLOC_FREE(ctx); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto out; } - if (chmod(fsp->fsp_name,0755) == -1) { - TALLOC_FREE(ctx); - return map_nt_error_from_unix(errno); + if (chmod(fname, 0755) == -1) { + status = map_nt_error_from_unix(errno); + goto out; } ret = smbrun(p,&tmp_fd); DEBUG(3,("Invoking magic command %s gave %d\n", p,ret)); - unlink(fsp->fsp_name); + unlink(fname); if (ret != 0 || tmp_fd == -1) { if (tmp_fd != -1) { close(tmp_fd); } - TALLOC_FREE(ctx); - return NT_STATUS_UNSUCCESSFUL; + status = NT_STATUS_UNSUCCESSFUL; + goto out; } outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600); if (outfd == -1) { int err = errno; close(tmp_fd); - TALLOC_FREE(ctx); - return map_nt_error_from_unix(err); + status = map_nt_error_from_unix(err); + goto out; } if (sys_fstat(tmp_fd,&st) == -1) { int err = errno; close(tmp_fd); close(outfd); - TALLOC_FREE(ctx); - return map_nt_error_from_unix(err); + status = map_nt_error_from_unix(err); + goto out; } if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) { int err = errno; close(tmp_fd); close(outfd); - TALLOC_FREE(ctx); - return map_nt_error_from_unix(err); + status = map_nt_error_from_unix(err); + goto out; } close(tmp_fd); if (close(outfd) == -1) { - TALLOC_FREE(ctx); - return map_nt_error_from_unix(errno); + status = map_nt_error_from_unix(errno); + goto out; } + + status = NT_STATUS_OK; + + out: TALLOC_FREE(ctx); - return NT_STATUS_OK; + return status; } /**************************************************************************** @@ -261,18 +273,10 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, bool delete_file = false; bool changed_user = false; struct share_mode_lock *lck = NULL; - struct smb_filename *smb_fname = NULL; - char *fname = NULL; NTSTATUS status = NT_STATUS_OK; int ret; struct file_id id; - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - /* * Lock the share entries, and determine if we should delete * on close. If so delete whilst the lock is still in effect. @@ -284,7 +288,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, if (lck == NULL) { DEBUG(0, ("close_remove_share_mode: Could not get share mode " - "lock for file %s\n", smb_fname_str_dbg(smb_fname))); + "lock for file %s\n", fsp_str_dbg(fsp))); status = NT_STATUS_INVALID_PARAMETER; goto done; } @@ -296,7 +300,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, if (!del_share_mode(lck, fsp)) { DEBUG(0, ("close_remove_share_mode: Could not delete share " "entry for file %s\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); } if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) { @@ -354,7 +358,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, */ DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set " - "- deleting file.\n", smb_fname_str_dbg(smb_fname))); + "- deleting file.\n", fsp_str_dbg(fsp))); /* * Don't try to update the write time when we delete the file @@ -366,7 +370,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, DEBUG(5,("close_remove_share_mode: file %s. " "Change user to uid %u\n", - smb_fname_str_dbg(smb_fname), + fsp_str_dbg(fsp), (unsigned int)lck->delete_token->uid)); if (!push_sec_ctx()) { @@ -387,30 +391,30 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, hasn't been renamed. */ if (fsp->posix_open) { - ret = SMB_VFS_LSTAT(conn, smb_fname); + ret = SMB_VFS_LSTAT(conn, fsp->fsp_name); } else { - ret = SMB_VFS_STAT(conn, smb_fname); + ret = SMB_VFS_STAT(conn, fsp->fsp_name); } if (ret != 0) { DEBUG(5,("close_remove_share_mode: file %s. Delete on close " "was set and stat failed with error %s\n", - smb_fname_str_dbg(smb_fname), strerror(errno))); + fsp_str_dbg(fsp), strerror(errno))); /* * Don't save the errno here, we ignore this error */ goto done; } - id = vfs_file_id_from_sbuf(conn, &smb_fname->st); + id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st); if (!file_id_equal(&fsp->file_id, &id)) { DEBUG(5,("close_remove_share_mode: file %s. Delete on close " "was set and dev and/or inode does not match\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, " "stat file_id %s\n", - smb_fname_str_dbg(smb_fname), + fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), file_id_string_tos(&id))); /* @@ -420,9 +424,9 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, } if ((conn->fs_capabilities & FILE_NAMED_STREAMS) - && !is_ntfs_stream_smb_fname(smb_fname)) { + && !is_ntfs_stream_smb_fname(fsp->fsp_name)) { - status = delete_all_streams(conn, smb_fname->base_name); + status = delete_all_streams(conn, fsp->fsp_name->base_name); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("delete_all_streams failed: %s\n", @@ -432,7 +436,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, } - if (SMB_VFS_UNLINK(conn, smb_fname) != 0) { + if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) { /* * This call can potentially fail as another smbd may * have had the file open with delete on close set and @@ -443,21 +447,14 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, DEBUG(5,("close_remove_share_mode: file %s. Delete on close " "was set and unlink failed with error %s\n", - smb_fname_str_dbg(smb_fname), strerror(errno))); + fsp_str_dbg(fsp), strerror(errno))); status = map_nt_error_from_unix(errno); } - status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - notify_fname(conn, NOTIFY_ACTION_REMOVED, FILE_NOTIFY_CHANGE_FILE_NAME, - fname); - - TALLOC_FREE(fname); + fsp->fsp_name->base_name); /* As we now have POSIX opens which can unlink * with other open files we may have taken @@ -476,7 +473,6 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, } TALLOC_FREE(lck); - TALLOC_FREE(smb_fname); return status; } @@ -499,7 +495,6 @@ void set_close_write_time(struct files_struct *fsp, struct timespec ts) static NTSTATUS update_write_time_on_close(struct files_struct *fsp) { - struct smb_filename *smb_fname = NULL; struct smb_file_time ft; NTSTATUS status; int ret = -1; @@ -514,43 +509,32 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp) fsp->close_write_time = timespec_current(); } - /* XXX: Remove when fsp->fsp_name is converted to smb_filename. */ - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - /* Ensure we have a valid stat struct for the source. */ if (fsp->fh->fd != -1) { - ret = SMB_VFS_FSTAT(fsp, &smb_fname->st); + ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); } else { if (fsp->posix_open) { - ret = SMB_VFS_LSTAT(fsp->conn, smb_fname); + ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name); } else { - ret = SMB_VFS_STAT(fsp->conn, smb_fname); + ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); } } if (ret == -1) { - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } - if (!VALID_STAT(smb_fname->st)) { + if (!VALID_STAT(fsp->fsp_name->st)) { /* if it doesn't seem to be a real file */ - status = NT_STATUS_OK; - goto out; + return NT_STATUS_OK; } ft.mtime = fsp->close_write_time; - status = smb_set_file_time(fsp->conn, fsp, smb_fname, &ft, true); + status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, true); if (!NT_STATUS_IS_OK(status)) { - goto out; + return status; } - out: - TALLOC_FREE(smb_fname); return status; } @@ -647,7 +631,7 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, status = ntstatus_keeperror(status, tmp); DEBUG(2,("%s closed file %s (numopen=%d) %s\n", - conn->server_info->unix_name,fsp->fsp_name, + conn->server_info->unix_name, fsp_str_dbg(fsp), conn->num_files_open - 1, nt_errstr(status) )); @@ -663,16 +647,9 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, enum file_close_type close_type) { struct share_mode_lock *lck = NULL; - struct smb_filename *smb_dname = NULL; bool delete_dir = False; NTSTATUS status = NT_STATUS_OK; - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - NULL, &smb_dname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - /* * NT can set delete_on_close of the last open * reference to a directory also. @@ -683,14 +660,14 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, if (lck == NULL) { DEBUG(0, ("close_directory: Could not get share mode lock for " - "%s\n", smb_fname_str_dbg(smb_dname))); + "%s\n", fsp_str_dbg(fsp))); status = NT_STATUS_INVALID_PARAMETER; goto out; } if (!del_share_mode(lck, fsp)) { DEBUG(0, ("close_directory: Could not delete share entry for " - "%s\n", smb_fname_str_dbg(smb_dname))); + "%s\n", fsp_str_dbg(fsp))); } if (fsp->initial_delete_on_close) { @@ -704,7 +681,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, become_user(fsp->conn, fsp->vuid); became_user = True; } - send_stat_cache_delete_message(fsp->fsp_name); + send_stat_cache_delete_message(fsp->fsp_name->base_name); set_delete_on_close_lck(lck, True, ¤t_user.ut); if (became_user) { unbecome_user(); @@ -747,11 +724,12 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, TALLOC_FREE(lck); - status = rmdir_internals(talloc_tos(), fsp->conn, smb_dname); + status = rmdir_internals(talloc_tos(), fsp->conn, + fsp->fsp_name); DEBUG(5,("close_directory: %s. Delete on close was set - " "deleting directory returned %s.\n", - smb_fname_str_dbg(smb_dname), nt_errstr(status))); + fsp_str_dbg(fsp), nt_errstr(status))); /* unbecome user. */ pop_sec_ctx(); @@ -774,7 +752,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n", - smb_fname_str_dbg(smb_dname), fsp->fh->fd, errno, + fsp_str_dbg(fsp), fsp->fh->fd, errno, strerror(errno))); } @@ -786,7 +764,6 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, out: TALLOC_FREE(lck); - TALLOC_FREE(smb_dname); return status; } diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index d3df80ad91..bd0c7df959 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -845,7 +845,7 @@ bool update_write_time(struct files_struct *fsp) } notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name); + FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name->base_name); return true; } diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 60cef09b3b..bd609d3e86 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -103,7 +103,7 @@ tryagain: } DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n", - fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); + fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret)); fsp->fh->pos += ret; fsp->fh->position_information = fsp->fh->pos; @@ -136,7 +136,7 @@ static ssize_t real_write_file(struct smb_request *req, } DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n", - fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); + fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret)); if (ret != -1) { fsp->fh->pos += ret; @@ -164,8 +164,9 @@ static int wcp_file_size_change(files_struct *fsp) wcp->file_size = wcp->offset + wcp->data_size; ret = SMB_VFS_FTRUNCATE(fsp, wcp->file_size); if (ret == -1) { - DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f error %s\n", - fsp->fsp_name, (double)wcp->file_size, strerror(errno) )); + DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f " + "error %s\n", fsp_str_dbg(fsp), + (double)wcp->file_size, strerror(errno))); } return ret; } @@ -179,7 +180,7 @@ static void update_write_time_handler(struct event_context *ctx, /* Remove the timed event handler. */ TALLOC_FREE(fsp->update_write_time_event); - DEBUG(5, ("Update write time on %s\n", fsp->fsp_name)); + DEBUG(5, ("Update write time on %s\n", fsp_str_dbg(fsp))); /* change the write time if not already changed by someone else */ update_write_time(fsp); @@ -244,7 +245,8 @@ void trigger_write_time_update_immediate(struct files_struct *fsp) } TALLOC_FREE(fsp->update_write_time_event); - DEBUG(5, ("Update write time immediate on %s\n", fsp->fsp_name)); + DEBUG(5, ("Update write time immediate on %s\n", + fsp_str_dbg(fsp))); fsp->update_write_time_triggered = true; @@ -285,28 +287,17 @@ ssize_t write_file(struct smb_request *req, } if (!fsp->modified) { - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - fsp->modified = True; - status = create_synthetic_smb_fname_split(talloc_tos(), - fsp->fsp_name, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; - } - - if (SMB_VFS_FSTAT(fsp, &smb_fname->st) == 0) { + if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == 0) { int dosmode; trigger_write_time_update(fsp); - dosmode = dos_mode(fsp->conn, smb_fname); + dosmode = dos_mode(fsp->conn, fsp->fsp_name); if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) { - file_set_dosmode(fsp->conn, smb_fname, - dosmode | aARCH, NULL, false); + file_set_dosmode(fsp->conn, fsp->fsp_name, + dosmode | aARCH, NULL, false); } /* @@ -316,11 +307,10 @@ ssize_t write_file(struct smb_request *req, if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) { setup_write_cache(fsp, - smb_fname->st.st_ex_size); + fsp->fsp_name->st.st_ex_size); wcp = fsp->wcp; } } - TALLOC_FREE(smb_fname); } #ifdef WITH_PROFILE @@ -382,8 +372,10 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", return total_written; } - DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n", - fsp->fsp_name, fsp->fh->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size)); + DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f " + "wcp->data_size=%u\n", fsp_str_dbg(fsp), fsp->fh->fd, + (double)pos, (unsigned int)n, (double)wcp->offset, + (unsigned int)wcp->data_size)); fsp->fh->pos = pos + n; @@ -828,7 +820,8 @@ void delete_write_cache(files_struct *fsp) SAFE_FREE(wcp->data); SAFE_FREE(fsp->wcp); - DEBUG(10,("delete_write_cache: File %s deleted write cache\n", fsp->fsp_name )); + DEBUG(10,("delete_write_cache: File %s deleted write cache\n", + fsp_str_dbg(fsp))); } /**************************************************************************** @@ -871,7 +864,7 @@ static bool setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) allocated_write_caches++; DEBUG(10,("setup_write_cache: File %s allocated write cache size %lu\n", - fsp->fsp_name, (unsigned long)wcp->alloc_size )); + fsp_str_dbg(fsp), (unsigned long)wcp->alloc_size)); return True; } @@ -888,7 +881,7 @@ void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size) char *msg; if (asprintf(&msg, "set_filelen_write_cache: size change " "on file %s with write cache size = %lu\n", - fsp->fsp_name, + fsp->fsp_name->base_name, (unsigned long)fsp->wcp->data_size) != -1) { smb_panic(msg); } else { @@ -970,7 +963,13 @@ NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_throug int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst) { if (fsp->fh->fd == -1) { - return vfs_stat_smb_fname(fsp->conn, fsp->fsp_name, pst); + int ret; + + ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); + if (ret != -1) { + *pst = fsp->fsp_name->st; + } + return ret; } else { return SMB_VFS_FSTAT(fsp, pst); } diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 48d2288468..8bd914bf0d 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -44,6 +44,7 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn, { int i; files_struct *fsp; + NTSTATUS status; /* we want to give out file handles differently on each new connection because of a common bug in MS clients where they try to @@ -100,8 +101,18 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn, fsp->fnum = i + FILE_HANDLE_OFFSET; SMB_ASSERT(fsp->fnum < 65536); - string_set(&fsp->fsp_name,""); - + /* + * Create an smb_filename with "" for the base_name. There are very + * few NULL checks, so make sure it's initialized with something. to + * be safe until an audit can be done. + */ + status = create_synthetic_smb_fname(fsp, "", NULL, NULL, + &fsp->fsp_name); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(fsp); + TALLOC_FREE(fsp->fh); + } + DLIST_ADD(Files, fsp); DEBUG(5,("allocated file structure %d, fnum = %d (%d used)\n", @@ -241,8 +252,9 @@ void file_dump_open_table(void) files_struct *fsp; for (fsp=Files;fsp;fsp=fsp->next,count++) { - DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, gen = %lu, fileid=%s\n", - count, fsp->fnum, fsp->fsp_name, fsp->fh->fd, (unsigned long)fsp->fh->gen_id, + DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, gen = %lu, " + "fileid=%s\n", count, fsp->fnum, fsp_str_dbg(fsp), + fsp->fh->fd, (unsigned long)fsp->fh->gen_id, file_id_string_tos(&fsp->file_id))); } } @@ -288,8 +300,10 @@ files_struct *file_find_dif(struct file_id id, unsigned long gen_id) if ((fsp->fh->fd == -1) && (fsp->oplock_type != NO_OPLOCK) && (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) { - DEBUG(0,("file_find_dif: file %s file_id = %s, gen = %u \ -oplock_type = %u is a stat open with oplock type !\n", fsp->fsp_name, + DEBUG(0,("file_find_dif: file %s file_id = " + "%s, gen = %u oplock_type = %u is a " + "stat open with oplock type !\n", + fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), (unsigned int)fsp->fh->gen_id, (unsigned int)fsp->oplock_type )); @@ -390,10 +404,11 @@ bool file_find_subpath(files_struct *dir_fsp) { files_struct *fsp; size_t dlen; - char *d_fullname = talloc_asprintf(talloc_tos(), - "%s/%s", - dir_fsp->conn->connectpath, - dir_fsp->fsp_name); + char *d_fullname; + + d_fullname = talloc_asprintf(talloc_tos(), "%s/%s", + dir_fsp->conn->connectpath, + dir_fsp->fsp_name->base_name); if (!d_fullname) { return false; @@ -411,7 +426,7 @@ bool file_find_subpath(files_struct *dir_fsp) d1_fullname = talloc_asprintf(talloc_tos(), "%s/%s", fsp->conn->connectpath, - fsp->fsp_name); + fsp->fsp_name->base_name); if (strnequal(d_fullname, d1_fullname, dlen)) { TALLOC_FREE(d_fullname); @@ -449,8 +464,6 @@ void file_free(struct smb_request *req, files_struct *fsp) { DLIST_REMOVE(Files, fsp); - string_free(&fsp->fsp_name); - TALLOC_FREE(fsp->fake_file_handle); if (fsp->fh->ref_count == 1) { @@ -500,6 +513,7 @@ void file_free(struct smb_request *req, files_struct *fsp) information */ ZERO_STRUCTP(fsp); + /* fsp->fsp_name is a talloc child and is free'd automatically. */ TALLOC_FREE(fsp); } @@ -546,7 +560,7 @@ files_struct *file_fsp(struct smb_request *req, uint16 fid) Duplicate the file handle part for a DOS or FCB open. ****************************************************************************/ -void dup_file_fsp(struct smb_request *req, files_struct *from, +NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from, uint32 access_mask, uint32 share_access, uint32 create_options, files_struct *to) { @@ -575,5 +589,34 @@ void dup_file_fsp(struct smb_request *req, files_struct *from, to->modified = from->modified; to->is_directory = from->is_directory; to->aio_write_behind = from->aio_write_behind; - string_set(&to->fsp_name,from->fsp_name); + return fsp_set_smb_fname(to, from->fsp_name); +} + +/** + * Return a debug string using the debug_ctx(). This can only be called from + * DEBUG() macros due to the debut_ctx(). + */ +const char *fsp_str_dbg(const struct files_struct *fsp) +{ + return smb_fname_str_dbg(fsp->fsp_name); +} + +/** + * The only way that the fsp->fsp_name field should ever be set. + */ +NTSTATUS fsp_set_smb_fname(struct files_struct *fsp, + const struct smb_filename *smb_fname_in) +{ + NTSTATUS status; + struct smb_filename *smb_fname_new; + + status = copy_smb_filename(fsp, smb_fname_in, &smb_fname_new); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + TALLOC_FREE(fsp->fsp_name); + fsp->fsp_name = smb_fname_new; + + return NT_STATUS_OK; } diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 1067dab074..96a411dd70 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -454,7 +454,7 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid, } DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n", - subcommand, fsp->fsp_name, pnum)); + subcommand, fsp_str_dbg(fsp), pnum)); DEBUG(10, ("api_fd_reply: p:%p max_trans_reply: %d\n", fsp, mdrcnt)); diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index ded888c021..8f37923865 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -182,7 +182,7 @@ void change_notify_reply(connection_struct *conn, static void notify_callback(void *private_data, const struct notify_event *e) { files_struct *fsp = (files_struct *)private_data; - DEBUG(10, ("notify_callback called for %s\n", fsp->fsp_name)); + DEBUG(10, ("notify_callback called for %s\n", fsp_str_dbg(fsp))); notify_fsp(fsp, e->action, e->path); } @@ -200,8 +200,9 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter, return NT_STATUS_NO_MEMORY; } + /* Do notify operations on the base_name. */ if (asprintf(&fullpath, "%s/%s", fsp->conn->connectpath, - fsp->fsp_name) == -1) { + fsp->fsp_name->base_name) == -1) { DEBUG(0, ("asprintf failed\n")); TALLOC_FREE(fsp->notify); return NT_STATUS_NO_MEMORY; @@ -236,7 +237,7 @@ NTSTATUS change_notify_add_request(struct smb_request *req, struct smbd_server_connection *sconn = smbd_server_conn; DEBUG(10, ("change_notify_add_request: Adding request for %s: " - "max_param = %d\n", fsp->fsp_name, (int)max_param)); + "max_param = %d\n", fsp_str_dbg(fsp), (int)max_param)); if (!(request = talloc(NULL, struct notify_change_request)) || !(map = talloc(request, struct notify_mid_map))) { diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index b65af26eca..ff76b7a21f 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -794,7 +794,7 @@ static NTSTATUS set_sd(files_struct *fsp, uint8 *data, uint32 sd_len, security_acl_map_generic(psd->sacl, &file_generic_mapping); if (DEBUGLEVEL >= 10) { - DEBUG(10,("set_sd for file %s\n", fsp->fsp_name )); + DEBUG(10,("set_sd for file %s\n", fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, psd); } @@ -1523,7 +1523,7 @@ static void call_nt_transact_notify_change(connection_struct *conn, DEBUG(3,("call_nt_transact_notify_change: notify change " "called on %s, filter = %s, recursive = %d\n", - fsp->fsp_name, filter_string, recursive)); + fsp_str_dbg(fsp), filter_string, recursive)); TALLOC_FREE(filter_string); } @@ -1626,7 +1626,7 @@ static void call_nt_transact_rename(connection_struct *conn, send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0); DEBUG(3,("nt transact rename from = %s, to = %s ignored!\n", - fsp->fsp_name, new_name)); + fsp_str_dbg(fsp), new_name)); return; } @@ -1684,8 +1684,9 @@ static void call_nt_transact_query_security_desc(connection_struct *conn, security_info_wanted = IVAL(params,4); - DEBUG(3,("call_nt_transact_query_security_desc: file = %s, info_wanted = 0x%x\n", fsp->fsp_name, - (unsigned int)security_info_wanted )); + DEBUG(3,("call_nt_transact_query_security_desc: file = %s, " + "info_wanted = 0x%x\n", fsp_str_dbg(fsp), + (unsigned int)security_info_wanted)); params = nttrans_realloc(ppparams, 4); if(params == NULL) { @@ -1722,7 +1723,8 @@ static void call_nt_transact_query_security_desc(connection_struct *conn, DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size)); if (DEBUGLEVEL >= 10) { - DEBUG(10,("call_nt_transact_query_security_desc for file %s\n", fsp->fsp_name)); + DEBUG(10,("call_nt_transact_query_security_desc for file %s\n", + fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, psd); } @@ -1796,8 +1798,8 @@ static void call_nt_transact_set_security_desc(connection_struct *conn, security_info_sent = IVAL(params,4); - DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name, - (unsigned int)security_info_sent )); + DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", + fsp_str_dbg(fsp), (unsigned int)security_info_sent)); if (data_count == 0) { reply_doserror(req, ERRDOS, ERRnoaccess); @@ -2021,7 +2023,7 @@ static void call_nt_transact_ioctl(connection_struct *conn, cur_pdata+=12; DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n", - shadow_data->num_volumes,fsp->fsp_name)); + shadow_data->num_volumes, fsp_str_dbg(fsp))); if (labels && shadow_data->labels) { for (i=0;inum_volumes;i++) { srvstr_push(pdata, req->flags2, diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 404461fb5e..33763d202d 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -219,13 +219,13 @@ void change_file_owner_to_parent(connection_struct *conn, if (ret == -1) { DEBUG(0,("change_file_owner_to_parent: failed to fchown " "file %s to parent directory uid %u. Error " - "was %s\n", fsp->fsp_name, + "was %s\n", fsp_str_dbg(fsp), (unsigned int)smb_fname_parent->st.st_ex_uid, strerror(errno) )); } DEBUG(10,("change_file_owner_to_parent: changed new file %s to " - "parent directory uid %u.\n", fsp->fsp_name, + "parent directory uid %u.\n", fsp_str_dbg(fsp), (unsigned int)smb_fname_parent->st.st_ex_uid)); TALLOC_FREE(smb_fname_parent); @@ -350,7 +350,6 @@ static NTSTATUS open_file(files_struct *fsp, uint32 access_mask, /* client requested access mask. */ uint32 open_access_mask) /* what we're actually using in the open. */ { - char *path = NULL; NTSTATUS status = NT_STATUS_OK; int accmode = (flags & O_ACCMODE); int local_flags = flags; @@ -435,7 +434,7 @@ static NTSTATUS open_file(files_struct *fsp, * wildcard characters are allowed in stream names * only test the basefilename */ - wild = fsp->base_fsp->fsp_name; + wild = fsp->base_fsp->fsp_name->base_name; } else { wild = smb_fname->base_name; } @@ -615,16 +614,13 @@ static NTSTATUS open_file(files_struct *fsp, conn->case_sensitive)) { fsp->aio_write_behind = True; } - - status = get_full_smb_filename(talloc_tos(), smb_fname, - &path); + status = fsp_set_smb_fname(fsp, smb_fname); if (!NT_STATUS_IS_OK(status)) { + fd_close(fsp); + errno = map_errno_from_nt_status(status); return status; } - string_set(&fsp->fsp_name, path); - TALLOC_FREE(path); - fsp->wcp = NULL; /* Write cache pointer. */ DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n", @@ -796,7 +792,8 @@ static void validate_my_share_entries(int num, str = talloc_asprintf(talloc_tos(), "validate_my_share_entries: " "file %s, oplock_type = 0x%x, op_type = 0x%x\n", - fsp->fsp_name, (unsigned int)fsp->oplock_type, + fsp->fsp_name->base_name, + (unsigned int)fsp->oplock_type, (unsigned int)share_entry->op_type ); smb_panic(str); } @@ -1030,7 +1027,7 @@ static bool delay_for_oplocks(struct share_mode_lock *lck, } DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n", - fsp->oplock_type, fsp->fsp_name)); + fsp->oplock_type, fsp_str_dbg(fsp))); /* No delay. */ return false; @@ -1153,13 +1150,6 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req, uint32 create_options) { files_struct *fsp; - char *fname = NULL; - NTSTATUS status; - - status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } DEBUG(5,("fcb_or_dos_open: attempting old open semantics for " "file %s.\n", smb_fname_str_dbg(smb_fname))); @@ -1169,7 +1159,7 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req, DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, " "vuid = %u, file_pid = %u, private_options = 0x%x " - "access_mask = 0x%x\n", fsp->fsp_name, + "access_mask = 0x%x\n", fsp_str_dbg(fsp), fsp->fh->fd, (unsigned int)fsp->vuid, (unsigned int)fsp->file_pid, (unsigned int)fsp->fh->private_options, @@ -1181,7 +1171,9 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req, (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) && (fsp->access_mask & FILE_WRITE_DATA) && - strequal(fsp->fsp_name, fname)) { + strequal(fsp->fsp_name->base_name, smb_fname->base_name) && + strequal(fsp->fsp_name->stream_name, + smb_fname->stream_name)) { DEBUG(10,("fcb_or_dos_open: file match\n")); break; } @@ -1199,10 +1191,8 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req, } /* We need to duplicate this fsp. */ - dup_file_fsp(req, fsp, access_mask, share_access, - create_options, fsp_to_dup_into); - - return NT_STATUS_OK; + return dup_file_fsp(req, fsp, access_mask, share_access, + create_options, fsp_to_dup_into); } /**************************************************************************** @@ -2612,8 +2602,10 @@ static NTSTATUS open_directory(connection_struct *conn, fsp->sent_oplock_break = NO_BREAK_SENT; fsp->is_directory = True; fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False; - - string_set(&fsp->fsp_name, smb_dname->base_name); + status = fsp_set_smb_fname(fsp, smb_dname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } mtimespec = smb_dname->st.st_ex_mtime; @@ -2731,6 +2723,11 @@ void msg_file_was_renamed(struct messaging_context *msg, bn_len = strlen(base_name); stream_name = sharepath + sp_len + 1 + bn_len + 1; + /* stream_name must always be NULL if there is no stream. */ + if (stream_name[0] == '\0') { + stream_name = NULL; + } + status = create_synthetic_smb_fname(talloc_tos(), base_name, stream_name, NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -2744,18 +2741,14 @@ void msg_file_was_renamed(struct messaging_context *msg, for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) { if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) { - char *newname = NULL; DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n", - fsp->fnum, fsp->fsp_name, + fsp->fnum, fsp_str_dbg(fsp), smb_fname_str_dbg(smb_fname))); - status = get_full_smb_filename(talloc_tos(), - smb_fname, &newname); + status = fsp_set_smb_fname(fsp, smb_fname); if (!NT_STATUS_IS_OK(status)) { goto out; } - string_set(&fsp->fsp_name, newname); - TALLOC_FREE(newname); } else { /* TODO. JRA. */ /* Now we have the complete path we can work out if this is @@ -2766,7 +2759,7 @@ void msg_file_was_renamed(struct messaging_context *msg, fsp->conn->connectpath, sharepath, fsp->fnum, - fsp->fsp_name, + fsp_str_dbg(fsp), smb_fname_str_dbg(smb_fname))); } } @@ -2927,7 +2920,7 @@ NTSTATUS open_streams_for_delete(connection_struct *conn, } DEBUG(10, ("Closing stream # %d, %s\n", i, - streams[i]->fsp_name)); + fsp_str_dbg(streams[i]))); close_file(NULL, streams[i], NORMAL_CLOSE); } @@ -3327,6 +3320,11 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn, dir_fsp = file_fsp(req, root_dir_fid); + if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) { + status = NT_STATUS_INVALID_HANDLE; + goto out; + } + if (dir_fsp == NULL) { status = NT_STATUS_INVALID_HANDLE; goto out; @@ -3355,7 +3353,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn, goto out; } - if (ISDOT(dir_fsp->fsp_name)) { + if (ISDOT(dir_fsp->fsp_name->base_name)) { /* * We're at the toplevel dir, the final file name * must not contain ./, as this is filtered out @@ -3368,7 +3366,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn, goto out; } } else { - size_t dir_name_len = strlen(dir_fsp->fsp_name); + size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name); /* * Copy in the base directory name. @@ -3380,7 +3378,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn, status = NT_STATUS_NO_MEMORY; goto out; } - memcpy(parent_fname, dir_fsp->fsp_name, + memcpy(parent_fname, dir_fsp->fsp_name->base_name, dir_name_len+1); /* diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index e9b2a6cf95..dd8d5372fb 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -81,7 +81,7 @@ bool set_file_oplock(files_struct *fsp, int oplock_type) DEBUG(5,("set_file_oplock: granted oplock on file %s, %s/%lu, " "tv_sec = %x, tv_usec = %x\n", - fsp->fsp_name, file_id_string_tos(&fsp->file_id), + fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), fsp->fh->gen_id, (int)fsp->open_time.tv_sec, (int)fsp->open_time.tv_usec )); @@ -158,14 +158,15 @@ bool remove_oplock(files_struct *fsp) NULL); if (lck == NULL) { DEBUG(0,("remove_oplock: failed to lock share entry for " - "file %s\n", fsp->fsp_name )); + "file %s\n", fsp_str_dbg(fsp))); return False; } ret = remove_share_oplock(lck, fsp); if (!ret) { DEBUG(0,("remove_oplock: failed to remove share oplock for " "file %s fnum %d, %s\n", - fsp->fsp_name, fsp->fnum, file_id_string_tos(&fsp->file_id))); + fsp_str_dbg(fsp), fsp->fnum, + file_id_string_tos(&fsp->file_id))); } release_file_oplock(fsp); TALLOC_FREE(lck); @@ -184,14 +185,15 @@ bool downgrade_oplock(files_struct *fsp) NULL); if (lck == NULL) { DEBUG(0,("downgrade_oplock: failed to lock share entry for " - "file %s\n", fsp->fsp_name )); + "file %s\n", fsp_str_dbg(fsp))); return False; } ret = downgrade_share_oplock(lck, fsp); if (!ret) { DEBUG(0,("downgrade_oplock: failed to downgrade share oplock " "for file %s fnum %d, file_id %s\n", - fsp->fsp_name, fsp->fnum, file_id_string_tos(&fsp->file_id))); + fsp_str_dbg(fsp), fsp->fnum, + file_id_string_tos(&fsp->file_id))); } downgrade_file_oplock(fsp); @@ -294,7 +296,8 @@ static files_struct *initial_break_processing(struct file_id id, unsigned long f if(fsp->oplock_type == NO_OPLOCK) { if( DEBUGLVL( 3 ) ) { - dbgtext( "initial_break_processing: file %s ", fsp->fsp_name ); + dbgtext( "initial_break_processing: file %s ", + fsp_str_dbg(fsp)); dbgtext( "(file_id = %s gen_id = %lu) has no oplock.\n", file_id_string_tos(&id), fsp->fh->gen_id ); dbgtext( "Allowing break to succeed regardless.\n" ); @@ -314,7 +317,8 @@ static void oplock_timeout_handler(struct event_context *ctx, /* Remove the timed event handler. */ TALLOC_FREE(fsp->oplock_timeout); - DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n", fsp->fsp_name)); + DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n", + fsp_str_dbg(fsp))); global_client_failed_oplock_break = True; remove_oplock(fsp); reply_to_oplock_break_requests(fsp); @@ -375,7 +379,7 @@ void break_level2_to_none_async(files_struct *fsp) DEBUG(10,("process_oplock_async_level2_break_message: sending break " "to none message for fid %d, file %s\n", fsp->fnum, - fsp->fsp_name)); + fsp_str_dbg(fsp))); /* Now send a break to none message to our client. */ break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE); @@ -506,7 +510,7 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx, !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { DEBUG(3, ("Already downgraded oplock on %s: %s\n", file_id_string_tos(&fsp->file_id), - fsp->fsp_name)); + fsp_str_dbg(fsp))); /* We just send the same message back. */ messaging_send_buf(msg_ctx, src, MSG_SMB_BREAK_RESPONSE, (uint8 *)data->data, @@ -740,7 +744,7 @@ static void contend_level2_oplocks_begin_default(files_struct *fsp, NULL); if (lck == NULL) { DEBUG(0,("release_level_2_oplocks_on_change: failed to lock " - "share mode entry for file %s.\n", fsp->fsp_name )); + "share mode entry for file %s.\n", fsp_str_dbg(fsp))); return; } diff --git a/source3/smbd/oplock_irix.c b/source3/smbd/oplock_irix.c index 89b8e0f7b5..dd32177988 100644 --- a/source3/smbd/oplock_irix.c +++ b/source3/smbd/oplock_irix.c @@ -212,7 +212,8 @@ static bool irix_set_kernel_oplock(struct kernel_oplocks *_ctx, DEBUG(0,("irix_set_kernel_oplock: Unable to get " "kernel oplock on file %s, file_id %s " "gen_id = %ul. Error was %s\n", - fsp->fsp_name, file_id_string_tos(&fsp->file_id), + fsp_str_dbg(fsp), + file_id_string_tos(&fsp->file_id), fsp->fh->gen_id, strerror(errno) )); } else { @@ -220,7 +221,7 @@ static bool irix_set_kernel_oplock(struct kernel_oplocks *_ctx, "file %s, fd = %d, file_id = %s, " "gen_id = %ul. Another process had the file " "open.\n", - fsp->fsp_name, fsp->fh->fd, + fsp_str_dbg(fsp), fsp->fh->fd, file_id_string_tos(&fsp->file_id), fsp->fh->gen_id )); } @@ -229,7 +230,7 @@ static bool irix_set_kernel_oplock(struct kernel_oplocks *_ctx, DEBUG(10,("irix_set_kernel_oplock: got kernel oplock on file %s, file_id = %s " "gen_id = %ul\n", - fsp->fsp_name, file_id_string_tos(&fsp->file_id), + fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), fsp->fh->gen_id)); return True; @@ -250,7 +251,8 @@ static void irix_release_kernel_oplock(struct kernel_oplocks *_ctx, int state = sys_fcntl_long(fsp->fh->fd, F_OPLKACK, -1); dbgtext("irix_release_kernel_oplock: file %s, file_id = %s" "gen_id = %ul, has kernel oplock state " - "of %x.\n", fsp->fsp_name, file_id_string_tos(&fsp->file_id), + "of %x.\n", fsp_str_dbg(fsp), + file_id_string_tos(&fsp->file_id), fsp->fh->gen_id, state ); } @@ -263,7 +265,8 @@ static void irix_release_kernel_oplock(struct kernel_oplocks *_ctx, "removing kernel oplock on file " ); dbgtext("%s, file_id = %s gen_id = %ul. " "Error was %s\n", - fsp->fsp_name, file_id_string_tos(&fsp->file_id), + fsp_str_dbg(fsp), + file_id_string_tos(&fsp->file_id), fsp->fh->gen_id, strerror(errno) ); } diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c index 273fbfdc01..b4a5495e4b 100644 --- a/source3/smbd/oplock_linux.c +++ b/source3/smbd/oplock_linux.c @@ -111,7 +111,7 @@ static bool linux_set_kernel_oplock(struct kernel_oplocks *ctx, if ( SMB_VFS_LINUX_SETLEASE(fsp, F_WRLCK) == -1) { DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, " "fd = %d, file_id = %s. (%s)\n", - fsp->fsp_name, fsp->fh->fd, + fsp_str_dbg(fsp), fsp->fh->fd, file_id_string_tos(&fsp->file_id), strerror(errno))); return False; @@ -119,7 +119,7 @@ static bool linux_set_kernel_oplock(struct kernel_oplocks *ctx, DEBUG(3,("linux_set_kernel_oplock: got kernel oplock on file %s, " "file_id = %s gen_id = %lu\n", - fsp->fsp_name, file_id_string_tos(&fsp->file_id), + fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), fsp->fh->gen_id)); return True; @@ -140,7 +140,8 @@ static void linux_release_kernel_oplock(struct kernel_oplocks *ctx, int state = fcntl(fsp->fh->fd, F_GETLEASE, 0); dbgtext("linux_release_kernel_oplock: file %s, file_id = %s " "gen_id = %lu has kernel oplock state " - "of %x.\n", fsp->fsp_name, file_id_string_tos(&fsp->file_id), + "of %x.\n", fsp_str_dbg(fsp), + file_id_string_tos(&fsp->file_id), fsp->fh->gen_id, state ); } @@ -152,7 +153,7 @@ static void linux_release_kernel_oplock(struct kernel_oplocks *ctx, dbgtext("linux_release_kernel_oplock: Error when " "removing kernel oplock on file " ); dbgtext("%s, file_id = %s, gen_id = %lu. " - "Error was %s\n", fsp->fsp_name, + "Error was %s\n", fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), fsp->fh->gen_id, strerror(errno) ); } diff --git a/source3/smbd/oplock_onefs.c b/source3/smbd/oplock_onefs.c index 497cfc7b54..a73100abdf 100644 --- a/source3/smbd/oplock_onefs.c +++ b/source3/smbd/oplock_onefs.c @@ -74,7 +74,8 @@ const char *onefs_cb_record_str_dbg(const struct onefs_callback_record *r) switch (r->state) { case ONEFS_OPEN_FILE: result = talloc_asprintf(dbg_ctx(), "cb record %llu for file " - "%s", r->id, r->data.fsp->fsp_name); + "%s", r->id, + fsp_str_dbg(r->data.fsp)); case ONEFS_WAITING_FOR_OPLOCK: result = talloc_asprintf(dbg_ctx(), "cb record %llu for " "pending mid %d", r->id, @@ -299,7 +300,7 @@ static void oplock_break_to_none_handler(uint64_t id) } DEBUG(10, ("oplock_break_to_none_handler called for file %s\n", - cb->data.fsp->fsp_name)); + cb->data.fsp_str_dbg(fsp))); init_share_mode_entry(&sme, cb, FORCE_OPLOCK_BREAK_TO_NONE); share_mode_entry_to_message(msg, &sme); @@ -336,7 +337,7 @@ static void oplock_break_to_level_two_handler(uint64_t id) } DEBUG(10, ("oplock_break_to_level_two_handler called for file %s\n", - cb->data.fsp->fsp_name)); + cb->data.fsp_str_dbg(fsp))); init_share_mode_entry(&sme, cb, LEVEL_II_OPLOCK); share_mode_entry_to_message(msg, &sme); @@ -377,7 +378,7 @@ static void oplock_revoked_handler(uint64_t id) SMB_ASSERT(fsp->oplock_timeout == NULL); DEBUG(0,("Level 1 oplock break failed for file %s. Forcefully " - "revoking oplock\n", fsp->fsp_name)); + "revoking oplock\n", fsp_str_dbg(fsp))); global_client_failed_oplock_break = True; remove_oplock(fsp); @@ -501,7 +502,7 @@ static void onefs_release_kernel_oplock(struct kernel_oplocks *_ctx, enum oplock_type oplock = onefs_samba_oplock_to_oplock(oplock_type); DEBUG(10, ("onefs_release_kernel_oplock: Releasing %s to type %s\n", - fsp->fsp_name, onefs_oplock_str(oplock))); + fsp_str_dbg(fsp), onefs_oplock_str(oplock))); if (fsp->fh->fd == -1) { DEBUG(1, ("no fd\n")); diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 799568d0d5..091db09987 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -37,6 +37,7 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name, { struct connection_struct *conn = smb_req->conn; struct files_struct *fsp; + struct smb_filename *smb_fname = NULL; NTSTATUS status; status = file_new(smb_req, conn, &fsp); @@ -50,7 +51,19 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name, fsp->vuid = smb_req->vuid; fsp->can_lock = false; fsp->access_mask = FILE_READ_DATA | FILE_WRITE_DATA; - string_set(&fsp->fsp_name, name); + + status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + file_free(smb_req, fsp); + return status; + } + status = fsp_set_smb_fname(fsp, smb_fname); + TALLOC_FREE(smb_fname); + if (!NT_STATUS_IS_OK(status)) { + file_free(smb_req, fsp); + return status; + } status = np_open(NULL, name, conn->client_address, conn->server_info, &fsp->fake_file_handle); @@ -179,7 +192,7 @@ void reply_pipe_write(struct smb_request *req) data = req->buf + 3; DEBUG(6, ("reply_pipe_write: %x name: %s len: %d\n", (int)fsp->fnum, - fsp->fsp_name, (int)state->numtowrite)); + fsp_str_dbg(fsp), (int)state->numtowrite)); subreq = np_write_send(state, smbd_event_context(), fsp->fake_file_handle, data, state->numtowrite); @@ -275,7 +288,7 @@ void reply_pipe_write_and_X(struct smb_request *req) == (PIPE_START_MESSAGE|PIPE_RAW_MODE)); DEBUG(6, ("reply_pipe_write_and_X: %x name: %s len: %d\n", - (int)fsp->fnum, fsp->fsp_name, (int)state->numtowrite)); + (int)fsp->fnum, fsp_str_dbg(fsp), (int)state->numtowrite)); data = (uint8_t *)smb_base(req->inbuf) + smb_doff; diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 76eee9b56a..fb2cda40ce 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -256,15 +256,16 @@ static void store_inheritance_attributes(files_struct *fsp, ret = SMB_VFS_FSETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME, pai_buf, store_size, 0); } else { - ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME, - pai_buf, store_size, 0); + ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name, + SAMBA_POSIX_INHERITANCE_EA_NAME, + pai_buf, store_size, 0); } SAFE_FREE(pai_buf); DEBUG(10,("store_inheritance_attribute: type 0x%x for file %s\n", (unsigned int)sd_type, - fsp->fsp_name)); + fsp_str_dbg(fsp))); if (ret == -1 && !no_acl_syscall_error(errno)) { DEBUG(1,("store_inheritance_attribute: Error %s\n", strerror(errno) )); @@ -599,8 +600,10 @@ static struct pai_val *fload_inherited_info(files_struct *fsp) ret = SMB_VFS_FGETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME, pai_buf, pai_buf_size); } else { - ret = SMB_VFS_GETXATTR(fsp->conn,fsp->fsp_name,SAMBA_POSIX_INHERITANCE_EA_NAME, - pai_buf, pai_buf_size); + ret = SMB_VFS_GETXATTR(fsp->conn, + fsp->fsp_name->base_name, + SAMBA_POSIX_INHERITANCE_EA_NAME, + pai_buf, pai_buf_size); } if (ret == -1) { @@ -618,7 +621,8 @@ static struct pai_val *fload_inherited_info(files_struct *fsp) } } while (ret == -1); - DEBUG(10,("load_inherited_info: ret = %lu for file %s\n", (unsigned long)ret, fsp->fsp_name)); + DEBUG(10,("load_inherited_info: ret = %lu for file %s\n", + (unsigned long)ret, fsp_str_dbg(fsp))); if (ret == -1) { /* No attribute or not supported. */ @@ -637,8 +641,7 @@ static struct pai_val *fload_inherited_info(files_struct *fsp) if (paiv) { DEBUG(10,("load_inherited_info: ACL type is 0x%x for file %s\n", - (unsigned int)paiv->sd_type, - fsp->fsp_name)); + (unsigned int)paiv->sd_type, fsp_str_dbg(fsp))); } SAFE_FREE(pai_buf); @@ -1727,8 +1730,12 @@ static bool create_canon_ace_lists(files_struct *fsp, got_dir_allow = True; if ((current_ace->attr == DENY_ACE) && got_dir_allow) { - DEBUG(0,("create_canon_ace_lists: malformed ACL in inheritable ACL ! \ -Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name )); + DEBUG(0,("create_canon_ace_lists: " + "malformed ACL in " + "inheritable ACL! Deny entry " + "after Allow entry. Failing " + "to set on file %s.\n", + fsp_str_dbg(fsp))); free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); return False; @@ -1785,8 +1792,10 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name )); got_file_allow = True; if ((current_ace->attr == DENY_ACE) && got_file_allow) { - DEBUG(0,("create_canon_ace_lists: malformed ACL in file ACL ! \ -Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name )); + DEBUG(0,("create_canon_ace_lists: malformed " + "ACL in file ACL ! Deny entry after " + "Allow entry. Failing to set on file " + "%s.\n", fsp_str_dbg(fsp))); free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); return False; @@ -2169,17 +2178,8 @@ static mode_t create_default_mode(files_struct *fsp, bool interitable_mode) mode_t mode; if (interitable_mode) { - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - - status = create_synthetic_smb_fname_split(talloc_tos(), - fsp->fsp_name, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return 0; - } - mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE, smb_fname, - NULL); + mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE, + fsp->fsp_name, NULL); } else { mode = S_IRUSR; } @@ -2602,14 +2602,9 @@ static bool set_canon_ace_list(files_struct *fsp, SMB_ACL_TYPE_T the_acl_type = (default_ace ? SMB_ACL_TYPE_DEFAULT : SMB_ACL_TYPE_ACCESS); bool needs_mask = False; mode_t mask_perms = 0; - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - psbuf, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - goto fail; - } + /* Use the psbuf that was passed in. */ + fsp->fsp_name->st = *psbuf; #if defined(POSIX_ACL_NEEDS_MASK) /* HP-UX always wants to have a mask (called "class" there). */ @@ -2767,7 +2762,7 @@ static bool set_canon_ace_list(files_struct *fsp, */ if(default_ace || fsp->is_directory || fsp->fh->fd == -1) { - if (SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname->base_name, + if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name->base_name, the_acl_type, the_acl) == -1) { /* * Some systems allow all the above calls and only fail with no ACL support @@ -2777,17 +2772,17 @@ static bool set_canon_ace_list(files_struct *fsp, *pacl_set_support = False; } - if (acl_group_override(conn, smb_fname)) { + if (acl_group_override(conn, fsp->fsp_name)) { int sret; DEBUG(5,("set_canon_ace_list: acl group " "control on and current user in file " "%s primary group.\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); become_root(); sret = SMB_VFS_SYS_ACL_SET_FILE(conn, - smb_fname->base_name, the_acl_type, + fsp->fsp_name->base_name, the_acl_type, the_acl); unbecome_root(); if (sret == 0) { @@ -2801,8 +2796,7 @@ static bool set_canon_ace_list(files_struct *fsp, "file %s (%s).\n", the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file", - smb_fname_str_dbg(smb_fname), - strerror(errno))); + fsp_str_dbg(fsp), strerror(errno))); goto fail; } } @@ -2816,13 +2810,13 @@ static bool set_canon_ace_list(files_struct *fsp, *pacl_set_support = False; } - if (acl_group_override(conn, smb_fname)) { + if (acl_group_override(conn, fsp->fsp_name)) { int sret; DEBUG(5,("set_canon_ace_list: acl group " "control on and current user in file " "%s primary group.\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); become_root(); sret = SMB_VFS_SYS_ACL_SET_FD(fsp, the_acl); @@ -2836,8 +2830,7 @@ static bool set_canon_ace_list(files_struct *fsp, DEBUG(2,("set_canon_ace_list: " "sys_acl_set_file failed for file %s " "(%s).\n", - smb_fname_str_dbg(smb_fname), - strerror(errno) )); + fsp_str_dbg(fsp), strerror(errno))); goto fail; } } @@ -2850,7 +2843,6 @@ static bool set_canon_ace_list(files_struct *fsp, if (the_acl != NULL) { SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl); } - TALLOC_FREE(smb_fname); return ret; } @@ -2906,8 +2898,9 @@ static bool convert_canon_ace_to_posix_perms( files_struct *fsp, canon_ace *file mode_t or_bits; if (ace_count != 3) { - DEBUG(3,("convert_canon_ace_to_posix_perms: Too many ACE entries for file %s to convert to \ -posix perms.\n", fsp->fsp_name )); + DEBUG(3,("convert_canon_ace_to_posix_perms: Too many ACE " + "entries for file %s to convert to posix perms.\n", + fsp_str_dbg(fsp))); return False; } @@ -2921,8 +2914,8 @@ posix perms.\n", fsp->fsp_name )); } if (!owner_ace || !group_ace || !other_ace) { - DEBUG(3,("convert_canon_ace_to_posix_perms: Can't get standard entries for file %s.\n", - fsp->fsp_name )); + DEBUG(3,("convert_canon_ace_to_posix_perms: Can't get " + "standard entries for file %s.\n", fsp_str_dbg(fsp))); return False; } @@ -2956,9 +2949,10 @@ posix perms.\n", fsp->fsp_name )); *posix_perms = (((*posix_perms) & and_bits)|or_bits); - DEBUG(10,("convert_canon_ace_to_posix_perms: converted u=%o,g=%o,w=%o to perm=0%o for file %s.\n", - (int)owner_ace->perms, (int)group_ace->perms, (int)other_ace->perms, (int)*posix_perms, - fsp->fsp_name )); + DEBUG(10,("convert_canon_ace_to_posix_perms: converted u=%o,g=%o,w=%o " + "to perm=0%o for file %s.\n", (int)owner_ace->perms, + (int)group_ace->perms, (int)other_ace->perms, + (int)*posix_perms, fsp_str_dbg(fsp))); return True; } @@ -3351,11 +3345,12 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, *ppdesc = NULL; - DEBUG(10,("posix_fget_nt_acl: called for file %s\n", fsp->fsp_name )); + DEBUG(10,("posix_fget_nt_acl: called for file %s\n", + fsp_str_dbg(fsp))); /* can it happen that fsp_name == NULL ? */ if (fsp->is_directory || fsp->fh->fd == -1) { - return posix_get_nt_acl(fsp->conn, fsp->fsp_name, + return posix_get_nt_acl(fsp->conn, fsp->fsp_name->base_name, security_info, ppdesc); } @@ -3369,8 +3364,9 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, pal = fload_inherited_info(fsp); - return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name, &sbuf, pal, - posix_acl, NULL, security_info, ppdesc); + return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name->base_name, + &sbuf, pal, posix_acl, NULL, + security_info, ppdesc); } NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, @@ -3514,7 +3510,8 @@ NTSTATUS append_parent_acl(files_struct *fsp, return NT_STATUS_NO_MEMORY; } - if (!parent_dirname(mem_ctx, fsp->fsp_name, &parent_name, NULL)) { + if (!parent_dirname(mem_ctx, fsp->fsp_name->base_name, &parent_name, + NULL)) { return NT_STATUS_NO_MEMORY; } @@ -3596,7 +3593,7 @@ NTSTATUS append_parent_acl(files_struct *fsp, "ignoring non container " "inherit flags %u on ACE with sid %s " "from parent %s\n", - fsp->fsp_name, + fsp_str_dbg(fsp), (unsigned int)se->flags, sid_string_dbg(&se->trustee), parent_name)); @@ -3609,7 +3606,7 @@ NTSTATUS append_parent_acl(files_struct *fsp, "ignoring non object " "inherit flags %u on ACE with sid %s " "from parent %s\n", - fsp->fsp_name, + fsp_str_dbg(fsp), (unsigned int)se->flags, sid_string_dbg(&se->trustee), parent_name)); @@ -3633,7 +3630,7 @@ NTSTATUS append_parent_acl(files_struct *fsp, DEBUG(10,("append_parent_acl: path %s " "ignoring ACE with protected sid %s " "from parent %s\n", - fsp->fsp_name, + fsp_str_dbg(fsp), sid_string_dbg(&se->trustee), parent_name)); continue; @@ -3671,7 +3668,7 @@ NTSTATUS append_parent_acl(files_struct *fsp, DEBUG(10,("append_parent_acl: path %s " "inheriting ACE with sid %s " "from parent %s\n", - fsp->fsp_name, + fsp_str_dbg(fsp), sid_string_dbg(&se->trustee), parent_name)); } @@ -3707,21 +3704,13 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC bool set_acl_as_root = false; bool acl_set_support = false; bool ret = false; - struct smb_filename *smb_fname = NULL; - - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } DEBUG(10,("set_nt_acl: called for file %s\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); if (!CAN_WRITE(conn)) { DEBUG(10,("set acl rejected on read-only share\n")); - status = NT_STATUS_MEDIA_WRITE_PROTECTED; - goto out; + return NT_STATUS_MEDIA_WRITE_PROTECTED; } /* @@ -3729,19 +3718,17 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC */ if(fsp->is_directory || fsp->fh->fd == -1) { - if(SMB_VFS_STAT(fsp->conn, smb_fname) != 0) { - status = map_nt_error_from_unix(errno); - goto out; + if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name) != 0) { + return map_nt_error_from_unix(errno); } } else { - if(SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { - status = map_nt_error_from_unix(errno); - goto out; + if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) { + return map_nt_error_from_unix(errno); } } /* Save the original element we check against. */ - orig_mode = smb_fname->st.st_ex_mode; + orig_mode = fsp->fsp_name->st.st_ex_mode; /* * Unpack the user/group/world id's. @@ -3749,7 +3736,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC status = unpack_nt_owners( SNUM(conn), &user, &grp, security_info_sent, psd); if (!NT_STATUS_IS_OK(status)) { - goto out; + return status; } /* @@ -3758,24 +3745,22 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC * Noticed by Simo. */ - if (((user != (uid_t)-1) && (smb_fname->st.st_ex_uid != user)) || - (( grp != (gid_t)-1) && (smb_fname->st.st_ex_gid != grp))) { + if (((user != (uid_t)-1) && (fsp->fsp_name->st.st_ex_uid != user)) || + (( grp != (gid_t)-1) && (fsp->fsp_name->st.st_ex_gid != grp))) { DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", - smb_fname_str_dbg(smb_fname), (unsigned int)user, - (unsigned int)grp )); + fsp_str_dbg(fsp), (unsigned int)user, + (unsigned int)grp)); - if(try_chown(fsp->conn, smb_fname, user, grp) == -1) { + if(try_chown(fsp->conn, fsp->fsp_name, user, grp) == -1) { DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error " - "= %s.\n", smb_fname_str_dbg(smb_fname), + "= %s.\n", fsp_str_dbg(fsp), (unsigned int)user, (unsigned int)grp, strerror(errno))); if (errno == EPERM) { - status = NT_STATUS_INVALID_OWNER; - goto out; + return NT_STATUS_INVALID_OWNER; } - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } /* @@ -3784,25 +3769,24 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC */ if(fsp->is_directory) { - if(SMB_VFS_STAT(fsp->conn, smb_fname) != 0) { - status = map_nt_error_from_unix(errno); - goto out; + if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name) != 0) { + return map_nt_error_from_unix(errno); } } else { int sret; if(fsp->fh->fd == -1) - sret = SMB_VFS_STAT(fsp->conn, smb_fname); + sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); else - sret = SMB_VFS_FSTAT(fsp, &smb_fname->st); + sret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); if(sret != 0) return map_nt_error_from_unix(errno); } /* Save the original element we check against. */ - orig_mode = smb_fname->st.st_ex_mode; + orig_mode = fsp->fsp_name->st.st_ex_mode; /* If we successfully chowned, we know we must * be able to set the acl, so do it as root. @@ -3810,24 +3794,22 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC set_acl_as_root = true; } - create_file_sids(&smb_fname->st, &file_owner_sid, &file_grp_sid); + create_file_sids(&fsp->fsp_name->st, &file_owner_sid, &file_grp_sid); - acl_perms = unpack_canon_ace(fsp, &smb_fname->st, &file_owner_sid, + acl_perms = unpack_canon_ace(fsp, &fsp->fsp_name->st, &file_owner_sid, &file_grp_sid, &file_ace_list, &dir_ace_list, security_info_sent, psd); /* Ignore W2K traverse DACL set. */ if (!file_ace_list && !dir_ace_list) { - status = NT_STATUS_OK; - goto out; + return NT_STATUS_OK; } if (!acl_perms) { DEBUG(3,("set_nt_acl: cannot set permissions\n")); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = NT_STATUS_ACCESS_DENIED; - goto out; + return NT_STATUS_ACCESS_DENIED; } /* @@ -3837,8 +3819,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC if(!(security_info_sent & DACL_SECURITY_INFORMATION) || (psd->dacl == NULL)) { free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = NT_STATUS_OK; - goto out; + return NT_STATUS_OK; } /* @@ -3851,18 +3832,17 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC become_root(); } ret = set_canon_ace_list(fsp, file_ace_list, false, - &smb_fname->st, &acl_set_support); + &fsp->fsp_name->st, &acl_set_support); if (set_acl_as_root) { unbecome_root(); } if (acl_set_support && ret == false) { DEBUG(3,("set_nt_acl: failed to set file acl on file " - "%s (%s).\n", smb_fname_str_dbg(smb_fname), + "%s (%s).\n", fsp_str_dbg(fsp), strerror(errno))); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } } @@ -3872,7 +3852,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC become_root(); } ret = set_canon_ace_list(fsp, dir_ace_list, true, - &smb_fname->st, + &fsp->fsp_name->st, &acl_set_support); if (set_acl_as_root) { unbecome_root(); @@ -3880,12 +3860,10 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC if (ret == false) { DEBUG(3,("set_nt_acl: failed to set default " "acl on directory %s (%s).\n", - smb_fname_str_dbg(smb_fname), - strerror(errno) )); + fsp_str_dbg(fsp), strerror(errno))); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } } else { int sret = -1; @@ -3898,23 +3876,23 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC become_root(); } sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, - smb_fname->base_name); + fsp->fsp_name->base_name); if (set_acl_as_root) { unbecome_root(); } if (sret == -1) { - if (acl_group_override(conn, smb_fname)) { + if (acl_group_override(conn, fsp->fsp_name)) { DEBUG(5,("set_nt_acl: acl group " "control on and current user " "in file %s primary group. " "Override delete_def_acl\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); become_root(); sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE( conn, - smb_fname->base_name); + fsp->fsp_name->base_name); unbecome_root(); } @@ -3922,8 +3900,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno))); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } } } @@ -3954,52 +3931,48 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC free_canon_ace_list(dir_ace_list); DEBUG(3,("set_nt_acl: failed to convert file acl to " "posix permissions for file %s.\n", - smb_fname_str_dbg(smb_fname))); - status = NT_STATUS_ACCESS_DENIED; - goto out; + fsp_str_dbg(fsp))); + return NT_STATUS_ACCESS_DENIED; } if (orig_mode != posix_perms) { int sret = -1; DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n", - smb_fname_str_dbg(smb_fname), - (unsigned int)posix_perms)); + fsp_str_dbg(fsp), (unsigned int)posix_perms)); if (set_acl_as_root) { become_root(); } - sret = SMB_VFS_CHMOD(conn, smb_fname->base_name, + sret = SMB_VFS_CHMOD(conn, fsp->fsp_name->base_name, posix_perms); if (set_acl_as_root) { unbecome_root(); } if(sret == -1) { - if (acl_group_override(conn, smb_fname)) { + if (acl_group_override(conn, fsp->fsp_name)) { DEBUG(5,("set_nt_acl: acl group " "control on and current user " "in file %s primary group. " "Override chmod\n", - smb_fname_str_dbg(smb_fname))); + fsp_str_dbg(fsp))); become_root(); - sret = - SMB_VFS_CHMOD(conn, - smb_fname->base_name, - posix_perms); + sret = SMB_VFS_CHMOD(conn, + fsp->fsp_name->base_name, + posix_perms); unbecome_root(); } if (sret == -1) { DEBUG(3,("set_nt_acl: chmod %s, 0%o " "failed. Error = %s.\n", - smb_fname_str_dbg(smb_fname), + fsp_str_dbg(fsp), (unsigned int)posix_perms, strerror(errno))); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } } } @@ -4008,10 +3981,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - status = NT_STATUS_OK; - out: - TALLOC_FREE(smb_fname); - return status; + return NT_STATUS_OK; } /**************************************************************************** @@ -4614,6 +4584,7 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname) connection_struct *conn; files_struct finfo; struct fd_handle fh; + NTSTATUS status; conn = TALLOC_ZERO_P(ctx, connection_struct); if (conn == NULL) { @@ -4644,16 +4615,24 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname) finfo.conn = conn; finfo.fh = &fh; finfo.fh->fd = -1; - finfo.fsp_name = CONST_DISCARD(char *,fname); + + status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, NULL, + &finfo.fsp_name); + if (!NT_STATUS_IS_OK(status)) { + conn_free_internal( conn ); + return NULL; + } if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, DACL_SECURITY_INFORMATION, &psd))) { DEBUG(0,("get_nt_acl_no_snum: get_nt_acl returned zero.\n")); + TALLOC_FREE(finfo.fsp_name); conn_free_internal( conn ); return NULL; } ret_sd = dup_sec_desc( ctx, psd ); + TALLOC_FREE(finfo.fsp_name); conn_free_internal( conn ); return ret_sd; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index a6e35c7342..46fdd4adde 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1812,7 +1812,8 @@ void reply_open(struct smb_request *req) mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime); if (fattr & aDIR) { - DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name)); + DEBUG(3,("attempt to open a directory %s\n", + fsp_str_dbg(fsp))); close_file(req, fsp, ERROR_CLOSE); reply_doserror(req, ERRDOS,ERRnoaccess); goto out; @@ -2313,9 +2314,9 @@ void reply_ctemp(struct smb_request *req) SSVAL(req->outbuf,smb_vwv0,fsp->fnum); /* the returned filename is relative to the directory */ - s = strrchr_m(fsp->fsp_name, '/'); + s = strrchr_m(fsp->fsp_name->base_name, '/'); if (!s) { - s = fsp->fsp_name; + s = fsp->fsp_name->base_name; } else { s++; } @@ -2341,8 +2342,8 @@ void reply_ctemp(struct smb_request *req) CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED); } - DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) ); - DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name, + DEBUG(2, ("reply_ctemp: created temp file %s\n", fsp_str_dbg(fsp))); + DEBUG(3, ("reply_ctemp %s fd=%d umode=0%o\n", fsp_str_dbg(fsp), fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode)); out: TALLOC_FREE(smb_fname); @@ -2357,22 +2358,13 @@ void reply_ctemp(struct smb_request *req) static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp, uint16 dirtype, SMB_STRUCT_STAT *pst) { - struct smb_filename *smb_fname = NULL; - NTSTATUS status; uint32 fmode; if (!CAN_WRITE(conn)) { return NT_STATUS_MEDIA_WRITE_PROTECTED; } - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - pst, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - fmode = dos_mode(conn, smb_fname); - TALLOC_FREE(smb_fname); + fmode = dos_mode(conn, fsp->fsp_name); if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) { return NT_STATUS_NO_SUCH_FILE; } @@ -2866,7 +2858,7 @@ static void sendfile_short_send(files_struct *fsp, if (nread < headersize) { DEBUG(0,("sendfile_short_send: sendfile failed to send " "header for file %s (%s). Terminating\n", - fsp->fsp_name, strerror(errno) )); + fsp_str_dbg(fsp), strerror(errno))); exit_server_cleanly("sendfile_short_send failed"); } @@ -2880,7 +2872,7 @@ static void sendfile_short_send(files_struct *fsp, } DEBUG(0,("sendfile_short_send: filling truncated file %s " - "with zeros !\n", fsp->fsp_name)); + "with zeros !\n", fsp_str_dbg(fsp))); while (nread < smb_maxcnt) { /* @@ -2975,15 +2967,19 @@ static void send_file_readbraw(connection_struct *conn, DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n")); if (fake_sendfile(fsp, startpos, nread) == -1) { - DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(0,("send_file_readbraw: " + "fake_sendfile failed for " + "file %s (%s).\n", + fsp_str_dbg(fsp), + strerror(errno))); exit_server_cleanly("send_file_readbraw fake_sendfile failed"); } return; } - DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(0,("send_file_readbraw: sendfile failed for " + "file %s (%s). Terminating\n", + fsp_str_dbg(fsp), strerror(errno))); exit_server_cleanly("send_file_readbraw sendfile failed"); } else if (sendfile_read == 0) { /* @@ -2995,7 +2991,7 @@ static void send_file_readbraw(connection_struct *conn, */ DEBUG(3, ("send_file_readbraw: sendfile sent zero " "bytes falling back to the normal read: " - "%s\n", fsp->fsp_name)); + "%s\n", fsp_str_dbg(fsp))); goto normal_readbraw; } @@ -3507,8 +3503,11 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, nread = fake_sendfile(fsp, startpos, smb_maxcnt); if (nread == -1) { - DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(0,("send_file_readX: " + "fake_sendfile failed for " + "file %s (%s).\n", + fsp_str_dbg(fsp), + strerror(errno))); exit_server_cleanly("send_file_readX: fake_sendfile failed"); } DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n", @@ -3517,8 +3516,9 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, goto strict_unlock; } - DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(0,("send_file_readX: sendfile failed for file " + "%s (%s). Terminating\n", fsp_str_dbg(fsp), + strerror(errno))); exit_server_cleanly("send_file_readX sendfile failed"); } else if (nread == 0) { /* @@ -3530,7 +3530,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, */ DEBUG(3, ("send_file_readX: sendfile sent zero bytes " "falling back to the normal read: %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); goto normal_read; } @@ -3560,14 +3560,16 @@ normal_read: /* Send out the header. */ if (write_data(smbd_server_fd(), (char *)headerbuf, sizeof(headerbuf)) != sizeof(headerbuf)) { - DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(0,("send_file_readX: write_data failed for file " + "%s (%s). Terminating\n", fsp_str_dbg(fsp), + strerror(errno))); exit_server_cleanly("send_file_readX sendfile failed"); } nread = fake_sendfile(fsp, startpos, smb_maxcnt); if (nread == -1) { - DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(0,("send_file_readX: fake_sendfile failed for " + "file %s (%s).\n", fsp_str_dbg(fsp), + strerror(errno))); exit_server_cleanly("send_file_readX: fake_sendfile failed"); } goto strict_unlock; @@ -3914,7 +3916,7 @@ void reply_writebraw(struct smb_request *req) status = sync_file(conn, fsp, write_through); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); reply_nterror(req, status); error_to_writebrawerr(req); goto strict_unlock; @@ -4024,7 +4026,7 @@ void reply_writeunlock(struct smb_request *req) status = sync_file(conn, fsp, False /* write through */); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); reply_nterror(req, status); goto strict_unlock; } @@ -4158,7 +4160,7 @@ void reply_write(struct smb_request *req) status = sync_file(conn, fsp, False); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("reply_write: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); reply_nterror(req, status); goto strict_unlock; } @@ -4441,7 +4443,7 @@ void reply_write_and_X(struct smb_request *req) status = sync_file(conn, fsp, write_through); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); reply_nterror(req, status); goto strict_unlock; } @@ -4577,7 +4579,7 @@ void reply_flush(struct smb_request *req) NTSTATUS status = sync_file(conn, fsp, True); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("reply_flush: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); reply_nterror(req, status); END_PROFILE(SMBflush); return; @@ -4745,8 +4747,8 @@ void reply_writeclose(struct smb_request *req) */ if (numtowrite) { - DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n", - fsp->fsp_name )); + DEBUG(3,("reply_writeclose: zero length write doesn't close " + "file %s\n", fsp_str_dbg(fsp))); close_status = close_file(req, fsp, NORMAL_CLOSE); } @@ -5743,7 +5745,6 @@ static void rename_open_files(connection_struct *conn, { files_struct *fsp; bool did_rename = False; - char *fname_dst = NULL; NTSTATUS status; for(fsp = file_find_di_first(lck->id); fsp; @@ -5757,17 +5758,13 @@ static void rename_open_files(connection_struct *conn, } DEBUG(10, ("rename_open_files: renaming file fnum %d " "(file_id %s) from %s -> %s\n", fsp->fnum, - file_id_string_tos(&fsp->file_id), fsp->fsp_name, + file_id_string_tos(&fsp->file_id), fsp_str_dbg(fsp), smb_fname_str_dbg(smb_fname_dst))); - status = get_full_smb_filename(talloc_tos(), smb_fname_dst, - &fname_dst); - if (!NT_STATUS_IS_OK(status)) { - return; + status = fsp_set_smb_fname(fsp, smb_fname_dst); + if (NT_STATUS_IS_OK(status)) { + did_rename = True; } - string_set(&fsp->fsp_name, fname_dst); - did_rename = True; - TALLOC_FREE(fname_dst); } if (!did_rename) { @@ -5899,17 +5896,12 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, } /* Make a copy of the src and dst smb_fname structs */ - status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst); + status = copy_smb_filename(ctx, fsp->fsp_name, &smb_fname_src); if (!NT_STATUS_IS_OK(status)) { goto out; } - /* - * This will be replaced with copy_smb_filename() when fsp->fsp_name - * is converted to store an smb_filename struct. - */ - status = create_synthetic_smb_fname_split(ctx, fsp->fsp_name, NULL, - &smb_fname_src); + status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst); if (!NT_STATUS_IS_OK(status)) { goto out; } @@ -7273,7 +7265,7 @@ NTSTATUS smbd_do_locking(struct smb_request *req, (double)e->offset, (double)e->count, (unsigned int)e->smbpid, - fsp->fsp_name)); + fsp_str_dbg(fsp))); if (e->brltype != UNLOCK_LOCK) { /* this can only happen with SMB2 */ @@ -7312,7 +7304,7 @@ NTSTATUS smbd_do_locking(struct smb_request *req, (double)e->offset, (double)e->count, (unsigned int)e->smbpid, - fsp->fsp_name, + fsp_str_dbg(fsp), (int)timeout)); if (type & LOCKING_ANDX_CANCEL_LOCK) { @@ -7528,7 +7520,8 @@ void reply_lockingX(struct smb_request *req) DEBUG(5,("reply_lockingX: Error : oplock break from " "client for fnum = %d (oplock=%d) and no " "oplock granted on this file (%s).\n", - fsp->fnum, fsp->oplock_type, fsp->fsp_name)); + fsp->fnum, fsp->oplock_type, + fsp_str_dbg(fsp))); /* if this is a pure oplock break request then don't * send a reply */ @@ -7551,7 +7544,7 @@ void reply_lockingX(struct smb_request *req) if (!result) { DEBUG(0, ("reply_lockingX: error in removing " - "oplock on file %s\n", fsp->fsp_name)); + "oplock on file %s\n", fsp_str_dbg(fsp))); /* Hmmm. Is this panic justified? */ smb_panic("internal tdb error"); } @@ -7708,7 +7701,6 @@ void reply_readbs(struct smb_request *req) void reply_setattrE(struct smb_request *req) { connection_struct *conn = req->conn; - struct smb_filename *smb_fname = NULL; struct smb_file_time ft; files_struct *fsp; NTSTATUS status; @@ -7728,14 +7720,6 @@ void reply_setattrE(struct smb_request *req) goto out; } - /* XXX: Remove when fsp->fsp_name is converted to smb_filename. */ - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - /* * Convert the DOS times into unix times. */ @@ -7756,7 +7740,7 @@ void reply_setattrE(struct smb_request *req) /* Ensure we have a valid stat struct for the source. */ if (fsp->fh->fd != -1) { - if (SMB_VFS_FSTAT(fsp, &smb_fname->st) == -1) { + if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == -1) { status = map_nt_error_from_unix(errno); reply_nterror(req, status); goto out; @@ -7765,9 +7749,9 @@ void reply_setattrE(struct smb_request *req) int ret = -1; if (fsp->posix_open) { - ret = SMB_VFS_LSTAT(conn, smb_fname); + ret = SMB_VFS_LSTAT(conn, fsp->fsp_name); } else { - ret = SMB_VFS_STAT(conn, smb_fname); + ret = SMB_VFS_STAT(conn, fsp->fsp_name); } if (ret == -1) { status = map_nt_error_from_unix(errno); @@ -7776,7 +7760,7 @@ void reply_setattrE(struct smb_request *req) } } - status = smb_set_file_time(conn, fsp, smb_fname, &ft, true); + status = smb_set_file_time(conn, fsp, fsp->fsp_name, &ft, true); if (!NT_STATUS_IS_OK(status)) { reply_doserror(req, ERRDOS, ERRnoaccess); goto out; @@ -7836,8 +7820,6 @@ void reply_getattrE(struct smb_request *req) int mode; files_struct *fsp; struct timespec create_ts; - struct smb_filename *smb_fname = NULL; - NTSTATUS status; START_PROFILE(SMBgetattrE); @@ -7862,16 +7844,9 @@ void reply_getattrE(struct smb_request *req) return; } - status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name, - &sbuf, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - END_PROFILE(SMBgetattrE); - return; - } + fsp->fsp_name->st = sbuf; - mode = dos_mode(conn, smb_fname); - TALLOC_FREE(smb_fname); + mode = dos_mode(conn, fsp->fsp_name); /* * Convert the times into dos times. Set create diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c index a46b36e2bb..acb5da7751 100644 --- a/source3/smbd/smb2_close.c +++ b/source3/smbd/smb2_close.c @@ -121,7 +121,7 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req, status = close_file(smbreq, fsp, NORMAL_CLOSE); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("smbd_smb2_close: close_file[%s]: %s\n", - fsp->fsp_name, nt_errstr(status))); + fsp_str_dbg(fsp), nt_errstr(status))); return status; } diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index bdff1939e5..7337a345fd 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -259,7 +259,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, files_struct *result; int info; SMB_STRUCT_STAT sbuf; - struct smb_filename *smb_fname = NULL; req = tevent_req_create(mem_ctx, &state, struct smbd_smb2_create_state); @@ -316,6 +315,8 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, } info = FILE_WAS_CREATED; } else { + struct smb_filename *smb_fname = NULL; + /* these are ignored for SMB2 */ in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */ in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */ @@ -328,6 +329,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, NULL); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); + TALLOC_FREE(smb_fname); goto out; } @@ -348,19 +350,11 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, &info); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); + TALLOC_FREE(smb_fname); goto out; } sbuf = smb_fname->st; - } - - if (!smb_fname) { - status = create_synthetic_smb_fname_split(talloc_tos(), - result->fsp_name, - &sbuf, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - goto out; - } + TALLOC_FREE(smb_fname); } smb2req->compat_chain_fsp = smbreq->chain_fsp; @@ -379,7 +373,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, state->out_allocation_size = sbuf.st_ex_blksize * sbuf.st_ex_blocks; state->out_end_of_file = sbuf.st_ex_size; state->out_file_attributes = dos_mode(result->conn, - smb_fname); + result->fsp_name); if (state->out_file_attributes == 0) { state->out_file_attributes = FILE_ATTRIBUTE_NORMAL; } @@ -387,7 +381,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, tevent_req_done(req); out: - TALLOC_FREE(smb_fname); return tevent_req_post(req, ev); } diff --git a/source3/smbd/smb2_flush.c b/source3/smbd/smb2_flush.c index 8ce683923b..1d3ae2eb06 100644 --- a/source3/smbd/smb2_flush.c +++ b/source3/smbd/smb2_flush.c @@ -176,7 +176,7 @@ static struct tevent_req *smbd_smb2_flush_send(TALLOC_CTX *mem_ctx, status = sync_file(smbreq->conn, fsp, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("smbd_smb2_flush: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status))); + fsp_str_dbg(fsp), nt_errstr(status))); tevent_req_nterror(req, status); return tevent_req_post(req, ev); } diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index f8c2d41e31..dda79c209f 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -244,7 +244,6 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, uint16_t file_info_level; char *data = NULL; unsigned int data_size = 0; - struct smb_filename *smb_fname = NULL; bool delete_pending = false; struct timespec write_time_ts; struct file_id fileid; @@ -271,15 +270,6 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, break; } - status = create_synthetic_smb_fname_split(state, - fsp->fsp_name, - NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); - } - if (fsp->fake_file_handle) { /* * This is actually for the QUOTA_FAKE_FILE --metze @@ -296,34 +286,34 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, if (INFO_LEVEL_IS_UNIX(file_info_level)) { /* Always do lstat for UNIX calls. */ - if (SMB_VFS_LSTAT(conn, smb_fname)) { + if (SMB_VFS_LSTAT(conn, fsp->fsp_name)) { DEBUG(3,("smbd_smb2_getinfo_send: " "SMB_VFS_LSTAT of %s failed " - "(%s)\n", - smb_fname_str_dbg(smb_fname), + "(%s)\n", fsp_str_dbg(fsp), strerror(errno))); status = map_nt_error_from_unix(errno); tevent_req_nterror(req, status); return tevent_req_post(req, ev); } - } else if (SMB_VFS_STAT(conn, smb_fname)) { + } else if (SMB_VFS_STAT(conn, fsp->fsp_name)) { DEBUG(3,("smbd_smb2_getinfo_send: " "SMB_VFS_STAT of %s failed (%s)\n", - smb_fname_str_dbg(smb_fname), + fsp_str_dbg(fsp), strerror(errno))); status = map_nt_error_from_unix(errno); tevent_req_nterror(req, status); return tevent_req_post(req, ev); } - fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + fileid = vfs_file_id_from_sbuf(conn, + &fsp->fsp_name->st); get_file_infos(fileid, &delete_pending, &write_time_ts); } else { /* * Original code - this is an open file. */ - if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) { DEBUG(3, ("smbd_smb2_getinfo_send: " "fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); @@ -331,14 +321,15 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, tevent_req_nterror(req, status); return tevent_req_post(req, ev); } - fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + fileid = vfs_file_id_from_sbuf(conn, + &fsp->fsp_name->st); get_file_infos(fileid, &delete_pending, &write_time_ts); } status = smbd_do_qfilepathinfo(conn, state, file_info_level, fsp, - smb_fname, + fsp->fsp_name, delete_pending, write_time_ts, ms_dfs_link, diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c index 7ab93ce574..f6d83aeeed 100644 --- a/source3/smbd/smb2_notify.c +++ b/source3/smbd/smb2_notify.c @@ -231,7 +231,7 @@ static struct tevent_req *smbd_smb2_notify_send(TALLOC_CTX *mem_ctx, DEBUG(3,("smbd_smb2_notify_send: notify change " "called on %s, filter = %s, recursive = %d\n", - fsp->fsp_name, filter_string, recursive)); + fsp_str_dbg(fsp), filter_string, recursive)); TALLOC_FREE(filter_string); } diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c index c9f281f73e..42993511ec 100644 --- a/source3/smbd/smb2_read.c +++ b/source3/smbd/smb2_read.c @@ -281,13 +281,13 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx, if (nread < 0) { DEBUG(5,("smbd_smb2_read: read_file[%s] nread[%lld]\n", - fsp->fsp_name, (long long)nread)); + fsp_str_dbg(fsp), (long long)nread)); tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); return tevent_req_post(req, ev); } if (nread == 0 && in_length != 0) { DEBUG(5,("smbd_smb2_read: read_file[%s] end of file\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); tevent_req_nterror(req, NT_STATUS_END_OF_FILE); return tevent_req_post(req, ev); } diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c index 2974695c9f..08c4a7f5bf 100644 --- a/source3/smbd/smb2_setinfo.c +++ b/source3/smbd/smb2_setinfo.c @@ -209,7 +209,6 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, case 0x01:/* SMB2_SETINFO_FILE */ { uint16_t file_info_level; - struct smb_filename *smb_fname = NULL; char *data; int data_size; int ret_size = 0; @@ -221,15 +220,6 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, file_info_level = 0xFF00 + in_file_info_class; } - status = create_synthetic_smb_fname_split(state, - fsp->fsp_name, - NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); - } - if (fsp->is_directory || fsp->fh->fd == -1) { /* * This is actually a SETFILEINFO on a directory @@ -238,21 +228,20 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, */ if (INFO_LEVEL_IS_UNIX(file_info_level)) { /* Always do lstat for UNIX calls. */ - if (SMB_VFS_LSTAT(conn, smb_fname)) { + if (SMB_VFS_LSTAT(conn, fsp->fsp_name)) { DEBUG(3,("smbd_smb2_setinfo_send: " "SMB_VFS_LSTAT of %s failed " - "(%s)\n", - smb_fname_str_dbg(smb_fname), + "(%s)\n", fsp_str_dbg(fsp), strerror(errno))); status = map_nt_error_from_unix(errno); tevent_req_nterror(req, status); return tevent_req_post(req, ev); } } else { - if (SMB_VFS_STAT(conn, smb_fname) != 0) { + if (SMB_VFS_STAT(conn, fsp->fsp_name) != 0) { DEBUG(3,("smbd_smb2_setinfo_send: " "fileinfo of %s failed (%s)\n", - smb_fname_str_dbg(smb_fname), + fsp_str_dbg(fsp), strerror(errno))); status = map_nt_error_from_unix(errno); tevent_req_nterror(req, status); @@ -270,7 +259,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, DEBUG(3,("smbd_smb2_setinfo_send: " "Cancelling print job (%s)\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); tevent_req_done(req); return tevent_req_post(req, ev); @@ -284,7 +273,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, * Original code - this is an open file. */ - if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) { + if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) { DEBUG(3,("smbd_smb2_setinfo_send: fstat " "of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); @@ -307,7 +296,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx, status = smbd_do_setfilepathinfo(conn, smbreq, state, file_info_level, fsp, - smb_fname, + fsp->fsp_name, &data, data_size, &ret_size); diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c index 31460a01a1..f1606be623 100644 --- a/source3/smbd/smb2_write.c +++ b/source3/smbd/smb2_write.c @@ -272,14 +272,14 @@ static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx, if (((nwritten == 0) && (in_data.length != 0)) || (nwritten < 0)) { DEBUG(5,("smbd_smb2_write: write_file[%s] disk full\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); tevent_req_nterror(req, NT_STATUS_DISK_FULL); return tevent_req_post(req, ev); } DEBUG(3,("smbd_smb2_write: fnum=[%d/%s] length=%d offset=%d wrote=%d\n", - fsp->fnum, fsp->fsp_name, (int)in_data.length, + fsp->fnum, fsp_str_dbg(fsp), (int)in_data.length, (int)in_offset, (int)nwritten)); if (in_flags & 0x00000001) { @@ -289,7 +289,7 @@ static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx, status = sync_file(conn, fsp, write_through); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("smbd_smb2_write: sync_file for %s returned %s\n", - fsp->fsp_name, nt_errstr(status))); + fsp_str_dbg(fsp), nt_errstr(status))); SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); tevent_req_nterror(req, status); return tevent_req_post(req, ev); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 122114c24f..e2efed331d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -502,8 +502,9 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, if (ea_list->ea.value.length == 0) { /* Remove the attribute. */ if (fsp && (fsp->fh->fd != -1)) { - DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n", - unix_ea_name, fsp->fsp_name)); + DEBUG(10,("set_ea: deleting ea name %s on " + "file %s by file descriptor.\n", + unix_ea_name, fsp_str_dbg(fsp))); ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name); } else { DEBUG(10,("set_ea: deleting ea name %s on file %s.\n", @@ -520,8 +521,9 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, #endif } else { if (fsp && (fsp->fh->fd != -1)) { - DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n", - unix_ea_name, fsp->fsp_name)); + DEBUG(10,("set_ea: setting ea name %s on file " + "%s by file descriptor.\n", + unix_ea_name, fsp_str_dbg(fsp))); ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name, ea_list->ea.value.data, ea_list->ea.value.length, 0); } else { @@ -1148,7 +1150,8 @@ static void call_trans2open(connection_struct *conn, SIVAL(params,20,inode); SSVAL(params,24,0); /* Padding. */ if (flags & 8) { - uint32 ea_size = estimate_ea_size(conn, fsp, fsp->fsp_name); + uint32 ea_size = estimate_ea_size(conn, fsp, + fsp->fsp_name->base_name); SIVAL(params, 26, ea_size); } else { SIVAL(params, 26, 0); @@ -4584,7 +4587,11 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, if (S_ISDIR(sbuf.st_ex_mode)) { if (fsp && fsp->is_directory) { - def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT); + def_acl = + SMB_VFS_SYS_ACL_GET_FILE( + conn, + fsp->fsp_name->base_name, + SMB_ACL_TYPE_DEFAULT); } else { def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT); } @@ -4791,14 +4798,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn, return; } - fname = talloc_strdup(talloc_tos(),fsp->fsp_name); - if (!fname) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, - NULL, &smb_fname); + status = copy_smb_filename(talloc_tos(), fsp->fsp_name, + &smb_fname); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); return; @@ -5524,8 +5525,9 @@ static NTSTATUS smb_file_position_information(connection_struct *conn, } #endif /* LARGE_SMB_OFF_T */ - DEBUG(10,("smb_file_position_information: Set file position information for file %s to %.0f\n", - fsp->fsp_name, (double)position_information )); + DEBUG(10,("smb_file_position_information: Set file position " + "information for file %s to %.0f\n", fsp_str_dbg(fsp), + (double)position_information)); fsp->fh->position_information = position_information; return NT_STATUS_OK; } @@ -5736,8 +5738,8 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, /* Create an smb_fname to call rename_internals_fsp() with. */ status = create_synthetic_smb_fname(talloc_tos(), - fsp->base_fsp->fsp_name, - newname, NULL, &smb_fname); + fsp->base_fsp->fsp_name->base_name, newname, NULL, + &smb_fname); if (!NT_STATUS_IS_OK(status)) { goto out; } @@ -5754,7 +5756,7 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, /* Create a char * to call rename_internals() with. */ base_name = talloc_asprintf(ctx, "%s%s", - fsp->base_fsp->fsp_name, + fsp->base_fsp->fsp_name->base_name, newname); if (!base_name) { status = NT_STATUS_NO_MEMORY; @@ -5811,13 +5813,15 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, } if (fsp) { - DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n", - fsp->fnum, fsp->fsp_name, base_name )); + DEBUG(10,("smb_file_rename_information: " + "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n", + fsp->fnum, fsp_str_dbg(fsp), base_name)); status = rename_internals_fsp(conn, fsp, smb_fname, 0, overwrite); } else { - DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n", - fname, base_name )); + DEBUG(10,("smb_file_rename_information: " + "SMB_FILE_RENAME_INFORMATION %s -> %s\n", + fname, base_name)); status = rename_internals(ctx, conn, req, fname, base_name, 0, overwrite, False, dest_has_wcard, FILE_WRITE_ATTRIBUTES); @@ -5872,7 +5876,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn, } DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n", - fname ? fname : fsp->fsp_name, + fname ? fname : fsp_str_dbg(fsp), (unsigned int)num_file_acls, (unsigned int)num_def_acls)); @@ -5959,7 +5963,7 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn, DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u," "lock_pid = %u, count = %.0f, offset = %.0f\n", - fsp->fsp_name, + fsp_str_dbg(fsp), (unsigned int)lock_type, (unsigned int)lock_pid, (double)count, @@ -7033,7 +7037,7 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, NULL); if (lck == NULL) { DEBUG(0, ("smb_posix_unlink: Could not get share mode " - "lock for file %s\n", fsp->fsp_name)); + "lock for file %s\n", fsp_str_dbg(fsp))); close_file(req, fsp, NORMAL_CLOSE); return NT_STATUS_INVALID_PARAMETER; } @@ -7370,14 +7374,8 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } info_level = SVAL(params,2); - fname = talloc_strdup(talloc_tos(),fsp->fsp_name); - if (!fname) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, - NULL, &smb_fname); + status = copy_smb_filename(talloc_tos(), fsp->fsp_name, + &smb_fname); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); return; @@ -7417,7 +7415,9 @@ static void call_trans2setfilepathinfo(connection_struct *conn, if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) { fsp->fh->private_options |= FILE_DELETE_ON_CLOSE; - DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name )); + DEBUG(3,("call_trans2setfilepathinfo: " + "Cancelling print job (%s)\n", + fsp_str_dbg(fsp))); SSVAL(params,0,0); send_trans2_replies(conn, req, params, 2, diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 2b4124bf7b..a2e3ec504c 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -487,10 +487,12 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len) * Actually try and commit the space on disk.... */ - DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", fsp->fsp_name, (double)len )); + DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", + fsp_str_dbg(fsp), (double)len)); if (((SMB_OFF_T)len) < 0) { - DEBUG(0,("vfs_allocate_file_space: %s negative len requested.\n", fsp->fsp_name )); + DEBUG(0,("vfs_allocate_file_space: %s negative len " + "requested.\n", fsp_str_dbg(fsp))); errno = EINVAL; return -1; } @@ -505,8 +507,9 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len) if (len < (uint64_t)st.st_ex_size) { /* Shrink - use ftruncate. */ - DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n", - fsp->fsp_name, (double)st.st_ex_size )); + DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current " + "size %.0f\n", fsp_str_dbg(fsp), + (double)st.st_ex_size)); contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK); @@ -530,13 +533,16 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len) len -= st.st_ex_size; len /= 1024; /* Len is now number of 1k blocks needed. */ - space_avail = get_dfree_info(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize); + space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false, + &bsize, &dfree, &dsize); if (space_avail == (uint64_t)-1) { return -1; } - DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n", - fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)space_avail )); + DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, " + "needed blocks = %.0f, space avail = %.0f\n", + fsp_str_dbg(fsp), (double)st.st_ex_size, (double)len, + (double)space_avail)); if (len > space_avail) { errno = ENOSPC; @@ -558,14 +564,15 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len) contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN); - DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len)); + DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", + fsp_str_dbg(fsp), (double)len)); flush_write_cache(fsp, SIZECHANGE_FLUSH); if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) { set_filelen_write_cache(fsp, len); notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_ATTRIBUTES, - fsp->fsp_name); + fsp->fsp_name->base_name); } contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN); @@ -600,8 +607,10 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) return 0; } - DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to len %.0f (%.0f bytes)\n", - fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)(len - st.st_ex_size))); + DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to " + "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp), + (double)st.st_ex_size, (double)len, + (double)(len - st.st_ex_size))); contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE); @@ -625,8 +634,9 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total); if (pwrite_ret == -1) { - DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file %s failed with error %s\n", - fsp->fsp_name, strerror(errno) )); + DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file " + "%s failed with error %s\n", + fsp_str_dbg(fsp), strerror(errno))); ret = -1; goto out; } -- cgit From c9b8a017147211d86662f40dcf835b152ab90cf4 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 18:11:32 -0700 Subject: s3: Finish plumbing the fsp->fsp_name smb_fname conversion through the modules. --- source3/modules/nfs4_acls.c | 34 +++++------ source3/modules/onefs_acl.c | 51 ++++++++-------- source3/modules/onefs_open.c | 18 +++--- source3/modules/onefs_streams.c | 10 ++- source3/modules/vfs_acl_tdb.c | 98 ++++++++++++++---------------- source3/modules/vfs_acl_xattr.c | 60 +++++++++++------- source3/modules/vfs_afsacl.c | 35 +++++++---- source3/modules/vfs_aixacl2.c | 16 ++--- source3/modules/vfs_audit.c | 4 +- source3/modules/vfs_cacheprime.c | 2 +- source3/modules/vfs_default.c | 4 +- source3/modules/vfs_extd_audit.c | 8 +-- source3/modules/vfs_full_audit.c | 93 ++++++++++++++++------------ source3/modules/vfs_gpfs.c | 33 +++++++--- source3/modules/vfs_hpuxacl.c | 20 +++--- source3/modules/vfs_hpuxacl.h | 2 +- source3/modules/vfs_shadow_copy2.c | 4 +- source3/modules/vfs_smb_traffic_analyzer.c | 18 +++--- source3/modules/vfs_streams_xattr.c | 25 +++----- source3/modules/vfs_tsmsm.c | 6 +- source3/modules/vfs_zfsacl.c | 11 ++-- source3/printing/printfsp.c | 10 ++- source3/torture/cmd_vfs.c | 13 ++-- 23 files changed, 312 insertions(+), 263 deletions(-) (limited to 'source3') diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 9b3c8725d5..748f17d457 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -183,7 +183,8 @@ static int smbacl4_fGetFileOwner(files_struct *fsp, SMB_STRUCT_STAT *psbuf) memset(psbuf, 0, sizeof(SMB_STRUCT_STAT)); if (fsp->is_directory || fsp->fh->fd == -1) { - return smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, psbuf); + return smbacl4_GetFileOwner(fsp->conn, + fsp->fsp_name->base_name, psbuf); } if (SMB_VFS_FSTAT(fsp, psbuf) != 0) { @@ -327,7 +328,7 @@ NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp, { SMB_STRUCT_STAT sbuf; - DEBUG(10, ("smb_fget_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name)); + DEBUG(10, ("smb_fget_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp))); if (smbacl4_fGetFileOwner(fsp, &sbuf)) { return map_nt_error_from_unix(errno); @@ -717,7 +718,7 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, gid_t newGID = (gid_t)-1; int saved_errno; - DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name)); + DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp))); if ((security_info_sent & (DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION)) == 0) @@ -743,26 +744,23 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, } if (((newUID != (uid_t)-1) && (sbuf.st_ex_uid != newUID)) || ((newGID != (gid_t)-1) && (sbuf.st_ex_gid != newGID))) { - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - status = create_synthetic_smb_fname_split(talloc_tos(), - fsp->fsp_name, NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - if(try_chown(fsp->conn, smb_fname, newUID, newGID)) { - DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, + if(try_chown(fsp->conn, fsp->fsp_name, newUID, + newGID)) { + DEBUG(3,("chown %s, %u, %u failed. Error = " + "%s.\n", fsp_str_dbg(fsp), + (unsigned int)newUID, + (unsigned int)newGID, strerror(errno))); - TALLOC_FREE(smb_fname); return map_nt_error_from_unix(errno); } - TALLOC_FREE(smb_fname); DEBUG(10,("chown %s, %u, %u succeeded.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID)); - if (smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, &sbuf)) + fsp_str_dbg(fsp), (unsigned int)newUID, + (unsigned int)newGID)); + if (smbacl4_GetFileOwner(fsp->conn, + fsp->fsp_name->base_name, + &sbuf)) return map_nt_error_from_unix(errno); /* If we successfully chowned, we know we must @@ -777,7 +775,7 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, return NT_STATUS_OK; } - theacl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, ¶ms, + theacl = smbacl4_win2nfs4(fsp->fsp_name->base_name, psd->dacl, ¶ms, sbuf.st_ex_uid, sbuf.st_ex_gid); if (!theacl) return map_nt_error_from_unix(errno); diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index 5c72d10a6b..2753a9e885 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -395,8 +395,8 @@ onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd) if ((sbuf.st_ex_flags & SF_HASNTFSACL) != 0) { DEBUG(10, ("Did not canonicalize ACLs because a " - "Windows ACL set was found for file %s\n", - fsp->fsp_name)); + "Windows ACL set was found for file %s\n", + fsp_str_dbg(fsp))); return true; } break; @@ -436,7 +436,7 @@ onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd) SMB_ASSERT(new_aces_count == sd->dacl->num_aces); DEBUG(10, ("Performed canonicalization of ACLs for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); /* * At this point you would think we could just do this: @@ -535,32 +535,21 @@ static bool add_sfs_aces(files_struct *fsp, struct ifs_security_descriptor *sd) if (error) { DEBUG(0, ("Failed to stat %s in simple files sharing " "compatibility mode. errno=%d\n", - fsp->fsp_name, errno)); + fsp_str_dbg(fsp), errno)); return false; } /* Only continue if this is a synthetic ACL and a directory. */ if (S_ISDIR(sbuf.st_ex_mode) && (sbuf.st_ex_flags & SF_HASNTFSACL) == 0) { - struct smb_filename *smb_fname = NULL; struct ifs_ace new_aces[6]; struct ifs_ace *old_aces; int i, num_aces_to_add = 0; mode_t file_mode = 0, dir_mode = 0; - NTSTATUS status; - - status = create_synthetic_smb_fname_split(talloc_tos(), - fsp->fsp_name, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return false; - } /* Use existing samba logic to derive the mode bits. */ - file_mode = unix_mode(fsp->conn, 0, smb_fname, NULL); - dir_mode = unix_mode(fsp->conn, aDIR, smb_fname, NULL); - - TALLOC_FREE(smb_fname); + file_mode = unix_mode(fsp->conn, 0, fsp->fsp_name, NULL); + dir_mode = unix_mode(fsp->conn, aDIR, fsp->fsp_name, NULL); /* Initialize ACEs. */ new_aces[0] = onefs_init_ace(fsp->conn, file_mode, false, USR); @@ -631,18 +620,18 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, *ppdesc = NULL; DEBUG(5, ("Getting sd for file %s. security_info=%u\n", - fsp->fsp_name, security_info)); + fsp_str_dbg(fsp), security_info)); if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE, PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) { - DEBUG(5, ("Ignoring SACL on %s.\n", fsp->fsp_name)); + DEBUG(5, ("Ignoring SACL on %s.\n", fsp_str_dbg(fsp))); security_info &= ~SACL_SECURITY_INFORMATION; } if (fsp->fh->fd == -1) { if ((fsp->fh->fd = onefs_sys_create_file(handle->conn, -1, - fsp->fsp_name, + fsp->fsp_name->base_name, 0, 0, 0, @@ -655,7 +644,7 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, 0, NULL)) == -1) { DEBUG(0, ("Error opening file %s. errno=%d (%s)\n", - fsp->fsp_name, errno, strerror(errno))); + fsp_str_dbg(fsp), errno, strerror(errno))); status = map_nt_error_from_unix(errno); goto out; } @@ -801,6 +790,7 @@ onefs_get_nt_acl(vfs_handle_struct *handle, const char* name, { files_struct finfo; struct fd_handle fh; + NTSTATUS status; ZERO_STRUCT(finfo); ZERO_STRUCT(fh); @@ -809,9 +799,16 @@ onefs_get_nt_acl(vfs_handle_struct *handle, const char* name, finfo.conn = handle->conn; finfo.fh = &fh; finfo.fh->fd = -1; - finfo.fsp_name = CONST_DISCARD(char *, name); + status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL, + &finfo.fsp_name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - return onefs_fget_nt_acl(handle, &finfo, security_info, ppdesc); + status = onefs_fget_nt_acl(handle, &finfo, security_info, ppdesc); + + TALLOC_FREE(finfo.fsp_name); + return status; } /** @@ -918,7 +915,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, START_PROFILE(syscall_set_sd); - DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name )); + DEBUG(5,("Setting SD on file %s.\n", fsp_str_dbg(fsp))); status = onefs_samba_sd_to_sd(sec_info_sent, psd, &sd, SNUM(handle->conn), &sec_info_effective); @@ -930,10 +927,10 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, fd = fsp->fh->fd; if (fd == -1) { - DEBUG(10,("Reopening file %s.\n", fsp->fsp_name)); + DEBUG(10,("Reopening file %s.\n", fsp_str_dbg(fsp))); if ((fd = onefs_sys_create_file(handle->conn, -1, - fsp->fsp_name, + fsp->fsp_name->base_name, 0, 0, 0, @@ -946,7 +943,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, 0, NULL)) == -1) { DEBUG(0, ("Error opening file %s. errno=%d (%s)\n", - fsp->fsp_name, errno, strerror(errno))); + fsp_str_dbg(fsp), errno, strerror(errno))); status = map_nt_error_from_unix(errno); goto out; } diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index b51d516956..31f27e907a 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -81,7 +81,6 @@ static NTSTATUS onefs_open_file(files_struct *fsp, struct security_descriptor *sd, int *granted_oplock) { - char *path = NULL; struct smb_filename *smb_fname_onefs = NULL; NTSTATUS status = NT_STATUS_OK; int accmode = (flags & O_ACCMODE); @@ -157,7 +156,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp, * wildcard characters are allowed in stream names * only test the basefilename */ - wild = fsp->base_fsp->fsp_name; + wild = fsp->base_fsp->fsp_name->base_name; } else { wild = smb_fname->base_name; } @@ -323,15 +322,13 @@ static NTSTATUS onefs_open_file(files_struct *fsp, fsp->aio_write_behind = True; } - status = get_full_smb_filename(talloc_tos(), smb_fname, - &path); + status = fsp_set_smb_fname(fsp, smb_fname); if (!NT_STATUS_IS_OK(status)) { + fd_close(fsp); + errno = map_errno_from_nt_status(status); return status; } - string_set(&fsp->fsp_name, path); - TALLOC_FREE(path); - fsp->wcp = NULL; /* Write cache pointer. */ DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n", @@ -1592,7 +1589,12 @@ static NTSTATUS onefs_open_directory(connection_struct *conn, fsp->is_directory = True; fsp->posix_open = posix_open; - string_set(&fsp->fsp_name, smb_dname->base_name); + status = fsp_set_smb_fname(fsp, smb_dname); + if (!NT_STATUS_IS_OK(status)) { + fd_close(fsp); + file_free(req, fsp); + return status; + } mtimespec = smb_dname->st.st_ex_mtime; diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index ded7dc672d..66eda57a34 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -376,7 +376,7 @@ int onefs_fstat(vfs_handle_struct *handle, struct files_struct *fsp, } } - onefs_adjust_stat_time(handle->conn, fsp->fsp_name, sbuf); + onefs_adjust_stat_time(handle->conn, fsp->fsp_name->base_name, sbuf); return ret; } @@ -600,7 +600,11 @@ static NTSTATUS walk_onefs_streams(connection_struct *conn, files_struct *fsp, fake_fs.conn = conn; fake_fs.fh = &fake_fh; - fake_fs.fsp_name = SMB_STRDUP(fname); + status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, NULL, + &fake_fs.fsp_name); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } /* Iterate over the streams in the ADS directory. */ while ((dp = SMB_VFS_READDIR(conn, dirp, NULL)) != NULL) { @@ -667,7 +671,7 @@ out: close(base_fd); } - SAFE_FREE(fake_fs.fsp_name); + TALLOC_FREE(fake_fs.fsp_name); return status; } diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 64ad3e1a78..ce84bd0e3a 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -272,27 +272,24 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, { uint8 id_buf[16]; struct file_id id; - SMB_STRUCT_STAT sbuf; TDB_DATA data; struct db_context *db; struct db_record *rec; int ret = -1; DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n", - (unsigned int)pblob->length, fsp->fsp_name)); + (unsigned int)pblob->length, fsp_str_dbg(fsp))); SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return NT_STATUS_INTERNAL_DB_CORRUPTION); if (fsp->fh->fd != -1) { - ret = SMB_VFS_FSTAT(fsp, &sbuf); + ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); } else { if (fsp->posix_open) { - ret = vfs_lstat_smb_fname(handle->conn, fsp->fsp_name, - &sbuf); + ret = SMB_VFS_LSTAT(handle->conn, fsp->fsp_name); } else { - ret = vfs_stat_smb_fname(handle->conn, fsp->fsp_name, - &sbuf); + ret = SMB_VFS_STAT(handle->conn, fsp->fsp_name); } } @@ -300,7 +297,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, return map_nt_error_from_unix(errno); } - id = vfs_file_id_from_sbuf(handle->conn, &sbuf); + id = vfs_file_id_from_sbuf(handle->conn, &fsp->fsp_name->st); /* For backwards compatibility only store the dev/inode. */ push_file_id_16((char *)id_buf, &id); @@ -381,7 +378,7 @@ static NTSTATUS get_nt_acl_tdb_internal(vfs_handle_struct *handle, NTSTATUS status; if (fsp && name == NULL) { - name = fsp->fsp_name; + name = fsp->fsp_name->base_name; } DEBUG(10, ("get_nt_acl_tdb_internal: name=%s\n", name)); @@ -450,7 +447,7 @@ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx, *********************************************************************/ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, - const char *fname, + struct smb_filename *smb_fname, files_struct *fsp, bool container) { @@ -462,7 +459,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, size_t size; char *parent_name; - if (!parent_dirname(ctx, fname, &parent_name, NULL)) { + if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) { return NT_STATUS_NO_MEMORY; } @@ -508,25 +505,22 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, } if (!psd || psd->dacl == NULL) { - SMB_STRUCT_STAT sbuf; int ret; TALLOC_FREE(psd); if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { - ret = SMB_VFS_FSTAT(fsp, &sbuf); + ret = SMB_VFS_FSTAT(fsp, &smb_fname->st); } else { if (fsp && fsp->posix_open) { - ret = vfs_lstat_smb_fname(handle->conn,fname, - &sbuf); + ret = SMB_VFS_LSTAT(handle->conn, smb_fname); } else { - ret = vfs_stat_smb_fname(handle->conn,fname, - &sbuf); + ret = SMB_VFS_STAT(handle->conn, smb_fname); } } if (ret == -1) { return map_nt_error_from_unix(errno); } - psd = default_file_sd(ctx, &sbuf); + psd = default_file_sd(ctx, &smb_fname->st); if (!psd) { return NT_STATUS_NO_MEMORY; } @@ -544,7 +538,8 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp) { return store_acl_blob_fsp(handle, fsp, &blob); } else { - return store_acl_blob_pathname(handle, fname, &blob); + return store_acl_blob_pathname(handle, smb_fname->base_name, + &blob); } } @@ -561,19 +556,11 @@ static int open_acl_tdb(vfs_handle_struct *handle, uint32_t access_granted = 0; struct security_descriptor *pdesc = NULL; bool file_existed = true; - char *fname = NULL; NTSTATUS status; - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; - } - status = get_nt_acl_tdb_internal(handle, NULL, - fname, + smb_fname->base_name, (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION), @@ -605,10 +592,13 @@ static int open_acl_tdb(vfs_handle_struct *handle, if (!file_existed && fsp->fh->fd != -1) { /* File was created. Inherit from parent directory. */ - string_set(&fsp->fsp_name, fname); - inherit_new_acl(handle, fname, fsp, false); + status = fsp_set_smb_fname(fsp, smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + inherit_new_acl(handle, smb_fname, fsp, false); } - return fsp->fh->fd; } @@ -659,13 +649,24 @@ static int unlink_acl_tdb(vfs_handle_struct *handle, static int mkdir_acl_tdb(vfs_handle_struct *handle, const char *path, mode_t mode) { + struct smb_filename *smb_fname = NULL; int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode); + NTSTATUS status; if (ret == -1) { return ret; } + + status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + /* New directory - inherit from parent. */ - inherit_new_acl(handle, path, NULL, true); + inherit_new_acl(handle, smb_fname, NULL, true); + TALLOC_FREE(smb_fname); return ret; } @@ -713,15 +714,14 @@ static NTSTATUS fget_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, if (NT_STATUS_IS_OK(status)) { if (DEBUGLEVEL >= 10) { DEBUG(10,("fget_nt_acl_tdb: returning tdb sd for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, *ppdesc); } return NT_STATUS_OK; } DEBUG(10,("fget_nt_acl_tdb: failed to get tdb sd for file %s, Error %s\n", - fsp->fsp_name, - nt_errstr(status) )); + fsp_str_dbg(fsp), nt_errstr(status))); return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc); @@ -765,7 +765,7 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_tdb: incoming sd for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, CONST_DISCARD(struct security_descriptor *,psd)); } @@ -778,7 +778,6 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, /* Ensure owner and group are set. */ if (!psd->owner_sid || !psd->group_sid) { int ret; - SMB_STRUCT_STAT sbuf; DOM_SID owner_sid, group_sid; struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd); @@ -787,23 +786,19 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, } if (fsp->is_directory || fsp->fh->fd == -1) { if (fsp->posix_open) { - ret = vfs_lstat_smb_fname(fsp->conn, - fsp->fsp_name, - &sbuf); + ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name); } else { - ret = vfs_stat_smb_fname(fsp->conn, - fsp->fsp_name, - &sbuf); + ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); } } else { - ret = SMB_VFS_FSTAT(fsp, &sbuf); + ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); } if (ret == -1) { /* Lower level acl set succeeded, * so still return OK. */ return NT_STATUS_OK; } - create_file_sids(&sbuf, &owner_sid, &group_sid); + create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid); /* This is safe as nc_psd is discarded at fn exit. */ nc_psd->owner_sid = &owner_sid; nc_psd->group_sid = &group_sid; @@ -831,7 +826,7 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_tdb: storing tdb sd for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, CONST_DISCARD(struct security_descriptor *,psd)); } @@ -913,7 +908,6 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl) { - SMB_STRUCT_STAT sbuf; struct db_context *db; int ret; @@ -921,14 +915,12 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle, if (fsp->is_directory || fsp->fh->fd == -1) { if (fsp->posix_open) { - ret = vfs_lstat_smb_fname(fsp->conn,fsp->fsp_name, - &sbuf); + ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name); } else { - ret = vfs_stat_smb_fname(fsp->conn,fsp->fsp_name, - &sbuf); + ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); } } else { - ret = SMB_VFS_FSTAT(fsp, &sbuf); + ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); } if (ret == -1) { return -1; @@ -941,7 +933,7 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle, return -1; } - acl_tdb_delete(handle, db, &sbuf); + acl_tdb_delete(handle, db, &fsp->fsp_name->st); return 0; } diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index eb6653bcd1..b18bc658ff 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -206,14 +206,14 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, int saved_errno = 0; DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n", - (unsigned int)pblob->length, fsp->fsp_name)); + (unsigned int)pblob->length, fsp_str_dbg(fsp))); become_root(); if (fsp->fh->fd != -1) { ret = SMB_VFS_FSETXATTR(fsp, XATTR_NTACL_NAME, pblob->data, pblob->length, 0); } else { - ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name, + ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name, XATTR_NTACL_NAME, pblob->data, pblob->length, 0); } @@ -225,7 +225,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, errno = saved_errno; DEBUG(5, ("store_acl_blob_fsp: setting attr failed for file %s" "with error %s\n", - fsp->fsp_name, + fsp_str_dbg(fsp), strerror(errno) )); return map_nt_error_from_unix(errno); } @@ -284,7 +284,7 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, struct security_descriptor *pdesc_next = NULL; if (fsp && name == NULL) { - name = fsp->fsp_name; + name = fsp->fsp_name->base_name; } DEBUG(10, ("get_nt_acl_xattr_internal: name=%s\n", name)); @@ -408,7 +408,7 @@ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx, *********************************************************************/ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, - const char *fname, + struct smb_filename *smb_fname, files_struct *fsp, bool container) { @@ -422,7 +422,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, char *parent_name; uint8_t hash[16]; - if (!parent_dirname(ctx, fname, &parent_name, NULL)) { + if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) { return NT_STATUS_NO_MEMORY; } @@ -468,23 +468,22 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, } if (!psd || psd->dacl == NULL) { - SMB_STRUCT_STAT sbuf; int ret; TALLOC_FREE(psd); if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { - ret = SMB_VFS_FSTAT(fsp, &sbuf); + ret = SMB_VFS_FSTAT(fsp, &smb_fname->st); } else { if (fsp && fsp->posix_open) { - ret = vfs_lstat_smb_fname(handle->conn,fname, &sbuf); + ret = SMB_VFS_LSTAT(handle->conn, smb_fname); } else { - ret = vfs_stat_smb_fname(handle->conn,fname, &sbuf); + ret = SMB_VFS_STAT(handle->conn, smb_fname); } } if (ret == -1) { return map_nt_error_from_unix(errno); } - psd = default_file_sd(ctx, &sbuf); + psd = default_file_sd(ctx, &smb_fname->st); if (!psd) { return NT_STATUS_NO_MEMORY; } @@ -503,7 +502,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, &pdesc_next); } else { status = SMB_VFS_NEXT_GET_NT_ACL(handle, - fname, + smb_fname->base_name, HASH_SECURITY_INFO, &pdesc_next); } @@ -523,7 +522,8 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp) { return store_acl_blob_fsp(handle, fsp, &blob); } else { - return store_acl_blob_pathname(handle, fname, &blob); + return store_acl_blob_pathname(handle, smb_fname->base_name, + &blob); } } @@ -591,8 +591,12 @@ static int open_acl_xattr(vfs_handle_struct *handle, if (!file_existed && fsp->fh->fd != -1) { /* File was created. Inherit from parent directory. */ - string_set(&fsp->fsp_name, fname); - inherit_new_acl(handle, fname, fsp, false); + status = fsp_set_smb_fname(fsp, smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + inherit_new_acl(handle, smb_fname, fsp, false); } return fsp->fh->fd; @@ -600,13 +604,24 @@ static int open_acl_xattr(vfs_handle_struct *handle, static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t mode) { + struct smb_filename *smb_fname = NULL; int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode); + NTSTATUS status; if (ret == -1) { return ret; } + + status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + /* New directory - inherit from parent. */ - inherit_new_acl(handle, path, NULL, true); + inherit_new_acl(handle, smb_fname, NULL, true); + TALLOC_FREE(smb_fname); return ret; } @@ -646,7 +661,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, CONST_DISCARD(struct security_descriptor *,psd)); } @@ -654,7 +669,6 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, /* Ensure owner and group are set. */ if (!psd->owner_sid || !psd->group_sid) { int ret; - SMB_STRUCT_STAT sbuf; DOM_SID owner_sid, group_sid; struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd); @@ -663,19 +677,19 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, } if (fsp->is_directory || fsp->fh->fd == -1) { if (fsp->posix_open) { - ret = vfs_lstat_smb_fname(fsp->conn,fsp->fsp_name, &sbuf); + ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name); } else { - ret = vfs_stat_smb_fname(fsp->conn,fsp->fsp_name, &sbuf); + ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); } } else { - ret = SMB_VFS_FSTAT(fsp, &sbuf); + ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); } if (ret == -1) { /* Lower level acl set succeeded, * so still return OK. */ return NT_STATUS_OK; } - create_file_sids(&sbuf, &owner_sid, &group_sid); + create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid); /* This is safe as nc_psd is discarded at fn exit. */ nc_psd->owner_sid = &owner_sid; nc_psd->group_sid = &group_sid; @@ -723,7 +737,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, CONST_DISCARD(struct security_descriptor *,psd)); } diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c index 55371c60f5..e6f43c9680 100644 --- a/source3/modules/vfs_afsacl.c +++ b/source3/modules/vfs_afsacl.c @@ -655,18 +655,17 @@ static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl, static size_t afs_to_nt_acl(struct afs_acl *afs_acl, struct connection_struct *conn, - const char *name, + struct smb_filename *smb_fname, uint32 security_info, struct security_descriptor **ppdesc) { - SMB_STRUCT_STAT sbuf; - /* Get the stat struct for the owner info. */ - if(vfs_stat_smb_fname(conn, name, &sbuf) != 0) { + if(SMB_VFS_STAT(conn, smb_fname) != 0) { return 0; } - return afs_to_nt_acl_common(afs_acl, &sbuf, security_info, ppdesc); + return afs_to_nt_acl_common(afs_acl, &smb_fname->st, security_info, + ppdesc); } static size_t afs_fto_nt_acl(struct afs_acl *afs_acl, @@ -905,7 +904,7 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, ZERO_STRUCT(dir_acl); ZERO_STRUCT(file_acl); - name = talloc_strdup(talloc_tos(), fsp->fsp_name); + name = talloc_strdup(talloc_tos(), fsp->fsp_name->base_name); if (!name) { return NT_STATUS_NO_MEMORY; } @@ -925,7 +924,7 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, } if (!afs_get_afs_acl(name, &old_afs_acl)) { - DEBUG(3, ("Could not get old ACL of %s\n", fsp->fsp_name)); + DEBUG(3, ("Could not get old ACL of %s\n", fsp_str_dbg(fsp))); goto done; } @@ -941,7 +940,8 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, } free_afs_acl(&dir_acl); - if (!nt_to_afs_acl(fsp->fsp_name, security_info_sent, psd, + if (!nt_to_afs_acl(fsp->fsp_name->base_name, + security_info_sent, psd, nt_to_afs_dir_rights, &dir_acl)) goto done; } else { @@ -956,7 +956,8 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, } free_afs_acl(&file_acl); - if (!nt_to_afs_acl(fsp->fsp_name, security_info_sent, psd, + if (!nt_to_afs_acl(fsp->fsp_name->base_name, + security_info_sent, psd, nt_to_afs_file_rights, &file_acl)) goto done; } @@ -997,11 +998,11 @@ static NTSTATUS afsacl_fget_nt_acl(struct vfs_handle_struct *handle, struct afs_acl acl; size_t sd_size; - DEBUG(5, ("afsacl_fget_nt_acl: %s\n", fsp->fsp_name)); + DEBUG(5, ("afsacl_fget_nt_acl: %s\n", fsp_str_dbg(fsp))); sidpts = lp_parm_bool(SNUM(fsp->conn), "afsacl", "sidpts", False); - if (!afs_get_afs_acl(fsp->fsp_name, &acl)) { + if (!afs_get_afs_acl(fsp->fsp_name->base_name, &acl)) { return NT_STATUS_ACCESS_DENIED; } @@ -1018,6 +1019,8 @@ static NTSTATUS afsacl_get_nt_acl(struct vfs_handle_struct *handle, { struct afs_acl acl; size_t sd_size; + struct smb_filename *smb_fname = NULL; + NTSTATUS status; DEBUG(5, ("afsacl_get_nt_acl: %s\n", name)); @@ -1027,8 +1030,16 @@ static NTSTATUS afsacl_get_nt_acl(struct vfs_handle_struct *handle, return NT_STATUS_ACCESS_DENIED; } - sd_size = afs_to_nt_acl(&acl, handle->conn, name, security_info, + status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + free_afs_acl(&acl); + return status; + } + + sd_size = afs_to_nt_acl(&acl, handle->conn, smb_fname, security_info, ppdesc); + TALLOC_FREE(smb_fname); free_afs_acl(&acl); diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c index 5ebc3a12f8..01de33ed0b 100644 --- a/source3/modules/vfs_aixacl2.c +++ b/source3/modules/vfs_aixacl2.c @@ -162,7 +162,8 @@ static NTSTATUS aixjfs2_fget_nt_acl(vfs_handle_struct *handle, bool retryPosix = False; *ppdesc = NULL; - result = aixjfs2_get_nfs4_acl(fsp->fsp_name, &pacl, &retryPosix); + result = aixjfs2_get_nfs4_acl(fsp->fsp_name->base_name, &pacl, + &retryPosix); if (retryPosix) { DEBUG(10, ("retrying with posix acl...\n")); @@ -258,7 +259,7 @@ SMB_ACL_T aixjfs2_sys_acl_get_fd(vfs_handle_struct *handle, acl_type_t aixjfs2_type; aixjfs2_type.u64 = ACL_AIXC; - return aixjfs2_get_posix_acl(fsp->fsp_name, aixjfs2_type); + return aixjfs2_get_posix_acl(fsp->fsp_name->base_name, aixjfs2_type); } /* @@ -304,7 +305,7 @@ static bool aixjfs2_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) int rc; acl_type_t acltype; - DEBUG(10, ("jfs2_process_smbacl invoked on %s\n", fsp->fsp_name)); + DEBUG(10, ("jfs2_process_smbacl invoked on %s\n", fsp_str_dbg(fsp))); /* no need to be freed which is alloced with mem_ctx */ mem_ctx = talloc_tos(); @@ -353,7 +354,7 @@ static bool aixjfs2_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) /* won't set S_ISUID - the only one JFS2/NFS4 accepts */ rc = aclx_put( - fsp->fsp_name, + fsp->fsp_name->base_name, SET_ACL, /* set only the ACL, not mode bits */ acltype, /* not a pointer !!! */ jfs2acl, @@ -444,9 +445,10 @@ int aixjfs2_sys_acl_set_fd(vfs_handle_struct *handle, acl_type_t acl_type_info; int rc; - DEBUG(10, ("aixjfs2_sys_acl_set_fd invoked for %s", fsp->fsp_name)); + DEBUG(10, ("aixjfs2_sys_acl_set_fd invoked for %s", fsp_str_dbg(fsp))); - rc = aixjfs2_query_acl_support(fsp->fsp_name, ACL_AIXC, &acl_type_info); + rc = aixjfs2_query_acl_support(fsp->fsp_name->base_name, ACL_AIXC, + &acl_type_info); if (rc) { DEBUG(8, ("jfs2_set_nt_acl: AIXC support not found\n")); return -1; @@ -466,7 +468,7 @@ int aixjfs2_sys_acl_set_fd(vfs_handle_struct *handle, ); if (rc) { DEBUG(2, ("aclx_fput failed with %s for %s\n", - strerror(errno), fsp->fsp_name)); + strerror(errno), fsp_str_dbg(fsp))); return -1; } diff --git a/source3/modules/vfs_audit.c b/source3/modules/vfs_audit.c index cf2e27301d..dab3d78cec 100644 --- a/source3/modules/vfs_audit.c +++ b/source3/modules/vfs_audit.c @@ -237,7 +237,7 @@ static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mod result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode); syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n", - fsp->fsp_name, mode, + fsp->fsp_name->base_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); @@ -251,7 +251,7 @@ static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode); syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n", - fsp->fsp_name, mode, + fsp->fsp_name->base_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); diff --git a/source3/modules/vfs_cacheprime.c b/source3/modules/vfs_cacheprime.c index 71b850505a..3997dcbcfc 100644 --- a/source3/modules/vfs_cacheprime.c +++ b/source3/modules/vfs_cacheprime.c @@ -72,7 +72,7 @@ static bool prime_cache( DEBUG(module_debug, ("%s: doing readahead of %lld bytes at %lld for %s\n", MODULE, (long long)g_readsz, (long long)*last, - fsp->fsp_name)); + fsp_str_dbg(fsp))); nread = sys_pread(fsp->fh->fd, g_readbuf, g_readsz, *last); if (nread < 0) { diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index bb7853b926..d6a66b01de 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -866,7 +866,9 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs uint64_t space_avail; uint64_t bsize,dfree,dsize; - space_avail = get_dfree_info(fsp->conn,fsp->fsp_name,false,&bsize,&dfree,&dsize); + space_avail = get_dfree_info(fsp->conn, + fsp->fsp_name->base_name, false, + &bsize, &dfree, &dsize); /* space_avail is 1k blocks */ if (space_avail == (uint64_t)-1 || ((uint64_t)space_to_write/1024 > space_avail) ) { diff --git a/source3/modules/vfs_extd_audit.c b/source3/modules/vfs_extd_audit.c index 68b85516ea..c9d1862fa4 100644 --- a/source3/modules/vfs_extd_audit.c +++ b/source3/modules/vfs_extd_audit.c @@ -304,12 +304,12 @@ static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mod if (lp_syslog() > 0) { syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n", - fsp->fsp_name, mode, + fsp->fsp_name->base_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); } DEBUG(1, ("vfs_extd_audit: fchmod %s mode 0x%x %s %s", - fsp->fsp_name, (unsigned int)mode, + fsp_str_dbg(fsp), (unsigned int)mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); @@ -324,12 +324,12 @@ static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t if (lp_syslog() > 0) { syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n", - fsp->fsp_name, mode, + fsp->fsp_name->base_name, mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); } DEBUG(1, ("vfs_extd_audit: fchmod_acl %s mode 0x%x %s %s", - fsp->fsp_name, (unsigned int)mode, + fsp_str_dbg(fsp), (unsigned int)mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index bf53ae269c..76fbc8a8ae 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -419,6 +419,13 @@ static const char *smb_fname_str_do_log(const struct smb_filename *smb_fname) return fname; } +/** + * Return an fsp debug string using the do_log_ctx() + */ +static const char *fsp_str_do_log(const struct files_struct *fsp) +{ + return smb_fname_str_do_log(fsp->fsp_name); +} /* Free function for the private data. */ @@ -736,7 +743,8 @@ static int smb_full_audit_close(vfs_handle_struct *handle, files_struct *fsp) result = SMB_VFS_NEXT_CLOSE(handle, fsp); - do_log(SMB_VFS_OP_CLOSE, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_CLOSE, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -748,7 +756,8 @@ static ssize_t smb_full_audit_read(vfs_handle_struct *handle, files_struct *fsp, result = SMB_VFS_NEXT_READ(handle, fsp, data, n); - do_log(SMB_VFS_OP_READ, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_READ, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -760,7 +769,8 @@ static ssize_t smb_full_audit_pread(vfs_handle_struct *handle, files_struct *fsp result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset); - do_log(SMB_VFS_OP_PREAD, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_PREAD, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -772,7 +782,8 @@ static ssize_t smb_full_audit_write(vfs_handle_struct *handle, files_struct *fsp result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n); - do_log(SMB_VFS_OP_WRITE, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_WRITE, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -785,7 +796,8 @@ static ssize_t smb_full_audit_pwrite(vfs_handle_struct *handle, files_struct *fs result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); - do_log(SMB_VFS_OP_PWRITE, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_PWRITE, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -798,7 +810,7 @@ static SMB_OFF_T smb_full_audit_lseek(vfs_handle_struct *handle, files_struct *f result = SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence); do_log(SMB_VFS_OP_LSEEK, (result != (ssize_t)-1), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -813,7 +825,7 @@ static ssize_t smb_full_audit_sendfile(vfs_handle_struct *handle, int tofd, result = SMB_VFS_NEXT_SENDFILE(handle, tofd, fromfsp, hdr, offset, n); do_log(SMB_VFS_OP_SENDFILE, (result >= 0), handle, - "%s", fromfsp->fsp_name); + "%s", fsp_str_do_log(fromfsp)); return result; } @@ -828,7 +840,7 @@ static ssize_t smb_full_audit_recvfile(vfs_handle_struct *handle, int fromfd, result = SMB_VFS_NEXT_RECVFILE(handle, fromfd, tofsp, offset, n); do_log(SMB_VFS_OP_RECVFILE, (result >= 0), handle, - "%s", tofsp->fsp_name); + "%s", fsp_str_do_log(tofsp)); return result; } @@ -854,7 +866,8 @@ static int smb_full_audit_fsync(vfs_handle_struct *handle, files_struct *fsp) result = SMB_VFS_NEXT_FSYNC(handle, fsp); - do_log(SMB_VFS_OP_FSYNC, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_FSYNC, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -879,7 +892,8 @@ static int smb_full_audit_fstat(vfs_handle_struct *handle, files_struct *fsp, result = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf); - do_log(SMB_VFS_OP_FSTAT, (result >= 0), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_FSTAT, (result >= 0), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -942,7 +956,7 @@ static int smb_full_audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode); do_log(SMB_VFS_OP_FCHMOD, (result >= 0), handle, - "%s|%o", fsp->fsp_name, mode); + "%s|%o", fsp_str_do_log(fsp), mode); return result; } @@ -968,7 +982,7 @@ static int smb_full_audit_fchown(vfs_handle_struct *handle, files_struct *fsp, result = SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid); do_log(SMB_VFS_OP_FCHOWN, (result >= 0), handle, "%s|%ld|%ld", - fsp->fsp_name, (long int)uid, (long int)gid); + fsp_str_do_log(fsp), (long int)uid, (long int)gid); return result; } @@ -1032,7 +1046,7 @@ static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp result = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, len); do_log(SMB_VFS_OP_FTRUNCATE, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1044,7 +1058,7 @@ static bool smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp, result = SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type); - do_log(SMB_VFS_OP_LOCK, result, handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_LOCK, result, handle, "%s", fsp_str_do_log(fsp)); return result; } @@ -1058,7 +1072,7 @@ static int smb_full_audit_kernel_flock(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, share_mode); do_log(SMB_VFS_OP_KERNEL_FLOCK, (result >= 0), handle, "%s", - fsp->fsp_name); + fsp_str_do_log(fsp)); return result; } @@ -1071,7 +1085,7 @@ static int smb_full_audit_linux_setlease(vfs_handle_struct *handle, files_struct result = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype); do_log(SMB_VFS_OP_LINUX_SETLEASE, (result >= 0), handle, "%s", - fsp->fsp_name); + fsp_str_do_log(fsp)); return result; } @@ -1083,7 +1097,7 @@ static bool smb_full_audit_getlock(vfs_handle_struct *handle, files_struct *fsp, result = SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid); - do_log(SMB_VFS_OP_GETLOCK, result, handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_GETLOCK, result, handle, "%s", fsp_str_do_log(fsp)); return result; } @@ -1256,7 +1270,7 @@ static NTSTATUS smb_full_audit_brl_lock_windows(struct vfs_handle_struct *handle blocking_lock, blr); do_log(SMB_VFS_OP_BRL_LOCK_WINDOWS, NT_STATUS_IS_OK(result), handle, - "%s:%llu-%llu. type=%d. blocking=%d", br_lck->fsp->fsp_name, + "%s:%llu-%llu. type=%d. blocking=%d", fsp_str_do_log(br_lck->fsp), plock->start, plock->size, plock->lock_type, blocking_lock ); return result; @@ -1273,7 +1287,7 @@ static bool smb_full_audit_brl_unlock_windows(struct vfs_handle_struct *handle, plock); do_log(SMB_VFS_OP_BRL_UNLOCK_WINDOWS, (result == 0), handle, - "%s:%llu-%llu:%d", br_lck->fsp->fsp_name, plock->start, + "%s:%llu-%llu:%d", fsp_str_do_log(br_lck->fsp), plock->start, plock->size, plock->lock_type); return result; @@ -1289,7 +1303,7 @@ static bool smb_full_audit_brl_cancel_windows(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_BRL_CANCEL_WINDOWS(handle, br_lck, plock, blr); do_log(SMB_VFS_OP_BRL_CANCEL_WINDOWS, (result == 0), handle, - "%s:%llu-%llu:%d", br_lck->fsp->fsp_name, plock->start, + "%s:%llu-%llu:%d", fsp_str_do_log(br_lck->fsp), plock->start, plock->size); return result; @@ -1304,7 +1318,7 @@ static bool smb_full_audit_strict_lock(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock); do_log(SMB_VFS_OP_STRICT_LOCK, result, handle, - "%s:%llu-%llu:%d", fsp->fsp_name, plock->start, + "%s:%llu-%llu:%d", fsp_str_do_log(fsp), plock->start, plock->size); return result; @@ -1317,7 +1331,7 @@ static void smb_full_audit_strict_unlock(struct vfs_handle_struct *handle, SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock); do_log(SMB_VFS_OP_STRICT_UNLOCK, true, handle, - "%s:%llu-%llu:%d", fsp->fsp_name, plock->start, + "%s:%llu-%llu:%d", fsp_str_do_log(fsp), plock->start, plock->size); return; @@ -1332,7 +1346,7 @@ static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_stru result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc); do_log(SMB_VFS_OP_FGET_NT_ACL, NT_STATUS_IS_OK(result), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1360,7 +1374,8 @@ static NTSTATUS smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_stru result = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); - do_log(SMB_VFS_OP_FSET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_FSET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", + fsp_str_do_log(fsp)); return result; } @@ -1386,7 +1401,7 @@ static int smb_full_audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fs result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode); do_log(SMB_VFS_OP_FCHMOD_ACL, (result >= 0), handle, - "%s|%o", fsp->fsp_name, mode); + "%s|%o", fsp_str_do_log(fsp), mode); return result; } @@ -1475,7 +1490,7 @@ static SMB_ACL_T smb_full_audit_sys_acl_get_fd(vfs_handle_struct *handle, result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp); do_log(SMB_VFS_OP_SYS_ACL_GET_FD, (result != NULL), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1635,7 +1650,7 @@ static int smb_full_audit_sys_acl_set_fd(vfs_handle_struct *handle, files_struct result = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl); do_log(SMB_VFS_OP_SYS_ACL_SET_FD, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1749,7 +1764,7 @@ static ssize_t smb_full_audit_fgetxattr(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size); do_log(SMB_VFS_OP_FGETXATTR, (result >= 0), handle, - "%s|%s", fsp->fsp_name, name); + "%s|%s", fsp_str_do_log(fsp), name); return result; } @@ -1787,7 +1802,7 @@ static ssize_t smb_full_audit_flistxattr(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size); do_log(SMB_VFS_OP_FLISTXATTR, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1829,7 +1844,7 @@ static int smb_full_audit_fremovexattr(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name); do_log(SMB_VFS_OP_FREMOVEXATTR, (result >= 0), handle, - "%s|%s", fsp->fsp_name, name); + "%s|%s", fsp_str_do_log(fsp), name); return result; } @@ -1875,7 +1890,7 @@ static int smb_full_audit_fsetxattr(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_FSETXATTR(handle, fsp, name, value, size, flags); do_log(SMB_VFS_OP_FSETXATTR, (result >= 0), handle, - "%s|%s", fsp->fsp_name, name); + "%s|%s", fsp_str_do_log(fsp), name); return result; } @@ -1886,7 +1901,7 @@ static int smb_full_audit_aio_read(struct vfs_handle_struct *handle, struct file result = SMB_VFS_NEXT_AIO_READ(handle, fsp, aiocb); do_log(SMB_VFS_OP_AIO_READ, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1897,7 +1912,7 @@ static int smb_full_audit_aio_write(struct vfs_handle_struct *handle, struct fil result = SMB_VFS_NEXT_AIO_WRITE(handle, fsp, aiocb); do_log(SMB_VFS_OP_AIO_WRITE, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1908,7 +1923,7 @@ static ssize_t smb_full_audit_aio_return(struct vfs_handle_struct *handle, struc result = SMB_VFS_NEXT_AIO_RETURN(handle, fsp, aiocb); do_log(SMB_VFS_OP_AIO_RETURN, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1919,7 +1934,7 @@ static int smb_full_audit_aio_cancel(struct vfs_handle_struct *handle, struct fi result = SMB_VFS_NEXT_AIO_CANCEL(handle, fsp, aiocb); do_log(SMB_VFS_OP_AIO_CANCEL, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1930,7 +1945,7 @@ static int smb_full_audit_aio_error(struct vfs_handle_struct *handle, struct fil result = SMB_VFS_NEXT_AIO_ERROR(handle, fsp, aiocb); do_log(SMB_VFS_OP_AIO_ERROR, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1941,7 +1956,7 @@ static int smb_full_audit_aio_fsync(struct vfs_handle_struct *handle, struct fil result = SMB_VFS_NEXT_AIO_FSYNC(handle, fsp, op, aiocb); do_log(SMB_VFS_OP_AIO_FSYNC, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1952,7 +1967,7 @@ static int smb_full_audit_aio_suspend(struct vfs_handle_struct *handle, struct f result = SMB_VFS_NEXT_AIO_SUSPEND(handle, fsp, aiocb, n, ts); do_log(SMB_VFS_OP_AIO_SUSPEND, (result >= 0), handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } @@ -1964,7 +1979,7 @@ static bool smb_full_audit_aio_force(struct vfs_handle_struct *handle, result = SMB_VFS_NEXT_AIO_FORCE(handle, fsp); do_log(SMB_VFS_OP_AIO_FORCE, result, handle, - "%s", fsp->fsp_name); + "%s", fsp_str_do_log(fsp)); return result; } diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index ffa8db00b3..cde80f0021 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -303,7 +303,7 @@ static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle, int result; *ppdesc = NULL; - result = gpfs_get_nfs4_acl(fsp->fsp_name, &pacl); + result = gpfs_get_nfs4_acl(fsp->fsp_name->base_name, &pacl); if (result == 0) return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc, pacl); @@ -389,7 +389,7 @@ static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) "merge_writeappend", True)) { DEBUG(2, ("vfs_gpfs.c: file [%s]: ACE contains " "WRITE^APPEND, setting WRITE|APPEND\n", - fsp->fsp_name)); + fsp_str_dbg(fsp))); gace->aceMask |= ACE4_MASK_WRITE|ACE4_MASK_APPEND; } @@ -423,7 +423,8 @@ static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) gacl->acl_nace++; } - ret = smbd_gpfs_putacl(fsp->fsp_name, GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gacl); + ret = smbd_gpfs_putacl(fsp->fsp_name->base_name, + GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gacl); if (ret != 0) { DEBUG(8, ("gpfs_putacl failed with %s\n", strerror(errno))); gpfs_dumpacl(8, gacl); @@ -439,7 +440,7 @@ static NTSTATUS gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_i struct gpfs_acl *acl; NTSTATUS result = NT_STATUS_ACCESS_DENIED; - acl = gpfs_getacl_alloc(fsp->fsp_name, 0); + acl = gpfs_getacl_alloc(fsp->fsp_name->base_name, 0); if (acl == NULL) return result; @@ -594,7 +595,8 @@ static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle, static SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) { - return gpfsacl_get_posix_acl(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS); + return gpfsacl_get_posix_acl(fsp->fsp_name->base_name, + GPFS_ACL_TYPE_ACCESS); } static struct gpfs_acl *smb2gpfs_acl(const SMB_ACL_T pacl, @@ -707,7 +709,8 @@ static int gpfsacl_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl) { - return gpfsacl_sys_acl_set_file(handle, fsp->fsp_name, SMB_ACL_TYPE_ACCESS, theacl); + return gpfsacl_sys_acl_set_file(handle, fsp->fsp_name->base_name, + SMB_ACL_TYPE_ACCESS, theacl); } static int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle, @@ -764,6 +767,8 @@ static int gpfsacl_emu_chmod(const char *path, mode_t mode) int i; files_struct fake_fsp; /* TODO: rationalize parametrization */ SMB4ACE_T *smbace; + struct smb_filename *smb_fname = NULL; + NTSTATUS status; DEBUG(10, ("gpfsacl_emu_chmod invoked for %s mode %o\n", path, mode)); @@ -833,11 +838,19 @@ static int gpfsacl_emu_chmod(const char *path, mode_t mode) /* don't add complementary DENY ACEs here */ ZERO_STRUCT(fake_fsp); - fake_fsp.fsp_name = (char *)path; /* no file_new is needed here */ - + status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL, + &fake_fsp.fsp_name); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } /* put the acl */ - if (gpfsacl_process_smbacl(&fake_fsp, pacl) == False) + if (gpfsacl_process_smbacl(&fake_fsp, pacl) == False) { + TALLOC_FREE(fake_fsp.fsp_name); return -1; + } + + TALLOC_FREE(fake_fsp.fsp_name); return 0; /* ok for [f]chmod */ } @@ -875,7 +888,7 @@ static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t return 0; } - rc = gpfsacl_emu_chmod(fsp->fsp_name, mode); + rc = gpfsacl_emu_chmod(fsp->fsp_name->base_name, mode); if (rc == 1) return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode); return rc; diff --git a/source3/modules/vfs_hpuxacl.c b/source3/modules/vfs_hpuxacl.c index 35341a5c3e..32e8539202 100644 --- a/source3/modules/vfs_hpuxacl.c +++ b/source3/modules/vfs_hpuxacl.c @@ -201,23 +201,23 @@ SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle, DEBUG(10, ("redirecting call of hpuxacl_sys_acl_get_fd to " "hpuxacl_sys_acl_get_file (no facl syscall on HPUX).\n")); - return hpuxacl_sys_acl_get_file(handle, file_struct_p->fsp_name, - SMB_ACL_TYPE_ACCESS); + return hpuxacl_sys_acl_get_file(handle, + file_struct_p->fsp_name->base_name, + SMB_ACL_TYPE_ACCESS); } int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle, - const char *name, + struct smb_filename *smb_fname, SMB_ACL_TYPE_T type, SMB_ACL_T theacl) { int ret = -1; - SMB_STRUCT_STAT s; HPUX_ACL_T hpux_acl = NULL; int count; DEBUG(10, ("hpuxacl_sys_acl_set_file called for file '%s'\n", - name)); + smb_fname_str_dbg(smb_fname))); if(hpux_acl_call_present() == False) { @@ -248,11 +248,11 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle, * that has _not_ been specified in "type" from the file first * and concatenate it with the acl provided. */ - if (vfs_stat_smb_fname(handle->conn, name, &s) != 0) { + if (SMB_VFS_STAT(handle->conn, smb_fname) != 0) { DEBUG(10, ("Error in stat call: %s\n", strerror(errno))); goto done; } - if (S_ISDIR(s.st_ex_mode)) { + if (S_ISDIR(smb_fname->st.st_ex_mode)) { HPUX_ACL_T other_acl; int other_count; SMB_ACL_TYPE_T other_type; @@ -261,7 +261,8 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle, ? SMB_ACL_TYPE_DEFAULT : SMB_ACL_TYPE_ACCESS; DEBUGADD(10, ("getting acl from filesystem\n")); - if (!hpux_acl_get_file(name, &other_acl, &other_count)) { + if (!hpux_acl_get_file(smb_fname->base_name, &other_acl, + &other_count)) { DEBUG(10, ("error getting acl from directory\n")); goto done; } @@ -289,7 +290,8 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle, } DEBUG(10, ("resulting acl is valid.\n")); - ret = acl(CONST_DISCARD(char *, name), ACL_SET, count, hpux_acl); + ret = acl(CONST_DISCARD(char *, smb_fname->base_name), ACL_SET, count, + hpux_acl); if (ret != 0) { DEBUG(0, ("ERROR calling acl: %s\n", strerror(errno))); } diff --git a/source3/modules/vfs_hpuxacl.h b/source3/modules/vfs_hpuxacl.h index 07b32d628c..9baed5790a 100644 --- a/source3/modules/vfs_hpuxacl.h +++ b/source3/modules/vfs_hpuxacl.h @@ -41,7 +41,7 @@ SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp); int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle, - const char *name, + struct smb_filename *smb_fname, SMB_ACL_TYPE_T type, SMB_ACL_T theacl); diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 29247ac7c2..7c338e7268 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -406,8 +406,8 @@ static int shadow_copy2_lstat(vfs_handle_struct *handle, static int shadow_copy2_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf) { int ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf); - if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name)) { - convert_sbuf(handle, fsp->fsp_name, sbuf); + if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name->base_name)) { + convert_sbuf(handle, fsp->fsp_name->base_name, sbuf); } return ret; } diff --git a/source3/modules/vfs_smb_traffic_analyzer.c b/source3/modules/vfs_smb_traffic_analyzer.c index a7fbeadbbe..6f7aee0e50 100644 --- a/source3/modules/vfs_smb_traffic_analyzer.c +++ b/source3/modules/vfs_smb_traffic_analyzer.c @@ -336,11 +336,11 @@ static ssize_t smb_traffic_analyzer_read(vfs_handle_struct *handle, \ ssize_t result; result = SMB_VFS_NEXT_READ(handle, fsp, data, n); - DEBUG(10, ("smb_traffic_analyzer_read: READ: %s\n", fsp->fsp_name )); + DEBUG(10, ("smb_traffic_analyzer_read: READ: %s\n", fsp_str_dbg(fsp))); smb_traffic_analyzer_send_data(handle, result, - fsp->fsp_name, + fsp->fsp_name->base_name, false); return result; } @@ -353,11 +353,12 @@ static ssize_t smb_traffic_analyzer_pread(vfs_handle_struct *handle, \ result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset); - DEBUG(10, ("smb_traffic_analyzer_pread: PREAD: %s\n", fsp->fsp_name )); + DEBUG(10, ("smb_traffic_analyzer_pread: PREAD: %s\n", + fsp_str_dbg(fsp))); smb_traffic_analyzer_send_data(handle, result, - fsp->fsp_name, + fsp->fsp_name->base_name, false); return result; @@ -370,11 +371,12 @@ static ssize_t smb_traffic_analyzer_write(vfs_handle_struct *handle, \ result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n); - DEBUG(10, ("smb_traffic_analyzer_write: WRITE: %s\n", fsp->fsp_name )); + DEBUG(10, ("smb_traffic_analyzer_write: WRITE: %s\n", + fsp_str_dbg(fsp))); smb_traffic_analyzer_send_data(handle, result, - fsp->fsp_name, + fsp->fsp_name->base_name, true); return result; } @@ -386,11 +388,11 @@ static ssize_t smb_traffic_analyzer_pwrite(vfs_handle_struct *handle, \ result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); - DEBUG(10, ("smb_traffic_analyzer_pwrite: PWRITE: %s\n", fsp->fsp_name )); + DEBUG(10, ("smb_traffic_analyzer_pwrite: PWRITE: %s\n", fsp_str_dbg(fsp))); smb_traffic_analyzer_send_data(handle, result, - fsp->fsp_name, + fsp->fsp_name->base_name, true); return result; } diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index eccc2379c9..c32c4f3190 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -128,27 +128,20 @@ static NTSTATUS streams_xattr_get_name(TALLOC_CTX *ctx, static bool streams_xattr_recheck(struct stream_io *sio) { NTSTATUS status; - struct smb_filename *smb_fname = NULL; char *xattr_name = NULL; if (sio->fsp->fsp_name == sio->fsp_name_ptr) { return true; } - status = create_synthetic_smb_fname_split(talloc_tos(), - sio->fsp->fsp_name, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return false; - } - - if (smb_fname->stream_name == NULL) { + if (sio->fsp->fsp_name->stream_name == NULL) { /* how can this happen */ errno = EINVAL; return false; } - status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name, + status = streams_xattr_get_name(talloc_tos(), + sio->fsp->fsp_name->stream_name, &xattr_name); if (!NT_STATUS_IS_OK(status)) { return false; @@ -159,10 +152,9 @@ static bool streams_xattr_recheck(struct stream_io *sio) sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp), xattr_name); sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp), - smb_fname->base_name); + sio->fsp->fsp_name->base_name); sio->fsp_name_ptr = sio->fsp->fsp_name; - TALLOC_FREE(smb_fname); TALLOC_FREE(xattr_name); if ((sio->xattr_name == NULL) || (sio->base == NULL)) { @@ -899,7 +891,8 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle, sio->xattr_name, ea.value.data, ea.value.length, 0); } else { - ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name, + ret = SMB_VFS_SETXATTR(fsp->conn, + fsp->base_fsp->fsp_name->base_name, sio->xattr_name, ea.value.data, ea.value.length, 0); } @@ -963,8 +956,7 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle, (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); DEBUG(10, ("streams_xattr_ftruncate called for file %s offset %.0f\n", - fsp->fsp_name, - (double)offset )); + fsp_str_dbg(fsp), (double)offset)); if (sio == NULL) { return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset); @@ -1004,7 +996,8 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle, sio->xattr_name, ea.value.data, ea.value.length, 0); } else { - ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name, + ret = SMB_VFS_SETXATTR(fsp->conn, + fsp->base_fsp->fsp_name->base_name, sio->xattr_name, ea.value.data, ea.value.length, 0); } diff --git a/source3/modules/vfs_tsmsm.c b/source3/modules/vfs_tsmsm.c index 57807105f6..753b2bcd26 100644 --- a/source3/modules/vfs_tsmsm.c +++ b/source3/modules/vfs_tsmsm.c @@ -273,7 +273,7 @@ static ssize_t tsmsm_aio_return(struct vfs_handle_struct *handle, struct files_s if(result >= 0) { notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, - fsp->fsp_name); + fsp->fsp_name->base_name); } return result; @@ -307,7 +307,7 @@ static ssize_t tsmsm_pread(struct vfs_handle_struct *handle, struct files_struct */ notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, - fsp->fsp_name); + fsp->fsp_name->base_name); } return result; @@ -325,7 +325,7 @@ static ssize_t tsmsm_pwrite(struct vfs_handle_struct *handle, struct files_struc */ notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, - fsp->fsp_name); + fsp->fsp_name->base_name); } return result; diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c index a5b0490c8d..a92d5dae26 100644 --- a/source3/modules/vfs_zfsacl.c +++ b/source3/modules/vfs_zfsacl.c @@ -145,14 +145,14 @@ static bool zfs_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) SMB_ASSERT(i == naces); /* store acl */ - if(acl(fsp->fsp_name, ACE_SETACL, naces, acebuf)) { + if(acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf)) { if(errno == ENOSYS) { DEBUG(9, ("acl(ACE_SETACL, %s): Operation is not " "supported on the filesystem where the file " - "reside", fsp->fsp_name)); + "reside", fsp_str_dbg(fsp))); } else { - DEBUG(9, ("acl(ACE_SETACL, %s): %s ", fsp->fsp_name, - strerror(errno))); + DEBUG(9, ("acl(ACE_SETACL, %s): %s ", fsp_str_dbg(fsp), + strerror(errno))); } return 0; } @@ -180,7 +180,8 @@ static NTSTATUS zfsacl_fget_nt_acl(struct vfs_handle_struct *handle, SMB4ACL_T *pacl; NTSTATUS status; - status = zfs_get_nt_acl_common(fsp->fsp_name, security_info, &pacl); + status = zfs_get_nt_acl_common(fsp->fsp_name->base_name, security_info, + &pacl); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c index a8e175a684..9185fc84b1 100644 --- a/source3/printing/printfsp.c +++ b/source3/printing/printfsp.c @@ -58,6 +58,13 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn, return NT_STATUS_ACCESS_DENIED; /* No errno around here */ } + status = create_synthetic_smb_fname(fsp, + print_job_fname(lp_const_servicename(SNUM(conn)), jobid), NULL, + NULL, &fsp->fsp_name); + if (!NT_STATUS_IS_OK(status)) { + pjob_delete(lp_const_servicename(SNUM(conn)), jobid); + return status; + } /* setup a full fsp */ fsp->fh->fd = print_job_fd(lp_const_servicename(SNUM(conn)),jobid); GetTimeOfDay(&fsp->open_time); @@ -72,7 +79,6 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn, fsp->oplock_type = NO_OPLOCK; fsp->sent_oplock_break = NO_BREAK_SENT; fsp->is_directory = False; - string_set(&fsp->fsp_name,print_job_fname(lp_const_servicename(SNUM(conn)),jobid)); fsp->wcp = NULL; SMB_VFS_FSTAT(fsp, psbuf); fsp->mode = psbuf->st_ex_mode; @@ -98,7 +104,7 @@ void print_fsp_end(files_struct *fsp, enum file_close_type close_type) } if (fsp->fsp_name) { - string_free(&fsp->fsp_name); + TALLOC_FREE(fsp->fsp_name); } if (!rap_to_pjobid(fsp->rap_print_jobid, NULL, &jobid)) { diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index 33ced8fa54..cd550a4f48 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -317,11 +317,6 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c if (fsp == NULL) { return NT_STATUS_NO_MEMORY; } - fsp->fsp_name = SMB_STRDUP(argv[1]); - if (fsp->fsp_name == NULL) { - SAFE_FREE(fsp); - return NT_STATUS_NO_MEMORY; - } fsp->fh = SMB_MALLOC_P(struct fd_handle); if (fsp->fh == NULL) { SAFE_FREE(fsp->fsp_name); @@ -333,18 +328,18 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c status = create_synthetic_smb_fname_split(mem_ctx, argv[1], NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { - SAFE_FREE(fsp->fsp_name); SAFE_FREE(fsp); return status; } + fsp->fsp_name = smb_fname; + fsp->fh->fd = SMB_VFS_OPEN(vfs->conn, smb_fname, fsp, flags, mode); - TALLOC_FREE(smb_fname); if (fsp->fh->fd == -1) { printf("open: error=%d (%s)\n", errno, strerror(errno)); SAFE_FREE(fsp->fh); - SAFE_FREE(fsp->fsp_name); SAFE_FREE(fsp); + TALLOC_FREE(smb_fname); return NT_STATUS_UNSUCCESSFUL; } @@ -415,7 +410,7 @@ static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, else printf("close: ok\n"); - SAFE_FREE(vfs->files[fd]->fsp_name); + TALLOC_FREE(vfs->files[fd]->fsp_name); SAFE_FREE(vfs->files[fd]->fh); SAFE_FREE(vfs->files[fd]); vfs->files[fd] = NULL; -- cgit From 82c3f505fe2e50022b5102e6388dc3b830d235da Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 15:10:35 -0700 Subject: s3: Move is_ntfs_stream*() to filename.c --- source3/include/proto.h | 4 ++-- source3/smbd/filename.c | 24 ++++++++++++++++++++++++ source3/smbd/nttrans.c | 24 ------------------------ 3 files changed, 26 insertions(+), 26 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 830d2284c4..cdc58437f0 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6325,6 +6325,8 @@ const char *smb_fname_str_dbg(const struct smb_filename *smb_fname); NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname_in, struct smb_filename **smb_fname_out); +bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname); +bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname); NTSTATUS unix_convert(TALLOC_CTX *ctx, connection_struct *conn, const char *orig_path, @@ -6548,8 +6550,6 @@ void send_nt_replies(connection_struct *conn, struct smb_request *req, NTSTATUS nt_error, char *params, int paramsize, char *pdata, int datasize); -bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname); -bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname); void reply_ntcreate_and_X(struct smb_request *req); void reply_ntcancel(struct smb_request *req); void reply_ntrename(struct smb_request *req); diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 29ebc37d1a..1eb6ce5065 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -275,6 +275,30 @@ NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, return NT_STATUS_NO_MEMORY; } +/**************************************************************************** + Simple check to determine if the filename is a stream. + ***************************************************************************/ +bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) +{ + if (lp_posix_pathnames()) { + return false; + } + + return smb_fname->stream_name; +} + +/**************************************************************************** + Returns true if the filename's stream == "::$DATA" + ***************************************************************************/ +bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname) +{ + if (!is_ntfs_stream_smb_fname(smb_fname)) { + return false; + } + + return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0; +} + /**************************************************************************** This routine is called to convert names from the dos namespace to unix namespace. It needs to handle any case conversions, mangling, format changes, diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index ff76b7a21f..ecb88296ca 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -271,30 +271,6 @@ void send_nt_replies(connection_struct *conn, } } -/**************************************************************************** - Simple check to determine if the filename is a stream. - ***************************************************************************/ -bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) -{ - if (lp_posix_pathnames()) { - return false; - } - - return smb_fname->stream_name; -} - -/**************************************************************************** - Returns true if the filename's stream == "::$DATA" - ***************************************************************************/ -bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname) -{ - if (!is_ntfs_stream_smb_fname(smb_fname)) { - return false; - } - - return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0; -} - /**************************************************************************** Reply to an NT create and X call on a pipe ****************************************************************************/ -- cgit From 841efce8b5e931a7ec910afb7d0d8b6a123c6900 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 15:35:08 -0700 Subject: s3: Separate out a new file: filename_utils.c This is to ease the linking pain of everything that links LOCKING_OBJ --- source3/Makefile.in | 14 +-- source3/include/proto.h | 43 +++++---- source3/smbd/filename.c | 219 ------------------------------------------- source3/smbd/filename_util.c | 194 ++++++++++++++++++++++++++++++++++++++ source3/smbd/files.c | 9 -- source3/smbd/vfs.c | 55 +++++++++++ 6 files changed, 280 insertions(+), 254 deletions(-) create mode 100644 source3/smbd/filename_util.c (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index f6396ef157..e6d0cf00dd 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -667,6 +667,8 @@ OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o \ NOTIFY_OBJ = smbd/notify.o smbd/notify_inotify.o smbd/notify_internal.o +FNAME_UTIL_OBJ = smbd/filename_util.o + VFS_DEFAULT_OBJ = modules/vfs_default.o VFS_AUDIT_OBJ = modules/vfs_audit.o VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o @@ -786,7 +788,7 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) \ $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \ $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \ - $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \ + $(NOTIFY_OBJ) $(FNAME_UTIL_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \ $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(AVAHI_OBJ) \ $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \ $(REG_FULL_OBJ) $(POPT_LIB_OBJ) $(BUILDOPT_OBJ) \ @@ -828,16 +830,16 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(PRINTBASE_OBJ) $(LIBSMB_O $(LOCKING_OBJ) $(PASSDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \ $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_GEN_OBJ) $(LIBMSRPC_OBJ) \ - $(PASSCHANGE_OBJ) $(LDB_OBJ) + $(PASSCHANGE_OBJ) $(LDB_OBJ) $(FNAME_UTIL_OBJ) STATUS_OBJ = utils/status.o utils/status_profile.o \ $(LOCKING_OBJ) $(PARAM_OBJ) \ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ - $(LIBSAMBA_OBJ) + $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ) SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ - $(LIBSAMBA_OBJ) \ + $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ) \ $(PRINTBASE_OBJ) SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \ @@ -1033,7 +1035,7 @@ MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIEN LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \ $(LIBSMB_OBJ) $(LDB_OBJ) $(LIB_NONSMBD_OBJ) \ - $(LIBNDR_GEN_OBJ0) + $(LIBNDR_GEN_OBJ0) $(FNAME_UTIL_OBJ) NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIB_NONSMBD_OBJ) \ @@ -1052,7 +1054,7 @@ LOG2PCAP_OBJ = utils/log2pcaphex.o LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \ - $(LIBNDR_GEN_OBJ0) + $(LIBNDR_GEN_OBJ0) $(FNAME_UTIL_OBJ) SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \ diff --git a/source3/include/proto.h b/source3/include/proto.h index cdc58437f0..c26f2a7c3a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6307,6 +6307,24 @@ int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst); /* The following definitions come from smbd/filename.c */ +NTSTATUS unix_convert(TALLOC_CTX *ctx, + connection_struct *conn, + const char *orig_path, + struct smb_filename **smb_fname, + uint32_t ucf_flags); +NTSTATUS check_name(connection_struct *conn, const char *name); +int get_real_filename(connection_struct *conn, const char *path, + const char *name, TALLOC_CTX *mem_ctx, + char **found_name); +NTSTATUS filename_convert(TALLOC_CTX *mem_ctx, + connection_struct *conn, + bool dfs_path, + const char *name_in, + struct smb_filename **pp_smb_fname, + char **pp_name); + +/* The following definitions come from smbd/filename_utils.c */ + NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname, char **full_name); NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name, @@ -6317,31 +6335,13 @@ NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx, const char *fname, const SMB_STRUCT_STAT *psbuf, struct smb_filename **smb_fname_out); -int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf); -int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf); const char *smb_fname_str_dbg(const struct smb_filename *smb_fname); +const char *fsp_str_dbg(const struct files_struct *fsp); NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname_in, struct smb_filename **smb_fname_out); bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname); bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname); -NTSTATUS unix_convert(TALLOC_CTX *ctx, - connection_struct *conn, - const char *orig_path, - struct smb_filename **smb_fname, - uint32_t ucf_flags); -NTSTATUS check_name(connection_struct *conn, const char *name); -int get_real_filename(connection_struct *conn, const char *path, - const char *name, TALLOC_CTX *mem_ctx, - char **found_name); -NTSTATUS filename_convert(TALLOC_CTX *mem_ctx, - connection_struct *conn, - bool dfs_path, - const char *name_in, - struct smb_filename **pp_smb_fname, - char **pp_name); /* The following definitions come from smbd/files.c */ @@ -6370,7 +6370,6 @@ files_struct *file_fsp(struct smb_request *req, uint16 fid); NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from, uint32 access_mask, uint32 share_access, uint32 create_options, files_struct *to); -const char *fsp_str_dbg(const struct files_struct *fsp); NTSTATUS fsp_set_smb_fname(struct files_struct *fsp, const struct smb_filename *smb_fname_in); @@ -7117,6 +7116,10 @@ char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf); int vfs_ChDir(connection_struct *conn, const char *path); char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn); NTSTATUS check_reduced_name(connection_struct *conn, const char *fname); +int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf); +int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf); /* The following definitions come from torture/denytest.c */ diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 1eb6ce5065..c05f0e659f 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -80,225 +80,6 @@ static NTSTATUS determine_path_error(const char *name, } } -/** - * XXX: This is temporary and there should be no callers of this outside of - * this file once smb_filename is plumbed through all path based operations. - * The one legitimate caller currently is smb_fname_str_dbg(), which this - * could be made static for. - */ -NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname, - char **full_name) -{ - if (smb_fname->stream_name) { - *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name, - smb_fname->stream_name); - } else { - *full_name = talloc_strdup(ctx, smb_fname->base_name); - } - - if (!*full_name) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - -/** - * There are actually legitimate callers of this such as functions that - * enumerate streams using the SMB_VFS_STREAMINFO interface and then want to - * operate on each stream. - */ -NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name, - const char *stream_name, - const SMB_STRUCT_STAT *psbuf, - struct smb_filename **smb_fname_out) -{ - struct smb_filename smb_fname_loc; - - ZERO_STRUCT(smb_fname_loc); - - /* Setup the base_name/stream_name. */ - smb_fname_loc.base_name = CONST_DISCARD(char *, base_name); - smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name); - - /* Copy the psbuf if one was given. */ - if (psbuf) - smb_fname_loc.st = *psbuf; - - /* Let copy_smb_filename() do the heavy lifting. */ - return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out); -} - -/** - * XXX: This is temporary and there should be no callers of this once - * smb_filename is plumbed through all path based operations. - */ -NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx, - const char *fname, - const SMB_STRUCT_STAT *psbuf, - struct smb_filename **smb_fname_out) -{ - NTSTATUS status; - const char *stream_name = NULL; - char *base_name = NULL; - - if (!lp_posix_pathnames()) { - stream_name = strchr_m(fname, ':'); - } - - /* Setup the base_name/stream_name. */ - if (stream_name) { - base_name = talloc_strndup(ctx, fname, - PTR_DIFF(stream_name, fname)); - } else { - base_name = talloc_strdup(ctx, fname); - } - - if (!base_name) { - return NT_STATUS_NO_MEMORY; - } - - status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf, - smb_fname_out); - TALLOC_FREE(base_name); - return status; -} - -/** - * XXX: This is temporary and there should be no callers of this once - * smb_filename is plumbed through all path based operations. - */ -int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf) -{ - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - int ret; - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; - } - - ret = SMB_VFS_STAT(conn, smb_fname); - if (ret != -1) { - *psbuf = smb_fname->st; - } - - TALLOC_FREE(smb_fname); - return ret; -} - -/** - * XXX: This is temporary and there should be no callers of this once - * smb_filename is plumbed through all path based operations. - */ -int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, - SMB_STRUCT_STAT *psbuf) -{ - struct smb_filename *smb_fname = NULL; - NTSTATUS status; - int ret; - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; - } - - ret = SMB_VFS_LSTAT(conn, smb_fname); - if (ret != -1) { - *psbuf = smb_fname->st; - } - - TALLOC_FREE(smb_fname); - return ret; -} - -/** - * Return a string using the debug_ctx() - */ -const char *smb_fname_str_dbg(const struct smb_filename *smb_fname) -{ - char *fname = NULL; - NTSTATUS status; - - if (smb_fname == NULL) { - return ""; - } - status = get_full_smb_filename(debug_ctx(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - return ""; - } - return fname; -} - -NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, - const struct smb_filename *smb_fname_in, - struct smb_filename **smb_fname_out) -{ - - *smb_fname_out = talloc_zero(ctx, struct smb_filename); - if (*smb_fname_out == NULL) { - return NT_STATUS_NO_MEMORY; - } - - if (smb_fname_in->base_name) { - (*smb_fname_out)->base_name = - talloc_strdup(*smb_fname_out, smb_fname_in->base_name); - if (!(*smb_fname_out)->base_name) - goto no_mem_err; - } - - if (smb_fname_in->stream_name) { - (*smb_fname_out)->stream_name = - talloc_strdup(*smb_fname_out, smb_fname_in->stream_name); - if (!(*smb_fname_out)->stream_name) - goto no_mem_err; - } - - if (smb_fname_in->original_lcomp) { - (*smb_fname_out)->original_lcomp = - talloc_strdup(*smb_fname_out, smb_fname_in->original_lcomp); - if (!(*smb_fname_out)->original_lcomp) - goto no_mem_err; - } - - (*smb_fname_out)->st = smb_fname_in->st; - return NT_STATUS_OK; - - no_mem_err: - TALLOC_FREE(*smb_fname_out); - return NT_STATUS_NO_MEMORY; -} - -/**************************************************************************** - Simple check to determine if the filename is a stream. - ***************************************************************************/ -bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) -{ - if (lp_posix_pathnames()) { - return false; - } - - return smb_fname->stream_name; -} - -/**************************************************************************** - Returns true if the filename's stream == "::$DATA" - ***************************************************************************/ -bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname) -{ - if (!is_ntfs_stream_smb_fname(smb_fname)) { - return false; - } - - return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0; -} - /**************************************************************************** This routine is called to convert names from the dos namespace to unix namespace. It needs to handle any case conversions, mangling, format changes, diff --git a/source3/smbd/filename_util.c b/source3/smbd/filename_util.c new file mode 100644 index 0000000000..1a7af714de --- /dev/null +++ b/source3/smbd/filename_util.c @@ -0,0 +1,194 @@ +/* + Unix SMB/CIFS implementation. + Filename utility functions. + Copyright (C) Tim Prouty 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#include "includes.h" + +/** + * XXX: This is temporary and there should be no callers of this outside of + * this file once smb_filename is plumbed through all path based operations. + * The one legitimate caller currently is smb_fname_str_dbg(), which this + * could be made static for. + */ +NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, + const struct smb_filename *smb_fname, + char **full_name) +{ + if (smb_fname->stream_name) { + *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name, + smb_fname->stream_name); + } else { + *full_name = talloc_strdup(ctx, smb_fname->base_name); + } + + if (!*full_name) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + +/** + * There are actually legitimate callers of this such as functions that + * enumerate streams using the SMB_VFS_STREAMINFO interface and then want to + * operate on each stream. + */ +NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name, + const char *stream_name, + const SMB_STRUCT_STAT *psbuf, + struct smb_filename **smb_fname_out) +{ + struct smb_filename smb_fname_loc; + + ZERO_STRUCT(smb_fname_loc); + + /* Setup the base_name/stream_name. */ + smb_fname_loc.base_name = CONST_DISCARD(char *, base_name); + smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name); + + /* Copy the psbuf if one was given. */ + if (psbuf) + smb_fname_loc.st = *psbuf; + + /* Let copy_smb_filename() do the heavy lifting. */ + return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out); +} + +/** + * XXX: This is temporary and there should be no callers of this once + * smb_filename is plumbed through all path based operations. + */ +NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx, + const char *fname, + const SMB_STRUCT_STAT *psbuf, + struct smb_filename **smb_fname_out) +{ + NTSTATUS status; + const char *stream_name = NULL; + char *base_name = NULL; + + if (!lp_posix_pathnames()) { + stream_name = strchr_m(fname, ':'); + } + + /* Setup the base_name/stream_name. */ + if (stream_name) { + base_name = talloc_strndup(ctx, fname, + PTR_DIFF(stream_name, fname)); + } else { + base_name = talloc_strdup(ctx, fname); + } + + if (!base_name) { + return NT_STATUS_NO_MEMORY; + } + + status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf, + smb_fname_out); + TALLOC_FREE(base_name); + return status; +} + +/** + * Return a string using the debug_ctx() + */ +const char *smb_fname_str_dbg(const struct smb_filename *smb_fname) +{ + char *fname = NULL; + NTSTATUS status; + + if (smb_fname == NULL) { + return ""; + } + status = get_full_smb_filename(debug_ctx(), smb_fname, &fname); + if (!NT_STATUS_IS_OK(status)) { + return ""; + } + return fname; +} + +/** + * Return a debug string using the debug_ctx(). This can only be called from + * DEBUG() macros due to the debut_ctx(). + */ +const char *fsp_str_dbg(const struct files_struct *fsp) +{ + return smb_fname_str_dbg(fsp->fsp_name); +} + +NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, + const struct smb_filename *smb_fname_in, + struct smb_filename **smb_fname_out) +{ + + *smb_fname_out = talloc_zero(ctx, struct smb_filename); + if (*smb_fname_out == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if (smb_fname_in->base_name) { + (*smb_fname_out)->base_name = + talloc_strdup(*smb_fname_out, smb_fname_in->base_name); + if (!(*smb_fname_out)->base_name) + goto no_mem_err; + } + + if (smb_fname_in->stream_name) { + (*smb_fname_out)->stream_name = + talloc_strdup(*smb_fname_out, smb_fname_in->stream_name); + if (!(*smb_fname_out)->stream_name) + goto no_mem_err; + } + + if (smb_fname_in->original_lcomp) { + (*smb_fname_out)->original_lcomp = + talloc_strdup(*smb_fname_out, smb_fname_in->original_lcomp); + if (!(*smb_fname_out)->original_lcomp) + goto no_mem_err; + } + + (*smb_fname_out)->st = smb_fname_in->st; + return NT_STATUS_OK; + + no_mem_err: + TALLOC_FREE(*smb_fname_out); + return NT_STATUS_NO_MEMORY; +} + +/**************************************************************************** + Simple check to determine if the filename is a stream. + ***************************************************************************/ +bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) +{ + if (lp_posix_pathnames()) { + return false; + } + + return smb_fname->stream_name; +} + +/**************************************************************************** + Returns true if the filename's stream == "::$DATA" + ***************************************************************************/ +bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname) +{ + if (!is_ntfs_stream_smb_fname(smb_fname)) { + return false; + } + + return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0; +} diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 8bd914bf0d..a170f774fe 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -592,15 +592,6 @@ NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from, return fsp_set_smb_fname(to, from->fsp_name); } -/** - * Return a debug string using the debug_ctx(). This can only be called from - * DEBUG() macros due to the debut_ctx(). - */ -const char *fsp_str_dbg(const struct files_struct *fsp) -{ - return smb_fname_str_dbg(fsp->fsp_name); -} - /** * The only way that the fsp->fsp_name field should ever be set. */ diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index a2e3ec504c..55495183bd 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -990,3 +990,58 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) } return NT_STATUS_OK; } + +/** + * XXX: This is temporary and there should be no callers of this once + * smb_filename is plumbed through all path based operations. + */ +int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf) +{ + struct smb_filename *smb_fname = NULL; + NTSTATUS status; + int ret; + + status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + + ret = SMB_VFS_STAT(conn, smb_fname); + if (ret != -1) { + *psbuf = smb_fname->st; + } + + TALLOC_FREE(smb_fname); + return ret; +} + +/** + * XXX: This is temporary and there should be no callers of this once + * smb_filename is plumbed through all path based operations. + */ +int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname, + SMB_STRUCT_STAT *psbuf) +{ + struct smb_filename *smb_fname = NULL; + NTSTATUS status; + int ret; + + status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + + ret = SMB_VFS_LSTAT(conn, smb_fname); + if (ret != -1) { + *psbuf = smb_fname->st; + } + + TALLOC_FREE(smb_fname); + return ret; +} + -- cgit From f4530f6d2a0688e350c3c7be23f256ebceffa636 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 10 Jul 2009 15:43:21 -0700 Subject: s3: Plumb smb_filename through open_fake_file --- source3/include/proto.h | 4 ++-- source3/smbd/fake_file.c | 29 ++++++++++++++++++++++------- source3/smbd/open.c | 13 ++----------- 3 files changed, 26 insertions(+), 20 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index c26f2a7c3a..c48cebce11 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6266,11 +6266,11 @@ void reply_openerror(struct smb_request *req, NTSTATUS status); /* The following definitions come from smbd/fake_file.c */ -enum FAKE_FILE_TYPE is_fake_file(const char *fname); +enum FAKE_FILE_TYPE is_fake_file(const struct smb_filename *smb_fname); NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn, uint16_t current_vuid, enum FAKE_FILE_TYPE fake_file_type, - const char *fname, + const struct smb_filename *smb_fname, uint32 access_mask, files_struct **result); NTSTATUS close_fake_file(struct smb_request *req, files_struct *fsp); diff --git a/source3/smbd/fake_file.c b/source3/smbd/fake_file.c index ef54398bc4..743d88f360 100644 --- a/source3/smbd/fake_file.c +++ b/source3/smbd/fake_file.c @@ -71,23 +71,32 @@ static struct fake_file_handle *init_fake_file_handle(enum FAKE_FILE_TYPE type) Does this name match a fake filename ? ****************************************************************************/ -enum FAKE_FILE_TYPE is_fake_file(const char *fname) +enum FAKE_FILE_TYPE is_fake_file(const struct smb_filename *smb_fname) { #ifdef HAVE_SYS_QUOTAS int i; + char *fname = NULL; + NTSTATUS status; #endif - if (!fname) { + if (!smb_fname) { return FAKE_FILE_TYPE_NONE; } #ifdef HAVE_SYS_QUOTAS + status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); + if (!NT_STATUS_IS_OK(status)) { + return FAKE_FILE_TYPE_NONE; + } + for (i=0;fake_files[i].name!=NULL;i++) { if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) { DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname)); + TALLOC_FREE(fname); return fake_files[i].type; } } + TALLOC_FREE(fname); #endif return FAKE_FILE_TYPE_NONE; @@ -101,7 +110,7 @@ enum FAKE_FILE_TYPE is_fake_file(const char *fname) NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn, uint16_t current_vuid, enum FAKE_FILE_TYPE fake_file_type, - const char *fname, + const struct smb_filename *smb_fname, uint32 access_mask, files_struct **result) { @@ -112,7 +121,8 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn, if (conn->server_info->utok.uid != 0) { DEBUG(3, ("open_fake_file_shared: access_denied to " "service[%s] file[%s] user[%s]\n", - lp_servicename(SNUM(conn)), fname, + lp_servicename(SNUM(conn)), + smb_fname_str_dbg(smb_fname), conn->server_info->unix_name)); return NT_STATUS_ACCESS_DENIED; @@ -124,7 +134,8 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn, } DEBUG(5,("open_fake_file_shared: fname = %s, FID = %d, access_mask = 0x%x\n", - fname, fsp->fnum, (unsigned int)access_mask)); + smb_fname_str_dbg(smb_fname), fsp->fnum, + (unsigned int)access_mask)); fsp->conn = conn; fsp->fh->fd = -1; @@ -132,8 +143,12 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn, fsp->fh->pos = -1; fsp->can_lock = False; /* Should this be true ? - No, JRA */ fsp->access_mask = access_mask; - string_set(&fsp->fsp_name,fname); - + status = fsp_set_smb_fname(fsp, smb_fname); + if (!NT_STATUS_IS_OK(status)) { + file_free(req, fsp); + return NT_STATUS_NO_MEMORY; + } + fsp->fake_file_handle = init_fake_file_handle(fake_file_type); if (fsp->fake_file_handle==NULL) { diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 33763d202d..7692c7c847 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -3462,16 +3462,9 @@ NTSTATUS create_file_default(connection_struct *conn, */ if (is_ntfs_stream_smb_fname(smb_fname)) { - char *fname = NULL; enum FAKE_FILE_TYPE fake_file_type; - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - goto fail; - } - - fake_file_type = is_fake_file(fname); + fake_file_type = is_fake_file(smb_fname); if (fake_file_type != FAKE_FILE_TYPE_NONE) { @@ -3487,9 +3480,8 @@ NTSTATUS create_file_default(connection_struct *conn, * close it */ status = open_fake_file(req, conn, req->vuid, - fake_file_type, fname, + fake_file_type, smb_fname, access_mask, &fsp); - TALLOC_FREE(fname); if (!NT_STATUS_IS_OK(status)) { goto fail; } @@ -3497,7 +3489,6 @@ NTSTATUS create_file_default(connection_struct *conn, ZERO_STRUCT(smb_fname->st); goto done; } - TALLOC_FREE(fname); if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) { status = NT_STATUS_OBJECT_NAME_NOT_FOUND; -- cgit From 8e04c69e027260e7e1f0a4cf3e58e31ed4084d8b Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Mon, 20 Jul 2009 14:32:32 -0700 Subject: s3: Add some asserts to the filename util functions In the smb_filename struct stream_name must equal NULL if there is no stream name. These asserts should catch any future offenders of this invariant early. --- source3/smbd/filename_util.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source3') diff --git a/source3/smbd/filename_util.c b/source3/smbd/filename_util.c index 1a7af714de..867709a373 100644 --- a/source3/smbd/filename_util.c +++ b/source3/smbd/filename_util.c @@ -29,6 +29,9 @@ NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, char **full_name) { if (smb_fname->stream_name) { + /* stream_name must always be NULL if there is no stream. */ + SMB_ASSERT(smb_fname->stream_name[0] != '\0'); + *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name, smb_fname->stream_name); } else { @@ -134,6 +137,10 @@ NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname_in, struct smb_filename **smb_fname_out) { + /* stream_name must always be NULL if there is no stream. */ + if (smb_fname_in->stream_name) { + SMB_ASSERT(smb_fname_in->stream_name[0] != '\0'); + } *smb_fname_out = talloc_zero(ctx, struct smb_filename); if (*smb_fname_out == NULL) { @@ -174,6 +181,11 @@ NTSTATUS copy_smb_filename(TALLOC_CTX *ctx, ***************************************************************************/ bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) { + /* stream_name must always be NULL if there is no stream. */ + if (smb_fname->stream_name) { + SMB_ASSERT(smb_fname->stream_name[0] != '\0'); + } + if (lp_posix_pathnames()) { return false; } -- cgit From d5efb38151dea179af920a1a279d974a47b6bfd6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 21 Jul 2009 12:26:14 +0200 Subject: s3:dbwrap: use the transaction wrapper in dbwrap_trans_delete(). Michael --- source3/lib/dbwrap_util.c | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) (limited to 'source3') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 7dbeb63927..32a1dd48e6 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -226,49 +226,33 @@ NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, return status; } -NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key) +static NTSTATUS dbwrap_delete_action(struct db_context * db, void *private_data) { - int res; - struct db_record *rec = NULL; NTSTATUS status; + struct db_record *rec; + TDB_DATA *key = (TDB_DATA *)private_data; - res = db->transaction_start(db); - if (res != 0) { - DEBUG(5, ("transaction_start failed\n")); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - rec = db->fetch_locked(db, talloc_tos(), key); + rec = db->fetch_locked(db, talloc_tos(), *key); if (rec == NULL) { DEBUG(5, ("fetch_locked failed\n")); - status = NT_STATUS_NO_MEMORY; - goto cancel; + return NT_STATUS_NO_MEMORY; } status = rec->delete_rec(rec); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("delete_rec returned %s\n", nt_errstr(status))); - goto cancel; } - TALLOC_FREE(rec); - - res = db->transaction_commit(db); - if (res != 0) { - DEBUG(5, ("tdb_transaction_commit failed\n")); - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - TALLOC_FREE(rec); - return status; - } + talloc_free(rec); + return status; +} - return NT_STATUS_OK; +NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key) +{ + NTSTATUS status; - cancel: - TALLOC_FREE(rec); + status = dbwrap_trans_do(db, dbwrap_delete_action, &key); - if (db->transaction_cancel(db) != 0) { - smb_panic("Cancelling transaction failed"); - } return status; } -- cgit From 319a97bce9f77161e62de9f86ddbec58629238cb Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 21 Jul 2009 12:35:48 +0200 Subject: s3:dbwrap: use the transaction wrapper in dbwrap_trans_store(). Now dbwrap_util.c contains only one call to each of transaction_start, transaction_commit and transaction_cancel. Michael --- source3/lib/dbwrap_util.c | 49 ++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) (limited to 'source3') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 32a1dd48e6..c3ab93c4df 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -179,50 +179,47 @@ int32 dbwrap_change_int32_atomic(struct db_context *db, const char *keystr, return 0; } -NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, - int flag) +struct dbwrap_store_context { + TDB_DATA *key; + TDB_DATA *dbuf; + int flag; +}; + +static NTSTATUS dbwrap_store_action(struct db_context *db, void *private_data) { - int res; struct db_record *rec = NULL; NTSTATUS status; + struct dbwrap_store_context *store_ctx; - res = db->transaction_start(db); - if (res != 0) { - DEBUG(5, ("transaction_start failed\n")); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } + store_ctx = (struct dbwrap_store_context *)private_data; - rec = db->fetch_locked(db, talloc_tos(), key); + rec = db->fetch_locked(db, talloc_tos(), *(store_ctx->key)); if (rec == NULL) { DEBUG(5, ("fetch_locked failed\n")); - status = NT_STATUS_NO_MEMORY; - goto cancel; + return NT_STATUS_NO_MEMORY; } - status = rec->store(rec, dbuf, flag); + status = rec->store(rec, *(store_ctx->dbuf), store_ctx->flag); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("store returned %s\n", nt_errstr(status))); - goto cancel; } TALLOC_FREE(rec); + return status; +} - res = db->transaction_commit(db); - if (res != 0) { - DEBUG(5, ("tdb_transaction_commit failed\n")); - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - TALLOC_FREE(rec); - return status; - } +NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, + int flag) +{ + NTSTATUS status; + struct dbwrap_store_context store_ctx; - return NT_STATUS_OK; + store_ctx.key = &key; + store_ctx.dbuf = &dbuf; + store_ctx.flag = flag; - cancel: - TALLOC_FREE(rec); + status = dbwrap_trans_do(db, dbwrap_store_action, &store_ctx); - if (db->transaction_cancel(db) != 0) { - smb_panic("Cancelling transaction failed"); - } return status; } -- cgit From 8b6ec5b82cbc66cf8efd9d0713e36aac63c8c49e Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Tue, 21 Jul 2009 13:56:17 +0200 Subject: do not log chdir with level 0 if reason is access denied this changes the level of logs caused by users trying to access shares or subdirectories for which they do not have access to in the ACL this can fill up the samba log even with log level 0 and is more an expected kind of logs that IMHO should not be logged with such a high level. All other errors while chdir() will still be logged with level 0 Signed-off-by: Christian Ambach --- source3/smbd/service.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 0124b2b047..a043288bc9 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -182,8 +182,8 @@ bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir) if (do_chdir && vfs_ChDir(conn,conn->connectpath) != 0 && vfs_ChDir(conn,conn->origpath) != 0) { - DEBUG(0,("chdir (%s) failed\n", - conn->connectpath)); + DEBUG(((errno!=EACCES)?0:3),("chdir (%s) failed, reason: %s\n", + conn->connectpath, strerror(errno))); return(False); } -- cgit From 6b49f28592af5c998642bd5d5f76b77c79a22cd7 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 09:29:59 -0700 Subject: s3: Plumb smb_filename through map_open_params_to_ntcreate --- source3/include/proto.h | 3 ++- source3/smbd/open.c | 10 ++++++---- source3/smbd/reply.c | 19 ++++++++++--------- source3/smbd/trans2.c | 10 ++++------ 4 files changed, 22 insertions(+), 20 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index c48cebce11..fe81bd2c97 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6589,7 +6589,8 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req, uint32 access_mask, uint32 share_access, uint32 create_options); -bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func, +bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname, + int deny_mode, int open_func, uint32 *paccess_mask, uint32 *pshare_mode, uint32 *pcreate_disposition, diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 7692c7c847..87cab1966b 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1199,7 +1199,8 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req, Open a file with a share mode - old openX method - map into NTCreate. ****************************************************************************/ -bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func, +bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname, + int deny_mode, int open_func, uint32 *paccess_mask, uint32 *pshare_mode, uint32 *pcreate_disposition, @@ -1212,7 +1213,8 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, " "open_func = 0x%x\n", - fname, (unsigned int)deny_mode, (unsigned int)open_func )); + smb_fname_str_dbg(smb_fname), (unsigned int)deny_mode, + (unsigned int)open_func )); /* Create the NT compatible access_mask. */ switch (GET_OPENX_MODE(deny_mode)) { @@ -1286,7 +1288,7 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func case DENY_DOS: create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS; - if (is_executable(fname)) { + if (is_executable(smb_fname->base_name)) { share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE; } else { if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) { @@ -1311,7 +1313,7 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, " "share_mode = 0x%x, create_disposition = 0x%x, " "create_options = 0x%x\n", - fname, + smb_fname_str_dbg(smb_fname), (unsigned int)access_mask, (unsigned int)share_mode, (unsigned int)create_disposition, diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 46fdd4adde..5924c46cc1 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1760,10 +1760,10 @@ void reply_open(struct smb_request *req) goto out; } - if (!map_open_params_to_ntcreate( - smb_fname->base_name, deny_mode, OPENX_FILE_EXISTS_OPEN, - &access_mask, &share_mode, &create_disposition, - &create_options)) { + if (!map_open_params_to_ntcreate(smb_fname, deny_mode, + OPENX_FILE_EXISTS_OPEN, &access_mask, + &share_mode, &create_disposition, + &create_options)) { reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess)); goto out; } @@ -1931,9 +1931,10 @@ void reply_open_and_X(struct smb_request *req) goto out; } - if (!map_open_params_to_ntcreate( - smb_fname->base_name, deny_mode, smb_ofun, &access_mask, - &share_mode, &create_disposition, &create_options)) { + if (!map_open_params_to_ntcreate(smb_fname, deny_mode, smb_ofun, + &access_mask, &share_mode, + &create_disposition, + &create_options)) { reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess)); goto out; } @@ -6659,8 +6660,8 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, if (!target_is_directory && count) { new_create_disposition = FILE_OPEN; } else { - if (!map_open_params_to_ntcreate(smb_fname_dst_tmp->base_name, - 0, ofun, NULL, NULL, + if (!map_open_params_to_ntcreate(smb_fname_dst_tmp, 0, ofun, + NULL, NULL, &new_create_disposition, NULL)) { status = NT_STATUS_INVALID_PARAMETER; diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index e2efed331d..9ce541aa63 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1046,12 +1046,10 @@ static void call_trans2open(connection_struct *conn, goto out; } - if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode, - open_ofun, - &access_mask, - &share_mode, - &create_disposition, - &create_options)) { + if (!map_open_params_to_ntcreate(smb_fname, deny_mode, open_ofun, + &access_mask, &share_mode, + &create_disposition, + &create_options)) { reply_doserror(req, ERRDOS, ERRbadaccess); goto out; } -- cgit From 78ce9dd471568773760292ea18478af51c11d71a Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 10:18:10 -0700 Subject: s3: Remove unnecessary fname argument from callers of filename_convert --- source3/smbd/trans2.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 9ce541aa63..2f1f50b11d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4748,7 +4748,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn, uint16 info_level; unsigned int data_size = 0; unsigned int param_size = 2; - char *fname = NULL; struct smb_filename *smb_fname = NULL; bool delete_pending = False; struct timespec write_time_ts; @@ -4861,6 +4860,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn, } } else { + char *fname = NULL; + /* qpathinfo */ if (total_params < 7) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -4889,7 +4890,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, &smb_fname, - &fname); + NULL); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -4969,7 +4970,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn, } else if (!VALID_STAT(smb_fname->st) && SMB_VFS_STAT(conn, smb_fname) && (info_level != SMB_INFO_IS_NAME_VALID)) { - ms_dfs_link = check_msdfs_link(conn, fname, + ms_dfs_link = check_msdfs_link(conn, + smb_fname->base_name, &smb_fname->st); if (!ms_dfs_link) { @@ -4991,8 +4993,9 @@ static void call_trans2qfilepathinfo(connection_struct *conn, } } - DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n", - fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data)); + DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d " + "total_data=%d\n", smb_fname_str_dbg(smb_fname), + fsp ? fsp->fnum : -1, info_level,tran_call,total_data)); /* Pull out any data sent here before we realloc. */ switch (info_level) { @@ -7348,7 +7351,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn, char *params = *pparams; char *pdata = *ppdata; uint16 info_level; - char *fname = NULL; struct smb_filename *smb_fname = NULL; files_struct *fsp = NULL; NTSTATUS status = NT_STATUS_OK; @@ -7443,6 +7445,8 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } } } else { + char *fname = NULL; + /* set path info */ if (total_params < 7) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -7462,7 +7466,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, &smb_fname, - &fname); + NULL); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -7493,8 +7497,9 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } } - DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n", - tran_call, fname, fsp ? fsp->fnum : -1, info_level,total_data)); + DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d " + "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname), + fsp ? fsp->fnum : -1, info_level,total_data)); /* Realloc the parameter size */ *pparams = (char *)SMB_REALLOC(*pparams,2); -- cgit From 4860fc4951a7dbd80d8938f4dba49c42a12b4d00 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 10:19:00 -0700 Subject: s3: Fix RENAME_FLAG_RENAME path to stop calling unix_convert twice --- source3/smbd/nttrans.c | 125 +++++++++++++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 50 deletions(-) (limited to 'source3') diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index ecb88296ca..af79986df4 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1317,8 +1317,7 @@ void reply_ntrename(struct smb_request *req) if (req->wct < 4) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - END_PROFILE(SMBntrename); - return; + goto out; } attrs = SVAL(req->vwv+0, 0); @@ -1329,14 +1328,12 @@ void reply_ntrename(struct smb_request *req) &status, &src_has_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); - END_PROFILE(SMBntrename); - return; + goto out; } if (ms_has_wild(oldname)) { reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD); - END_PROFILE(SMBntrename); - return; + goto out; } p++; @@ -1344,55 +1341,85 @@ void reply_ntrename(struct smb_request *req) &status, &dest_has_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); - END_PROFILE(SMBntrename); - return; + goto out; } - status = filename_convert(ctx, conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - oldname, - &smb_fname_old, - &oldname); - if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { - reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, - ERRSRV, ERRbadpath); - END_PROFILE(SMBntrename); - return; - } - reply_nterror(req, status); - END_PROFILE(SMBntrename); - return; + /* The newname must begin with a ':' if the oldname contains a ':'. */ + if (strchr_m(oldname, ':') && (newname[0] != ':')) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + goto out; } - status = filename_convert(ctx, conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - newname, - &smb_fname_new, - &newname); - if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { - reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, - ERRSRV, ERRbadpath); - END_PROFILE(SMBntrename); - return; + /* rename_internals() calls unix_convert(), so don't call it here. */ + if (rename_type != RENAME_FLAG_RENAME) { + status = filename_convert(ctx, conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + oldname, + &smb_fname_old, + NULL); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, + NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + goto out; + } + reply_nterror(req, status); + goto out; } - reply_nterror(req, status); - END_PROFILE(SMBntrename); - return; - } - /* The new name must begin with a ':' if the old name is a stream. */ - if (is_ntfs_stream_smb_fname(smb_fname_old) && (newname[0] != ':')) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - END_PROFILE(SMBntrename); - return; - } + status = filename_convert(ctx, conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + newname, + &smb_fname_new, + NULL); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, + NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + goto out; + } + reply_nterror(req, status); + goto out; + } - DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname)); + DEBUG(3,("reply_ntrename: %s -> %s\n", + smb_fname_str_dbg(smb_fname_old), + smb_fname_str_dbg(smb_fname_new))); + } switch(rename_type) { case RENAME_FLAG_RENAME: + status = resolve_dfspath(ctx, conn, + (req->flags2 & + FLAGS2_DFS_PATHNAMES), + oldname, &oldname); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("resolve_dfspath failed for name %s " + "with %s\n", oldname, + nt_errstr(status))); + reply_nterror(req, status); + goto out; + } + + status = resolve_dfspath(ctx, conn, + (req->flags2 & + FLAGS2_DFS_PATHNAMES), + newname, &newname); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("resolve_dfspath failed for name %s " + "with %s\n", newname, + nt_errstr(status))); + reply_nterror(req, status); + goto out; + } + + DEBUG(3,("reply_ntrename: %s -> %s\n", oldname, + newname)); + status = rename_internals(ctx, conn, req, oldname, newname, attrs, False, src_has_wcard, dest_has_wcard, DELETE_ACCESS); @@ -1430,17 +1457,15 @@ void reply_ntrename(struct smb_request *req) if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { /* We have re-scheduled this call. */ - END_PROFILE(SMBntrename); - return; + goto out; } reply_nterror(req, status); - END_PROFILE(SMBntrename); - return; + goto out; } reply_outbuf(req, 0, 0); - + out: END_PROFILE(SMBntrename); return; } -- cgit From 00e267008defe18475115a4300addf3cbcabff5a Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 10:28:28 -0700 Subject: s3: Remove the now unused fname parameter from filename_convert() --- source3/include/proto.h | 3 +-- source3/rpc_server/srv_srvsvc_nt.c | 6 ++---- source3/smbd/filename.c | 16 ++++------------ source3/smbd/nttrans.c | 12 ++++-------- source3/smbd/reply.c | 27 +++++++++------------------ source3/smbd/smb2_create.c | 3 +-- source3/smbd/trans2.c | 15 +++++---------- 7 files changed, 26 insertions(+), 56 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index fe81bd2c97..77283d9cf0 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6320,8 +6320,7 @@ NTSTATUS filename_convert(TALLOC_CTX *mem_ctx, connection_struct *conn, bool dfs_path, const char *name_in, - struct smb_filename **pp_smb_fname, - char **pp_name); + struct smb_filename **pp_smb_fname); /* The following definitions come from smbd/filename_utils.c */ diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index c58c08ecdc..b9d1ed6d73 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -2072,8 +2072,7 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, conn, false, r->in.file, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(nt_status)) { werr = ntstatus_to_werror(nt_status); goto error_exit; @@ -2201,8 +2200,7 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, conn, false, r->in.file, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(nt_status)) { werr = ntstatus_to_werror(nt_status); goto error_exit; diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index c05f0e659f..541b0cd3cb 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -1018,8 +1018,7 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, connection_struct *conn, bool dfs_path, const char *name_in, - struct smb_filename **pp_smb_fname, - char **pp_name) + struct smb_filename **pp_smb_fname) { NTSTATUS status; char *fname = NULL; @@ -1046,22 +1045,15 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, return status; } - status = get_full_smb_filename(ctx, *pp_smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = check_name(conn, fname); + status = check_name(conn, (*pp_smb_fname)->base_name); if (!NT_STATUS_IS_OK(status)) { DEBUG(3,("filename_convert: check_name failed " "for name %s with %s\n", - fname, + smb_fname_str_dbg(*pp_smb_fname), nt_errstr(status) )); + TALLOC_FREE(*pp_smb_fname); return status; } - if (pp_name != NULL) { - *pp_name = fname; - } return status; } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index af79986df4..43212dc800 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -478,8 +478,7 @@ void reply_ntcreate_and_X(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -968,8 +967,7 @@ static void call_nt_transact_create(connection_struct *conn, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1355,8 +1353,7 @@ void reply_ntrename(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, oldname, - &smb_fname_old, - NULL); + &smb_fname_old); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, NT_STATUS_PATH_NOT_COVERED)) { @@ -1372,8 +1369,7 @@ void reply_ntrename(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, newname, - &smb_fname_new, - NULL); + &smb_fname_new); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, NT_STATUS_PATH_NOT_COVERED)) { diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 5924c46cc1..72595aeda7 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -994,8 +994,7 @@ void reply_checkpath(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, name, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1091,8 +1090,7 @@ void reply_getatr(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -1193,8 +1191,7 @@ void reply_setatr(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -1747,8 +1744,7 @@ void reply_open(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -1918,8 +1914,7 @@ void reply_open_and_X(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -2128,8 +2123,7 @@ void reply_mknew(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -2261,8 +2255,7 @@ void reply_ctemp(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -5267,8 +5260,7 @@ void reply_mkdir(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, - &smb_dname, - NULL); + &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -5575,8 +5567,7 @@ void reply_rmdir(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, - &smb_dname, - NULL); + &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index 7337a345fd..b455f82d80 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -325,8 +325,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, smbreq->conn, smbreq->flags2 & FLAGS2_DFS_PATHNAMES, in_name, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); TALLOC_FREE(smb_fname); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 2f1f50b11d..8637d1bda1 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1028,8 +1028,7 @@ static void call_trans2open(connection_struct *conn, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -4889,8 +4888,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -5664,8 +5662,7 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, oldname, - &smb_fname_old, - NULL); + &smb_fname_old); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -7465,8 +7462,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, status = filename_convert(req, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - &smb_fname, - NULL); + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -7587,8 +7583,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, - &smb_dname, - NULL); + &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { -- cgit From 23c703a01eddfa9103352e0ad43bc9fe39ea0c27 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 11:35:17 -0700 Subject: s3: Remove unnecessary callers of get_full_smb_filename This often times means explicitly denying certain operations on a stream as they are not supported or don't make sense at a particular level. At some point in the future these can be enabled, but for now it's better to remove ambiguity --- source3/modules/vfs_default.c | 58 +++++++++-------------------- source3/smbd/close.c | 5 +-- source3/smbd/file_access.c | 10 +---- source3/smbd/reply.c | 86 ++++++++++++++----------------------------- source3/smbd/trans2.c | 81 +++++++++++++++++----------------------- 5 files changed, 81 insertions(+), 159 deletions(-) (limited to 'source3') diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index d6a66b01de..cdfd28c571 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -218,27 +218,17 @@ static int vfswrap_open(vfs_handle_struct *handle, struct smb_filename *smb_fname, files_struct *fsp, int flags, mode_t mode) { - int result; - NTSTATUS status; - char *fname = NULL; + int result = -1; START_PROFILE(syscall_open); - /* - * XXX: Should an error be returned if there is a stream rather than - * trying to open a filename with a ':'? - */ - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; + if (smb_fname->stream_name) { + errno = ENOENT; + goto out; } - result = sys_open(fname, flags, mode); - - TALLOC_FREE(fname); - + result = sys_open(smb_fname->base_name, flags, mode); + out: END_PROFILE(syscall_open); return result; } @@ -562,23 +552,17 @@ static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp) static int vfswrap_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { - int result; - NTSTATUS status; - char *fname = NULL; + int result = -1; START_PROFILE(syscall_stat); - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; + if (smb_fname->stream_name) { + errno = ENOENT; + goto out; } - result = sys_stat(fname, &smb_fname->st); - - TALLOC_FREE(fname); - + result = sys_stat(smb_fname->base_name, &smb_fname->st); + out: END_PROFILE(syscall_stat); return result; } @@ -596,23 +580,17 @@ static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUC static int vfswrap_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { - int result; - NTSTATUS status; - char *fname = NULL; + int result = -1; START_PROFILE(syscall_lstat); - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; + if (smb_fname->stream_name) { + errno = ENOENT; + goto out; } - result = sys_lstat(fname, &smb_fname->st); - - TALLOC_FREE(fname); - + result = sys_lstat(smb_fname->base_name, &smb_fname->st); + out: END_PROFILE(syscall_lstat); return result; } diff --git a/source3/smbd/close.c b/source3/smbd/close.c index f878aaa056..788b0a7cec 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -47,10 +47,7 @@ static NTSTATUS check_magic(struct files_struct *fsp) ctx = talloc_stackframe(); - status = get_full_smb_filename(ctx, fsp->fsp_name, &fname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } + fname = fsp->fsp_name->base_name; if (!(p = strrchr_m(fname,'/'))) { p = fname; diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c index d8fee1db06..7d0a552956 100644 --- a/source3/smbd/file_access.c +++ b/source3/smbd/file_access.c @@ -33,7 +33,6 @@ bool can_access_file_acl(struct connection_struct *conn, NTSTATUS status; uint32_t access_granted; struct security_descriptor *secdesc = NULL; - char *fname = NULL; bool ret; if (conn->server_info->utok.uid == 0 || conn->admin_user) { @@ -41,13 +40,7 @@ bool can_access_file_acl(struct connection_struct *conn, return true; } - status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - ret = false; - goto out; - } - - status = SMB_VFS_GET_NT_ACL(conn, fname, + status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name, (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION), @@ -62,7 +55,6 @@ bool can_access_file_acl(struct connection_struct *conn, access_mask, &access_granted); ret = NT_STATUS_IS_OK(status); out: - TALLOC_FREE(fname); TALLOC_FREE(secdesc); return ret; } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 72595aeda7..76d32a2f98 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1340,6 +1340,7 @@ void reply_search(struct smb_request *req) char *path = NULL; const char *mask = NULL; char *directory = NULL; + struct smb_filename *smb_fname = NULL; char *fname = NULL; SMB_OFF_T size; uint32 mode; @@ -1364,14 +1365,12 @@ void reply_search(struct smb_request *req) if (req->wct < 2) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - END_PROFILE(SMBsearch); - return; + goto out; } if (lp_posix_pathnames()) { reply_unknown_new(req, req->cmd); - END_PROFILE(SMBsearch); - return; + goto out; } /* If we were called as SMBffirst then we must expect close. */ @@ -1387,8 +1386,7 @@ void reply_search(struct smb_request *req) &nt_status, &mask_contains_wcard); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } p++; @@ -1398,8 +1396,6 @@ void reply_search(struct smb_request *req) /* dirtype &= ~aDIR; */ if (status_len == 0) { - struct smb_filename *smb_fname = NULL; - nt_status = resolve_dfspath_wcard(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, path, @@ -1409,35 +1405,25 @@ void reply_search(struct smb_request *req) if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); - END_PROFILE(SMBsearch); - return; + goto out; } reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } nt_status = unix_convert(ctx, conn, path, &smb_fname, UCF_ALLOW_WCARD_LCOMP); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } - nt_status = get_full_smb_filename(ctx, smb_fname, &directory); - TALLOC_FREE(smb_fname); - if (!NT_STATUS_IS_OK(nt_status)) { - reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; - } + directory = smb_fname->base_name; nt_status = check_name(conn, directory); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } p = strrchr_m(directory,'/'); @@ -1452,8 +1438,7 @@ void reply_search(struct smb_request *req) if (!directory) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } memset((char *)status,'\0',21); @@ -1470,8 +1455,7 @@ void reply_search(struct smb_request *req) &conn->dirptr); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } dptr_num = dptr_dnum(conn->dirptr); } else { @@ -1511,8 +1495,7 @@ void reply_search(struct smb_request *req) if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)), 0,aVOLID,0,!allow_long_path_components)) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } dptr_fill(buf+12,dptr_num); if (dptr_zero(buf+12) && (status_len==0)) { @@ -1524,8 +1507,7 @@ void reply_search(struct smb_request *req) data_blob_const(buf, sizeof(buf))) == -1) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } } else { unsigned int i; @@ -1564,8 +1546,7 @@ void reply_search(struct smb_request *req) convert_timespec_to_time_t(date), !allow_long_path_components)) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } if (!dptr_fill(buf+12,dptr_num)) { break; @@ -1574,8 +1555,7 @@ void reply_search(struct smb_request *req) data_blob_const(buf, sizeof(buf))) == -1) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } numentries++; } @@ -1602,8 +1582,7 @@ void reply_search(struct smb_request *req) if ((numentries == 0) && !mask_contains_wcard) { reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles); - END_PROFILE(SMBsearch); - return; + goto out; } SSVAL(req->outbuf,smb_vwv0,numentries); @@ -1635,7 +1614,8 @@ void reply_search(struct smb_request *req) dirtype, numentries, maxentries )); - + out: + TALLOC_FREE(smb_fname); END_PROFILE(SMBsearch); return; } @@ -5811,9 +5791,6 @@ static void notify_rename(connection_struct *conn, bool is_dir, { char *parent_dir_src = NULL; char *parent_dir_dst = NULL; - char *fname_src = NULL; - char *fname_dst = NULL; - NTSTATUS status; uint32 mask; mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME @@ -5826,24 +5803,17 @@ static void notify_rename(connection_struct *conn, bool is_dir, goto out; } - status = get_full_smb_filename(talloc_tos(), smb_fname_src, - &fname_src); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - status = get_full_smb_filename(talloc_tos(), smb_fname_dst, - &fname_dst); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - if (strcmp(parent_dir_src, parent_dir_dst) == 0) { - notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, fname_src); - notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, fname_dst); + notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, + smb_fname_src->base_name); + notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, + smb_fname_dst->base_name); } else { - notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, fname_src); - notify_fname(conn, NOTIFY_ACTION_ADDED, mask, fname_dst); + notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, + smb_fname_src->base_name); + notify_fname(conn, NOTIFY_ACTION_ADDED, mask, + smb_fname_dst->base_name); } /* this is a strange one. w2k3 gives an additional event for @@ -5853,13 +5823,11 @@ static void notify_rename(connection_struct *conn, bool is_dir, notify_fname(conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES |FILE_NOTIFY_CHANGE_CREATION, - fname_dst); + smb_fname_dst->base_name); } out: TALLOC_FREE(parent_dir_src); TALLOC_FREE(parent_dir_dst); - TALLOC_FREE(fname_src); - TALLOC_FREE(fname_dst); } /**************************************************************************** diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 8637d1bda1..daaf97c18d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -471,17 +471,13 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const struct smb_filename *smb_fname, struct ea_list *ea_list) { char *fname = NULL; - NTSTATUS status; if (!lp_ea_support(SNUM(conn))) { return NT_STATUS_EAS_NOT_SUPPORTED; } - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + /* For now setting EAs on streams isn't supported. */ + fname = smb_fname->base_name; for (;ea_list; ea_list = ea_list->next) { int ret; @@ -2039,7 +2035,7 @@ static void call_trans2findfirst(connection_struct *conn, if (total_params < 13) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + goto out; } dirtype = SVAL(params,0); @@ -2077,12 +2073,12 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", ask_sharemode = false; if (!lp_unix_extensions()) { reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + goto out; } break; default: reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + goto out; } srvstr_get_path_wcard(ctx, params, req->flags2, &directory, @@ -2090,7 +2086,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", STR_TERMINATE, &ntstatus, &mask_contains_wcard); if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); - return; + goto out; } ntstatus = resolve_dfspath_wcard(ctx, conn, @@ -2102,32 +2098,27 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); - return; + goto out; } reply_nterror(req, ntstatus); - return; + goto out; } ntstatus = unix_convert(ctx, conn, directory, &smb_dname, (UCF_SAVE_LCOMP | UCF_ALLOW_WCARD_LCOMP)); if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); - return; + goto out; } mask = smb_dname->original_lcomp; - ntstatus = get_full_smb_filename(ctx, smb_dname, &directory); - TALLOC_FREE(smb_dname); - if (!NT_STATUS_IS_OK(ntstatus)) { - reply_nterror(req, ntstatus); - return; - } + directory = smb_dname->base_name; ntstatus = check_name(conn, directory); if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); - return; + goto out; } p = strrchr_m(directory,'/'); @@ -2137,14 +2128,14 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", mask = talloc_strdup(ctx,"*"); if (!mask) { reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + goto out; } mask_contains_wcard = True; } directory = talloc_strdup(talloc_tos(), "./"); if (!directory) { reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + goto out; } } else { *p = 0; @@ -2157,7 +2148,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", if (total_data < 4) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + goto out; } ea_size = IVAL(pdata,0); @@ -2165,19 +2156,19 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) )); reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + goto out; } if (!lp_ea_support(SNUM(conn))) { reply_doserror(req, ERRDOS, ERReasnotsupported); - return; + goto out; } /* Pull out the list of names. */ ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4); if (!ea_list) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + goto out; } } @@ -2185,7 +2176,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); if(*ppdata == NULL ) { reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + goto out; } pdata = *ppdata; data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1; @@ -2194,7 +2185,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd *pparams = (char *)SMB_REALLOC(*pparams, 10); if (*pparams == NULL) { reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + goto out; } params = *pparams; @@ -2213,7 +2204,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); - return; + goto out; } dptr_num = dptr_dnum(conn->dirptr); @@ -2296,11 +2287,11 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd dptr_close(&dptr_num); if (Protocol < PROTOCOL_NT1) { reply_doserror(req, ERRDOS, ERRnofiles); - return; + goto out; } else { reply_botherror(req, NT_STATUS_NO_SUCH_FILE, ERRDOS, ERRbadfile); - return; + goto out; } } @@ -2339,7 +2330,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd char mangled_name[13]; name_to_8_3(mask, mangled_name, True, conn->params); } - + out: + TALLOC_FREE(smb_dname); return; } @@ -5122,8 +5114,6 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx, const struct smb_filename *smb_fname_old, const struct smb_filename *smb_fname_new) { - char *oldname = NULL; - char *newname = NULL; NTSTATUS status = NT_STATUS_OK; /* source must already exist. */ @@ -5141,25 +5131,22 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx, return NT_STATUS_FILE_IS_A_DIRECTORY; } - status = get_full_smb_filename(ctx, smb_fname_new, &newname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - status = get_full_smb_filename(ctx, smb_fname_old, &oldname); - if (!NT_STATUS_IS_OK(status)) { - goto out; + /* Setting a hardlink to/from a stream isn't currently supported. */ + if (is_ntfs_stream_smb_fname(smb_fname_old) || + is_ntfs_stream_smb_fname(smb_fname_new)) { + return NT_STATUS_INVALID_PARAMETER; } - DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname )); + DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", + smb_fname_old->base_name, smb_fname_new->base_name)); - if (SMB_VFS_LINK(conn,oldname,newname) != 0) { + if (SMB_VFS_LINK(conn, smb_fname_old->base_name, + smb_fname_new->base_name) != 0) { status = map_nt_error_from_unix(errno); DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n", - nt_errstr(status), newname, oldname)); + nt_errstr(status), smb_fname_old->base_name, + smb_fname_new->base_name)); } - out: - TALLOC_FREE(newname); - TALLOC_FREE(oldname); return status; } -- cgit From 605649edc3d3ce4f760b08fd8ee5684007369be8 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 11:37:51 -0700 Subject: s3: plumb smb_filename through some of the trans2 posix_* functions --- source3/smbd/trans2.c | 98 ++++++++++++++++++++------------------------------- 1 file changed, 38 insertions(+), 60 deletions(-) (limited to 'source3') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index daaf97c18d..cac0147c4d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3994,7 +3994,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, } DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n", - fname, fsp ? fsp->fnum : -1, info_level, max_data_bytes)); + smb_fname_str_dbg(smb_fname), fsp ? fsp->fnum : -1, + info_level, max_data_bytes)); if (ms_dfs_link) { mode = dos_mode_msdfs(conn, smb_fname); @@ -5546,10 +5547,10 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn, struct smb_request *req, const char *pdata, int total_data, - const char *fname) + const struct smb_filename *smb_fname) { char *link_target = NULL; - const char *newname = fname; + const char *newname = smb_fname->base_name; NTSTATUS status = NT_STATUS_OK; TALLOC_CTX *ctx = talloc_tos(); @@ -5825,8 +5826,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn, const char *pdata, int total_data, files_struct *fsp, - const char *fname, - SMB_STRUCT_STAT *psbuf) + const struct smb_filename *smb_fname) { uint16 posix_acl_version; uint16 num_file_acls; @@ -5861,18 +5861,20 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn, } DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n", - fname ? fname : fsp_str_dbg(fsp), + smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp), (unsigned int)num_file_acls, (unsigned int)num_def_acls)); - if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls, - pdata + SMB_POSIX_ACL_HEADER_SIZE)) { + if (valid_file_acls && !set_unix_posix_acl(conn, fsp, + smb_fname->base_name, num_file_acls, + pdata + SMB_POSIX_ACL_HEADER_SIZE)) { return map_nt_error_from_unix(errno); } - if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, psbuf, num_def_acls, - pdata + SMB_POSIX_ACL_HEADER_SIZE + - (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) { + if (valid_def_acls && !set_unix_posix_default_acl(conn, + smb_fname->base_name, &smb_fname->st, num_def_acls, + pdata + SMB_POSIX_ACL_HEADER_SIZE + + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) { return map_nt_error_from_unix(errno); } return NT_STATUS_OK; @@ -6640,11 +6642,9 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, struct smb_request *req, char **ppdata, int total_data, - const char *fname, - SMB_STRUCT_STAT *psbuf, + struct smb_filename *smb_fname, int *pdata_return_size) { - struct smb_filename *smb_fname; NTSTATUS status = NT_STATUS_OK; uint32 raw_unixmode = 0; uint32 mod_unixmode = 0; @@ -6661,7 +6661,8 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, raw_unixmode = IVAL(pdata,8); /* Next 4 bytes are not yet defined. */ - status = unix_perms_from_wire(conn, psbuf, raw_unixmode, PERM_NEW_DIR, &unixmode); + status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode, + PERM_NEW_DIR, &unixmode); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -6669,13 +6670,7 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS; DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n", - fname, (unsigned int)unixmode )); - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + smb_fname_str_dbg(smb_fname), (unsigned int)unixmode)); status = SMB_VFS_CREATE_FILE( conn, /* conn */ @@ -6694,9 +6689,6 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, &fsp, /* result */ &info); /* pinfo */ - *psbuf = smb_fname->st; - TALLOC_FREE(smb_fname); - if (NT_STATUS_IS_OK(status)) { close_file(req, fsp, NORMAL_CLOSE); } @@ -6727,12 +6719,14 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, case SMB_QUERY_FILE_UNIX_BASIC: SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC); SSVAL(pdata,10,0); /* Padding. */ - store_file_unix_basic(conn, pdata + 12, fsp, psbuf); + store_file_unix_basic(conn, pdata + 12, fsp, + &smb_fname->st); break; case SMB_QUERY_FILE_UNIX_INFO2: SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2); SSVAL(pdata,10,0); /* Padding. */ - store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf); + store_file_unix_basic_info2(conn, pdata + 12, fsp, + &smb_fname->st); break; default: SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED); @@ -6751,11 +6745,9 @@ static NTSTATUS smb_posix_open(connection_struct *conn, struct smb_request *req, char **ppdata, int total_data, - const char *fname, - SMB_STRUCT_STAT *psbuf, + struct smb_filename *smb_fname, int *pdata_return_size) { - struct smb_filename *smb_fname = NULL; bool extended_oplock_granted = False; char *pdata = *ppdata; uint32 flags = 0; @@ -6788,8 +6780,7 @@ static NTSTATUS smb_posix_open(connection_struct *conn, return smb_posix_mkdir(conn, req, ppdata, total_data, - fname, - psbuf, + smb_fname, pdata_return_size); } @@ -6828,11 +6819,10 @@ static NTSTATUS smb_posix_open(connection_struct *conn, raw_unixmode = IVAL(pdata,8); /* Next 4 bytes are not yet defined. */ - status = unix_perms_from_wire(conn, - psbuf, - raw_unixmode, - VALID_STAT(*psbuf) ? PERM_EXISTING_FILE : PERM_NEW_FILE, - &unixmode); + status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode, + (VALID_STAT(smb_fname->st) ? + PERM_EXISTING_FILE : PERM_NEW_FILE), + &unixmode); if (!NT_STATUS_IS_OK(status)) { return status; @@ -6851,16 +6841,10 @@ static NTSTATUS smb_posix_open(connection_struct *conn, } DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n", - fname, + smb_fname_str_dbg(smb_fname), (unsigned int)wire_open_mode, (unsigned int)unixmode )); - status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ @@ -6879,9 +6863,6 @@ static NTSTATUS smb_posix_open(connection_struct *conn, &fsp, /* result */ &info); /* pinfo */ - *psbuf = smb_fname->st; - TALLOC_FREE(smb_fname); - if (!NT_STATUS_IS_OK(status)) { return status; } @@ -6934,12 +6915,14 @@ static NTSTATUS smb_posix_open(connection_struct *conn, case SMB_QUERY_FILE_UNIX_BASIC: SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC); SSVAL(pdata,10,0); /* padding. */ - store_file_unix_basic(conn, pdata + 12, fsp, psbuf); + store_file_unix_basic(conn, pdata + 12, fsp, + &smb_fname->st); break; case SMB_QUERY_FILE_UNIX_INFO2: SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2); SSVAL(pdata,10,0); /* padding. */ - store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf); + store_file_unix_basic_info2(conn, pdata + 12, fsp, + &smb_fname->st); break; default: SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED); @@ -7073,16 +7056,12 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, int *ret_data_size) { char *pdata = *ppdata; - SMB_STRUCT_STAT sbuf; char *fname = NULL; NTSTATUS status = NT_STATUS_OK; int data_return_size = 0; *ret_data_size = 0; - /* Set sbuf for use below. */ - sbuf = smb_fname->st; - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { return NT_STATUS_INVALID_LEVEL; } @@ -7100,8 +7079,9 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, return status; } - DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d totdata=%d\n", - fname, fsp ? fsp->fnum : -1, info_level, total_data)); + DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d " + "totdata=%d\n", smb_fname_str_dbg(smb_fname), + fsp ? fsp->fnum : -1, info_level, total_data)); switch (info_level) { @@ -7232,7 +7212,7 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, return NT_STATUS_INVALID_LEVEL; } status = smb_set_file_unix_link(conn, req, pdata, - total_data, fname); + total_data, smb_fname); break; } @@ -7263,8 +7243,7 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, pdata, total_data, fsp, - fname, - &sbuf); + smb_fname); break; } #endif @@ -7289,8 +7268,7 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, status = smb_posix_open(conn, req, ppdata, total_data, - fname, - &sbuf, + smb_fname, &data_return_size); break; } -- cgit From 8f5ef1063354b4ce32dfc9122e8221e2fea88890 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Sun, 5 Jul 2009 09:21:07 +0200 Subject: Revert "net: Use samba default command line arguments." This reverts commit fb262f79fab00374023e59476e8d05a1015a7041 and related commits c36031778e1983ddb11d3e1fcab35e738dbf94bc 72fd5fa6bb78a054fad5e5ebe19a0c0387a7d45b and 38cd0e086f50ce54d88a19aa5a6803469af90489 This change caused more trouble than it solved. We need to do this differently. Reverting so we don't accidently release this. --- source3/utils/net.c | 43 ++++++++++++---- source3/utils/net.h | 9 +++- source3/utils/net_ads.c | 83 +++++++++++++++--------------- source3/utils/net_dom.c | 8 ++- source3/utils/net_help.c | 1 - source3/utils/net_proto.h | 3 ++ source3/utils/net_rpc.c | 74 +++++++++------------------ source3/utils/net_rpc_join.c | 3 +- source3/utils/net_rpc_samsync.c | 4 +- source3/utils/net_rpc_shell.c | 9 ++-- source3/utils/net_util.c | 109 +++++++++++++++++++++++++++++++++------- 11 files changed, 209 insertions(+), 137 deletions(-) (limited to 'source3') diff --git a/source3/utils/net.c b/source3/utils/net.c index 9f29ac42fe..f8bfab3e99 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -625,6 +625,7 @@ static struct functable net_func[] = { int main(int argc, const char **argv) { int opt,i; + char *p; int rc = 0; int argc_new = 0; const char ** argv_new; @@ -635,10 +636,12 @@ static struct functable net_func[] = { struct poptOption long_options[] = { {"help", 'h', POPT_ARG_NONE, 0, 'h'}, {"workgroup", 'w', POPT_ARG_STRING, &c->opt_target_workgroup}, + {"user", 'U', POPT_ARG_STRING, &c->opt_user_name, 'U'}, {"ipaddress", 'I', POPT_ARG_STRING, 0,'I'}, {"port", 'p', POPT_ARG_INT, &c->opt_port}, {"myname", 'n', POPT_ARG_STRING, &c->opt_requester_name}, {"server", 'S', POPT_ARG_STRING, &c->opt_host}, + {"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" }, {"container", 'c', POPT_ARG_STRING, &c->opt_container}, {"comment", 'C', POPT_ARG_STRING, &c->opt_comment}, {"maxusers", 'M', POPT_ARG_INT, &c->opt_maxusers}, @@ -649,13 +652,15 @@ static struct functable net_func[] = { {"stdin", 'i', POPT_ARG_NONE, &c->opt_stdin}, {"timeout", 't', POPT_ARG_INT, &c->opt_timeout}, {"request-timeout",0,POPT_ARG_INT, &c->opt_request_timeout}, + {"machine-pass",'P', POPT_ARG_NONE, &c->opt_machine_pass}, + {"kerberos", 'k', POPT_ARG_NONE, &c->opt_kerberos}, {"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup}, {"verbose", 'v', POPT_ARG_NONE, &c->opt_verbose}, {"test", 'T', POPT_ARG_NONE, &c->opt_testmode}, /* Options for 'net groupmap set' */ {"local", 'L', POPT_ARG_NONE, &c->opt_localgroup}, {"domain", 'D', POPT_ARG_NONE, &c->opt_domaingroup}, - {"ntname", 0, POPT_ARG_STRING, &c->opt_newntname}, + {"ntname", 'N', POPT_ARG_STRING, &c->opt_newntname}, {"rid", 'R', POPT_ARG_INT, &c->opt_rid}, /* Options for 'net rpc share migrate' */ {"acls", 0, POPT_ARG_NONE, &c->opt_acls}, @@ -670,7 +675,6 @@ static struct functable net_func[] = { {"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries}, POPT_COMMON_SAMBA - POPT_COMMON_CREDENTIALS { 0, 0, 0, 0} }; @@ -684,13 +688,6 @@ static struct functable net_func[] = { dbf = x_stderr; c->private_data = net_func; - c->auth_info = user_auth_info_init(frame); - if (c->auth_info == NULL) { - d_fprintf(stderr, "\nOut of memory!\n"); - exit(1); - } - popt_common_set_auth_info(c->auth_info); - pc = poptGetContext(NULL, argc, (const char **) argv, long_options, POPT_CONTEXT_KEEP_FIRST); @@ -698,7 +695,9 @@ static struct functable net_func[] = { switch (opt) { case 'h': c->display_usage = true; - set_cmdline_auth_info_password(c->auth_info, ""); + break; + case 'e': + c->smb_encrypt = true; break; case 'I': if (!interpret_string_addr(&c->opt_dest_ip, @@ -708,6 +707,15 @@ static struct functable net_func[] = { c->opt_have_ip = true; } break; + case 'U': + c->opt_user_specified = true; + c->opt_user_name = SMB_STRDUP(c->opt_user_name); + p = strchr(c->opt_user_name,'%'); + if (p) { + *p = 0; + c->opt_password = p+1; + } + break; default: d_fprintf(stderr, "\nInvalid option %s: %s\n", poptBadOption(pc, 0), poptStrerror(opt)); @@ -741,6 +749,10 @@ static struct functable net_func[] = { set_global_myname(c->opt_requester_name); } + if (!c->opt_user_name && getenv("LOGNAME")) { + c->opt_user_name = getenv("LOGNAME"); + } + if (!c->opt_workgroup) { c->opt_workgroup = smb_xstrdup(lp_workgroup()); } @@ -758,6 +770,17 @@ static struct functable net_func[] = { that it won't assert becouse we are not root */ sec_init(); + if (c->opt_machine_pass) { + /* it is very useful to be able to make ads queries as the + machine account for testing purposes and for domain leave */ + + net_use_krb_machine_account(c); + } + + if (!c->opt_password) { + c->opt_password = getenv("PASSWD"); + } + rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func); DEBUG(2,("return code = %d\n", rc)); diff --git a/source3/utils/net.h b/source3/utils/net.h index f604d96361..d88f962d41 100644 --- a/source3/utils/net.h +++ b/source3/utils/net.h @@ -28,8 +28,11 @@ struct net_context { const char *opt_requester_name; const char *opt_host; - int opt_long_list_entries; + const char *opt_password; + const char *opt_user_name; + bool opt_user_specified; const char *opt_workgroup; + int opt_long_list_entries; int opt_reboot; int opt_force; int opt_stdin; @@ -42,6 +45,7 @@ struct net_context { int opt_timeout; int opt_request_timeout; const char *opt_target_workgroup; + int opt_machine_pass; int opt_localgroup; int opt_domaingroup; int do_talloc_report; @@ -53,14 +57,15 @@ struct net_context { const char *opt_exclude; const char *opt_destination; int opt_testmode; + bool opt_kerberos; int opt_force_full_repl; int opt_single_obj_repl; int opt_clean_old_entries; int opt_have_ip; struct sockaddr_storage opt_dest_ip; + bool smb_encrypt; struct libnetapi_ctx *netapi_ctx; - struct user_auth_info *auth_info; bool display_usage; void *private_data; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index f746fc6bd5..8f76c0eb09 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -231,23 +231,32 @@ retry_connect: ads = ads_init(realm, c->opt_target_workgroup, c->opt_host); + if (!c->opt_user_name) { + c->opt_user_name = "administrator"; + } + + if (c->opt_user_specified) { + need_password = true; + } + retry: - if (need_password) { - set_cmdline_auth_info_getpass(c->auth_info); + if (!c->opt_password && need_password && !c->opt_machine_pass) { + c->opt_password = net_prompt_pass(c, c->opt_user_name); + if (!c->opt_password) { + ads_destroy(&ads); + return ADS_ERROR(LDAP_NO_MEMORY); + } } - if (get_cmdline_auth_info_got_pass(c->auth_info) || - !get_cmdline_auth_info_use_kerberos(c->auth_info)) { + if (c->opt_password) { use_in_memory_ccache(); SAFE_FREE(ads->auth.password); - ads->auth.password = smb_xstrdup( - get_cmdline_auth_info_password(c->auth_info)); + ads->auth.password = smb_xstrdup(c->opt_password); } ads->auth.flags |= auth_flags; SAFE_FREE(ads->auth.user_name); - ads->auth.user_name = smb_xstrdup( - get_cmdline_auth_info_username(c->auth_info)); + ads->auth.user_name = smb_xstrdup(c->opt_user_name); /* * If the username is of the form "name@realm", @@ -866,7 +875,6 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv) TALLOC_CTX *ctx; struct libnet_UnjoinCtx *r = NULL; WERROR werr; - struct user_auth_info *ai = c->auth_info; if (c->display_usage) { d_printf("Usage:\n" @@ -885,7 +893,7 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv) return -1; } - if (!get_cmdline_auth_info_use_kerberos(ai)) { + if (!c->opt_kerberos) { use_in_memory_ccache(); } @@ -895,14 +903,12 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv) return -1; } - set_cmdline_auth_info_getpass(ai); - r->in.debug = true; - r->in.use_kerberos = get_cmdline_auth_info_use_kerberos(ai); + r->in.use_kerberos = c->opt_kerberos; r->in.dc_name = c->opt_host; r->in.domain_name = lp_realm(); - r->in.admin_account = get_cmdline_auth_info_username(ai); - r->in.admin_password = get_cmdline_auth_info_password(ai); + r->in.admin_account = c->opt_user_name; + r->in.admin_password = net_prompt_pass(c, c->opt_user_name); r->in.modify_config = lp_config_backend_is_registry(); /* Try to delete it, but if that fails, disable it. The @@ -960,8 +966,7 @@ static NTSTATUS net_ads_join_ok(struct net_context *c) return NT_STATUS_ACCESS_DENIED; } - set_cmdline_auth_info_use_machine_account(c->auth_info); - set_cmdline_auth_info_machine_account_creds(c->auth_info); + net_use_krb_machine_account(c); status = ads_startup(c, true, &ads); if (!ADS_ERR_OK(status)) { @@ -1192,7 +1197,6 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) const char *os_name = NULL; const char *os_version = NULL; bool modify_config = lp_config_backend_is_registry(); - struct user_auth_info *ai = c->auth_info;; if (c->display_usage) return net_ads_join_usage(c, argc, argv); @@ -1212,7 +1216,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) goto fail; } - if (!get_cmdline_auth_info_use_kerberos(ai)) { + if (!c->opt_kerberos) { use_in_memory_ccache(); } @@ -1262,8 +1266,6 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) /* Do the domain join here */ - set_cmdline_auth_info_getpass(ai); - r->in.domain_name = domain; r->in.create_upn = createupn; r->in.upn = machineupn; @@ -1271,10 +1273,10 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) r->in.os_name = os_name; r->in.os_version = os_version; r->in.dc_name = c->opt_host; - r->in.admin_account = get_cmdline_auth_info_username(ai); - r->in.admin_password = get_cmdline_auth_info_password(ai); + r->in.admin_account = c->opt_user_name; + r->in.admin_password = net_prompt_pass(c, c->opt_user_name); r->in.debug = true; - r->in.use_kerberos = get_cmdline_auth_info_use_kerberos(ai); + r->in.use_kerberos = c->opt_kerberos; r->in.modify_config = modify_config; r->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE | @@ -1585,7 +1587,6 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char * char *prt_dn, *srv_dn, **srv_cn; char *srv_cn_escaped = NULL, *printername_escaped = NULL; LDAPMessage *res = NULL; - struct user_auth_info *ai = c->auth_info; if (argc < 1 || c->display_usage) { d_printf("Usage:\n" @@ -1617,9 +1618,8 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char * nt_status = cli_full_connection(&cli, global_myname(), servername, &server_ss, 0, "IPC$", "IPC", - get_cmdline_auth_info_username(ai), - c->opt_workgroup, - get_cmdline_auth_info_password(ai), + c->opt_user_name, c->opt_workgroup, + c->opt_password ? c->opt_password : "", CLI_FULL_CONNECTION_USE_KERBEROS, Undefined, NULL); @@ -1807,8 +1807,8 @@ static int net_ads_printer(struct net_context *c, int argc, const char **argv) static int net_ads_password(struct net_context *c, int argc, const char **argv) { ADS_STRUCT *ads; - const char *auth_principal; - const char *auth_password; + const char *auth_principal = c->opt_user_name; + const char *auth_password = c->opt_password; char *realm = NULL; char *new_password = NULL; char *chr, *prompt; @@ -1823,9 +1823,10 @@ static int net_ads_password(struct net_context *c, int argc, const char **argv) return 0; } - auth_principal = get_cmdline_auth_info_username(c->auth_info); - set_cmdline_auth_info_getpass(c->auth_info); - auth_password = get_cmdline_auth_info_password(c->auth_info); + if (c->opt_user_name == NULL || c->opt_password == NULL) { + d_fprintf(stderr, "You must supply an administrator username/password\n"); + return -1; + } if (argc < 1) { d_fprintf(stderr, "ERROR: You must say which username to change password for\n"); @@ -1907,7 +1908,7 @@ int net_ads_changetrustpw(struct net_context *c, int argc, const char **argv) return -1; } - set_cmdline_auth_info_use_machine_account(c->auth_info); + net_use_krb_machine_account(c); use_in_memory_ccache(); @@ -2289,7 +2290,6 @@ static int net_ads_kerberos_pac(struct net_context *c, int argc, const char **ar TALLOC_CTX *mem_ctx = NULL; NTSTATUS status; int ret = -1; - struct user_auth_info *ai = c->auth_info; if (c->display_usage) { d_printf("Usage:\n" @@ -2303,11 +2303,11 @@ static int net_ads_kerberos_pac(struct net_context *c, int argc, const char **ar goto out; } - set_cmdline_auth_info_getpass(ai); + c->opt_password = net_prompt_pass(c, c->opt_user_name); status = kerberos_return_pac(mem_ctx, - get_cmdline_auth_info_username(ai), - get_cmdline_auth_info_password(ai), + c->opt_user_name, + c->opt_password, 0, NULL, NULL, @@ -2340,7 +2340,6 @@ static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char ** TALLOC_CTX *mem_ctx = NULL; int ret = -1; NTSTATUS status; - struct user_auth_info *ai = c->auth_info; if (c->display_usage) { d_printf("Usage:\n" @@ -2354,10 +2353,10 @@ static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char ** goto out; } - set_cmdline_auth_info_getpass(ai); + c->opt_password = net_prompt_pass(c, c->opt_user_name); - ret = kerberos_kinit_password_ext(get_cmdline_auth_info_username(ai), - get_cmdline_auth_info_password(ai), + ret = kerberos_kinit_password_ext(c->opt_user_name, + c->opt_password, 0, NULL, NULL, diff --git a/source3/utils/net_dom.c b/source3/utils/net_dom.c index a13f52c519..401079777f 100644 --- a/source3/utils/net_dom.c +++ b/source3/utils/net_dom.c @@ -368,11 +368,9 @@ int net_dom(struct net_context *c, int argc, const char **argv) return -1; } - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c index 5a170790c5..0502373aa2 100644 --- a/source3/utils/net_help.c +++ b/source3/utils/net_help.c @@ -65,6 +65,5 @@ int net_help(struct net_context *c, int argc, const char **argv) } c->display_usage = true; - set_cmdline_auth_info_password(c->auth_info, ""); return net_run_function(c, argc, argv, "net help", func); } diff --git a/source3/utils/net_proto.h b/source3/utils/net_proto.h index 8a09147aad..75ac032db9 100644 --- a/source3/utils/net_proto.h +++ b/source3/utils/net_proto.h @@ -459,6 +459,8 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c, NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst, struct rpc_pipe_client **pp_pipe_hnd, const struct ndr_syntax_id *interface); +int net_use_krb_machine_account(struct net_context *c); +int net_use_machine_account(struct net_context *c); bool net_find_server(struct net_context *c, const char *domain, unsigned flags, @@ -473,6 +475,7 @@ NTSTATUS net_make_ipc_connection_ex(struct net_context *c ,const char *domain, const char *server, struct sockaddr_storage *pss, unsigned flags, struct cli_state **pcli); +const char *net_prompt_pass(struct net_context *c, const char *user); int net_run_function(struct net_context *c, int argc, const char **argv, const char *whoami, struct functable *table); void net_display_usage_from_functable(struct functable *table); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 0118b4818a..f6f90030fe 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -25,8 +25,7 @@ #include "../libcli/auth/libcli_auth.h" static int net_mode_share; -static bool sync_files(struct copy_clistate *cp_clistate, const char *mask, - const struct user_auth_info *auth_info); +static bool sync_files(struct copy_clistate *cp_clistate, const char *mask); /** * @file net_rpc.c @@ -123,7 +122,6 @@ int run_rpc_command(struct net_context *c, DOM_SID *domain_sid; const char *domain_name; int ret = -1; - struct user_auth_info *ai = c->auth_info; /* make use of cli_state handed over as an argument, if possible */ if (!cli_arg) { @@ -173,10 +171,8 @@ int run_rpc_command(struct net_context *c, nt_status = cli_rpc_pipe_open_ntlmssp( cli, interface, PIPE_AUTH_LEVEL_PRIVACY, - lp_workgroup(), - get_cmdline_auth_info_username(ai), - get_cmdline_auth_info_password(ai), - &pipe_hnd); + lp_workgroup(), c->opt_user_name, + c->opt_password, &pipe_hnd); } else { nt_status = cli_rpc_pipe_open_noauth( cli, interface, @@ -944,12 +940,9 @@ int net_rpc_user(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - set_cmdline_auth_info_getpass(c->auth_info); - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } @@ -2763,12 +2756,9 @@ int net_rpc_group(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - set_cmdline_auth_info_getpass(c->auth_info); - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } @@ -3255,7 +3245,7 @@ static void copy_fn(const char *mnt, file_info *f, old_dir = local_state->cwd; local_state->cwd = dir; - if (!sync_files(local_state, new_mask, c->auth_info)) + if (!sync_files(local_state, new_mask)) printf("could not handle files\n"); local_state->cwd = old_dir; @@ -3302,18 +3292,15 @@ static void copy_fn(const char *mnt, file_info *f, * * @return Boolean result **/ -static bool sync_files(struct copy_clistate *cp_clistate, const char *mask, - const struct user_auth_info *auth_info) +static bool sync_files(struct copy_clistate *cp_clistate, const char *mask) { struct cli_state *targetcli; char *targetpath = NULL; DEBUG(3,("calling cli_list with mask: %s\n", mask)); - - if ( !cli_resolve_path(talloc_tos(), "", auth_info, - cp_clistate->cli_share_src, mask, &targetcli, - &targetpath ) ) { + if ( !cli_resolve_path(talloc_tos(), "", NULL, cp_clistate->cli_share_src, + mask, &targetcli, &targetpath ) ) { d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n", mask, cli_errstr(cp_clistate->cli_share_src)); return false; @@ -3476,7 +3463,7 @@ static NTSTATUS rpc_share_migrate_files_internals(struct net_context *c, goto done; } - if (!sync_files(&cp_clistate, mask, c->auth_info)) { + if (!sync_files(&cp_clistate, mask)) { d_fprintf(stderr, "could not handle files for share: %s\n", info502.name); nt_status = NT_STATUS_UNSUCCESSFUL; goto done; @@ -4577,12 +4564,9 @@ int net_rpc_share(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - set_cmdline_auth_info_getpass(c->auth_info); - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } @@ -4855,12 +4839,9 @@ int net_rpc_file(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - set_cmdline_auth_info_getpass(c->auth_info); - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } @@ -5550,7 +5531,7 @@ static int rpc_trustdom_establish(struct net_context *c, int argc, c->opt_workgroup = smb_xstrdup(domain_name); }; - set_cmdline_auth_info_username(c->auth_info, acct_name); + c->opt_user_name = acct_name; /* find the domain controller */ if (!net_find_pdc(&server_ss, pdc_name, domain_name)) { @@ -5647,9 +5628,7 @@ static int rpc_trustdom_establish(struct net_context *c, int argc, * Store the password in secrets db */ - if (!pdb_set_trusteddom_pw(domain_name, - get_cmdline_auth_info_password(c->auth_info), - domain_sid)) { + if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) { DEBUG(0, ("Storing password for trusted domain failed.\n")); cli_shutdown(cli); talloc_destroy(mem_ctx); @@ -7211,12 +7190,9 @@ int net_rpc(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - set_cmdline_auth_info_getpass(c->auth_info); - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index cae2491aed..ed0311317d 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -58,8 +58,7 @@ NTSTATUS net_rpc_join_ok(struct net_context *c, const char *domain, if (sec == SEC_ADS) { /* Connect to IPC$ using machine account's credentials. We don't use anonymous connection here, as it may be denied by server's local policy. */ - set_cmdline_auth_info_use_machine_account(c->auth_info); - set_cmdline_auth_info_machine_account_creds(c->auth_info); + net_use_machine_account(c); } else { /* some servers (e.g. WinNT) don't accept machine-authenticated diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index c0de247e7f..309be171cc 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -379,8 +379,8 @@ NTSTATUS rpc_vampire_keytab_internals(struct net_context *c, ctx->cli = pipe_hnd; ctx->ops = &libnet_samsync_keytab_ops; ctx->domain_name = domain_name; - ctx->username = get_cmdline_auth_info_username(c->auth_info); - ctx->password = get_cmdline_auth_info_password(c->auth_info); + ctx->username = c->opt_user_name; + ctx->password = c->opt_password; ctx->force_full_replication = c->opt_force_full_repl ? true : false; ctx->clean_old_entries = c->opt_clean_old_entries ? true : false; diff --git a/source3/utils/net_rpc_shell.c b/source3/utils/net_rpc_shell.c index dc13e91423..3aaed1ed18 100644 --- a/source3/utils/net_rpc_shell.c +++ b/source3/utils/net_rpc_shell.c @@ -220,12 +220,9 @@ int net_rpc_shell(struct net_context *c, int argc, const char **argv) if (libnetapi_init(&c->netapi_ctx) != 0) { return -1; } - set_cmdline_auth_info_getpass(c->auth_info); - libnetapi_set_username(c->netapi_ctx, - get_cmdline_auth_info_username(c->auth_info)); - libnetapi_set_password(c->netapi_ctx, - get_cmdline_auth_info_password(c->auth_info)); - if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { + libnetapi_set_username(c->netapi_ctx, c->opt_user_name); + libnetapi_set_password(c->netapi_ctx, c->opt_password); + if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c index 50f3c1db01..8bf9aac6f2 100644 --- a/source3/utils/net_util.c +++ b/source3/utils/net_util.c @@ -96,22 +96,22 @@ NTSTATUS connect_to_service(struct net_context *c, { NTSTATUS nt_status; int flags = 0; - struct user_auth_info *ai = c->auth_info; - set_cmdline_auth_info_getpass(ai); + c->opt_password = net_prompt_pass(c, c->opt_user_name); - if (get_cmdline_auth_info_use_kerberos(ai)) { - flags |= CLI_FULL_CONNECTION_USE_KERBEROS | - CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; + if (c->opt_kerberos) { + flags |= CLI_FULL_CONNECTION_USE_KERBEROS; + } + + if (c->opt_kerberos && c->opt_password) { + flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; } nt_status = cli_full_connection(cli_ctx, NULL, server_name, server_ss, c->opt_port, service_name, service_type, - get_cmdline_auth_info_username(ai), - c->opt_workgroup, - get_cmdline_auth_info_password(ai), - flags, Undefined, NULL); + c->opt_user_name, c->opt_workgroup, + c->opt_password, flags, Undefined, NULL); if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, "Could not connect to server %s\n", server_name); @@ -131,10 +131,10 @@ NTSTATUS connect_to_service(struct net_context *c, return nt_status; } - if (get_cmdline_auth_info_smb_encrypt(ai)) { + if (c->smb_encrypt) { nt_status = cli_force_encryption(*cli_ctx, - get_cmdline_auth_info_username(ai), - get_cmdline_auth_info_password(ai), + c->opt_user_name, + c->opt_password, c->opt_workgroup); if (NT_STATUS_EQUAL(nt_status,NT_STATUS_NOT_SUPPORTED)) { @@ -234,12 +234,14 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c, { NTSTATUS nt_status; char *user_and_realm = NULL; - struct user_auth_info *ai = c->auth_info; /* FIXME: Should get existing kerberos ticket if possible. */ - set_cmdline_auth_info_getpass(ai); + c->opt_password = net_prompt_pass(c, c->opt_user_name); + if (!c->opt_password) { + return NT_STATUS_NO_MEMORY; + } - user_and_realm = get_user_and_realm(get_cmdline_auth_info_username(ai)); + user_and_realm = get_user_and_realm(c->opt_user_name); if (!user_and_realm) { return NT_STATUS_NO_MEMORY; } @@ -248,7 +250,7 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c, server_ss, c->opt_port, "IPC$", "IPC", user_and_realm, c->opt_workgroup, - get_cmdline_auth_info_password(ai), + c->opt_password, CLI_FULL_CONNECTION_USE_KERBEROS, Undefined, NULL); @@ -259,10 +261,10 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c, return nt_status; } - if (get_cmdline_auth_info_smb_encrypt(ai)) { + if (c->smb_encrypt) { nt_status = cli_cm_force_encryption(*cli_ctx, user_and_realm, - get_cmdline_auth_info_password(ai), + c->opt_password, c->opt_workgroup, "IPC$"); if (!NT_STATUS_IS_OK(nt_status)) { @@ -326,6 +328,50 @@ NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst, return nt_status; } +/**************************************************************************** + Use the local machine account (krb) and password for this session. +****************************************************************************/ + +int net_use_krb_machine_account(struct net_context *c) +{ + char *user_name = NULL; + + if (!secrets_init()) { + d_fprintf(stderr, "ERROR: Unable to open secrets database\n"); + exit(1); + } + + c->opt_password = secrets_fetch_machine_password( + c->opt_target_workgroup, NULL, NULL); + if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) { + return -1; + } + c->opt_user_name = user_name; + return 0; +} + +/**************************************************************************** + Use the machine account name and password for this session. +****************************************************************************/ + +int net_use_machine_account(struct net_context *c) +{ + char *user_name = NULL; + + if (!secrets_init()) { + d_fprintf(stderr, "ERROR: Unable to open secrets database\n"); + exit(1); + } + + c->opt_password = secrets_fetch_machine_password( + c->opt_target_workgroup, NULL, NULL); + if (asprintf(&user_name, "%s$", global_myname()) == -1) { + return -1; + } + c->opt_user_name = user_name; + return 0; +} + bool net_find_server(struct net_context *c, const char *domain, unsigned flags, @@ -489,6 +535,33 @@ done: /**************************************************************************** ****************************************************************************/ +const char *net_prompt_pass(struct net_context *c, const char *user) +{ + char *prompt = NULL; + const char *pass = NULL; + + if (c->opt_password) { + return c->opt_password; + } + + if (c->opt_machine_pass) { + return NULL; + } + + if (c->opt_kerberos && !c->opt_user_specified) { + return NULL; + } + + if (asprintf(&prompt, "Enter %s's password:", user) == -1) { + return NULL; + } + + pass = getpass(prompt); + SAFE_FREE(prompt); + + return pass; +} + int net_run_function(struct net_context *c, int argc, const char **argv, const char *whoami, struct functable *table) { -- cgit From 4b42927ec31a0819b1e5ec415fd1a16061cff677 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 13:57:56 -0700 Subject: s3: Convert some callers of vfs_stat_smb_fname to SMB_VFS_STAT() --- source3/smbd/globals.h | 1 - source3/smbd/posix_acls.c | 24 ++++++++++++++++++------ source3/smbd/smb2_getinfo.c | 10 ---------- source3/smbd/trans2.c | 28 +++++++++++++++++++--------- 4 files changed, 37 insertions(+), 26 deletions(-) (limited to 'source3') diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index cd3e054d1a..434204b60d 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -213,7 +213,6 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, NTSTATUS smbd_do_qfsinfo(connection_struct *conn, TALLOC_CTX *mem_ctx, uint16_t info_level, - SMB_STRUCT_STAT st, uint16_t flags2, unsigned int max_data_bytes, char **ppdata, diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index fb2cda40ce..0a3b0dff75 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3372,33 +3372,45 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, uint32_t security_info, SEC_DESC **ppdesc) { - SMB_STRUCT_STAT sbuf; SMB_ACL_T posix_acl = NULL; SMB_ACL_T def_acl = NULL; struct pai_val *pal; + struct smb_filename *smb_fname = NULL; + NTSTATUS status; *ppdesc = NULL; DEBUG(10,("posix_get_nt_acl: called for file %s\n", name )); + status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + /* Get the stat struct for the owner info. */ - if(vfs_stat_smb_fname(conn, name, &sbuf) != 0) { - return map_nt_error_from_unix(errno); + if(SMB_VFS_STAT(conn, smb_fname) != 0) { + status = map_nt_error_from_unix(errno); + goto out; } /* Get the ACL from the path. */ posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_ACCESS); /* If it's a directory get the default POSIX ACL. */ - if(S_ISDIR(sbuf.st_ex_mode)) { + if(S_ISDIR(smb_fname->st.st_ex_mode)) { def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_DEFAULT); def_acl = free_empty_sys_acl(conn, def_acl); } pal = load_inherited_info(conn, name); - return posix_get_nt_acl_common(conn, name, &sbuf, pal, posix_acl, - def_acl, security_info, ppdesc); + status = posix_get_nt_acl_common(conn, name, &smb_fname->st, pal, + posix_acl, def_acl, security_info, + ppdesc); + out: + TALLOC_FREE(smb_fname); + return status; } /**************************************************************************** diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index dda79c209f..5a6e3d7ecb 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -367,22 +367,12 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, char *data = NULL; int data_size = 0; NTSTATUS status; - SMB_STRUCT_STAT st; /* the levels directly map to the passthru levels */ file_info_level = in_file_info_class + 1000; - if (vfs_stat_smb_fname(conn,".",&st)!=0) { - DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", - strerror(errno))); - status = map_nt_error_from_unix(errno); - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); - } - status = smbd_do_qfsinfo(conn, state, file_info_level, - st, STR_UNICODE, in_output_buffer_length, &data, diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index cac0147c4d..856fd9432d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2682,7 +2682,6 @@ static void samba_extended_info_version(struct smb_extended_info *extended_info) NTSTATUS smbd_do_qfsinfo(connection_struct *conn, TALLOC_CTX *mem_ctx, uint16_t info_level, - SMB_STRUCT_STAT st, uint16_t flags2, unsigned int max_data_bytes, char **ppdata, @@ -2694,6 +2693,9 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, int snum = SNUM(conn); char *fstype = lp_fstype(SNUM(conn)); uint32 additional_flags = 0; + struct smb_filename *smb_fname_dot = NULL; + SMB_STRUCT_STAT st; + NTSTATUS status; if (IS_IPC(conn)) { if (info_level != SMB_QUERY_CIFS_UNIX_INFO) { @@ -2706,6 +2708,21 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level)); + status = create_synthetic_smb_fname(talloc_tos(), ".", NULL, NULL, + &smb_fname_dot); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if(SMB_VFS_STAT(conn, smb_fname_dot) != 0) { + DEBUG(2,("stat of . failed (%s)\n", strerror(errno))); + TALLOC_FREE(smb_fname_dot); + return map_nt_error_from_unix(errno); + } + + st = smb_fname_dot->st; + TALLOC_FREE(smb_fname_dot); + *ppdata = (char *)SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); if (*ppdata == NULL) { @@ -3228,7 +3245,6 @@ static void call_trans2qfsinfo(connection_struct *conn, char *params = *pparams; uint16_t info_level; int data_len = 0; - SMB_STRUCT_STAT st; NTSTATUS status; if (total_params < 2) { @@ -3251,14 +3267,8 @@ static void call_trans2qfsinfo(connection_struct *conn, DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level)); - if(vfs_stat_smb_fname(conn,".",&st)!=0) { - DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno))); - reply_doserror(req, ERRSRV, ERRinvdevice); - return; - } - status = smbd_do_qfsinfo(conn, req, - info_level, st, + info_level, req->flags2, max_data_bytes, ppdata, &data_len); -- cgit From 83284e13f91f685b8dcccb9202e33fe64e6930b2 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 21 Jul 2009 15:55:25 -0700 Subject: s3: Convert some callers of vfs_lstat_smb_fname to SMB_VFS_LSTAT() --- source3/smbd/msdfs.c | 20 ++++++++++++++------ source3/smbd/vfs.c | 19 ++++++++++++++++--- 2 files changed, 30 insertions(+), 9 deletions(-) (limited to 'source3') diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index d40b8a8902..2b63eb1743 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -411,7 +411,6 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx, char **pp_link_target, SMB_STRUCT_STAT *sbufp) { - SMB_STRUCT_STAT st; int referral_len = 0; #if defined(HAVE_BROKEN_READLINK) char link_target_buf[PATH_MAX]; @@ -420,6 +419,8 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx, #endif size_t bufsize = 0; char *link_target = NULL; + struct smb_filename *smb_fname = NULL; + NTSTATUS status; if (pp_link_target) { bufsize = 1024; @@ -433,21 +434,28 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx, link_target = link_target_buf; } - if (sbufp == NULL) { - sbufp = &st; + status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + goto err; } - if (vfs_lstat_smb_fname(conn, path, sbufp) != 0) { + if (SMB_VFS_LSTAT(conn, smb_fname) != 0) { DEBUG(5,("is_msdfs_link_read_target: %s does not exist.\n", path)); + TALLOC_FREE(smb_fname); goto err; } - - if (!S_ISLNK(sbufp->st_ex_mode)) { + if (!S_ISLNK(smb_fname->st.st_ex_mode)) { DEBUG(5,("is_msdfs_link_read_target: %s is not a link.\n", path)); + TALLOC_FREE(smb_fname); goto err; } + if (sbufp != NULL) { + *sbufp = smb_fname->st; + } + TALLOC_FREE(smb_fname); referral_len = SMB_VFS_READLINK(conn, path, link_target, bufsize - 1); if (referral_len == -1) { diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 55495183bd..cd78c7962e 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -972,15 +972,28 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) #ifdef S_ISLNK if (!lp_symlinks(SNUM(conn))) { - SMB_STRUCT_STAT statbuf; - if ( (vfs_lstat_smb_fname(conn,fname,&statbuf) != -1) && - (S_ISLNK(statbuf.st_ex_mode)) ) { + struct smb_filename *smb_fname = NULL; + NTSTATUS status; + + status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, + NULL, &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + if (free_resolved_name) { + SAFE_FREE(resolved_name); + } + return status; + } + + if ( (SMB_VFS_LSTAT(conn, smb_fname) != -1) && + (S_ISLNK(smb_fname->st.st_ex_mode)) ) { if (free_resolved_name) { SAFE_FREE(resolved_name); } DEBUG(3,("reduce_name: denied: file path name %s is a symlink\n",resolved_name)); + TALLOC_FREE(smb_fname); return NT_STATUS_ACCESS_DENIED; } + TALLOC_FREE(smb_fname); } #endif -- cgit From 07d3b69b55c37f26ba6fa8b0c1c59e800325b435 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Wed, 22 Jul 2009 09:52:09 -0700 Subject: s3: Change unix_convert to use an smb_filename struct internally This allows SMB_VFS_[L]STAT to be called directly. Additionally, I changed NTSTATUS result to be named status for consistency. I also removed the stat_cache_add() from build_stream_path() because stat_cache_lookup() is never actually called on a file with a stream. There is no reason why the stat cache couldn't be consulted for streams in the future. Jeremy/Volker, please take a look at this one when you get a chance. --- source3/smbd/filename.c | 291 +++++++++++++++++++++++++---------------------- source3/smbd/statcache.c | 15 ++- 2 files changed, 168 insertions(+), 138 deletions(-) (limited to 'source3') diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 541b0cd3cb..09f9a418bd 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -117,23 +117,21 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, struct smb_filename **smb_fname_out, uint32_t ucf_flags) { - SMB_STRUCT_STAT st; struct smb_filename *smb_fname = NULL; char *start, *end; char *dirpath = NULL; - char *name = NULL; char *stream = NULL; bool component_was_mangled = False; bool name_has_wildcard = False; bool posix_pathnames = false; bool allow_wcard_last_component = ucf_flags & UCF_ALLOW_WCARD_LCOMP; bool save_last_component = ucf_flags & UCF_SAVE_LCOMP; - NTSTATUS result; + NTSTATUS status; int ret = -1; *smb_fname_out = NULL; - smb_fname = talloc_zero(talloc_tos(), struct smb_filename); + smb_fname = talloc_zero(ctx, struct smb_filename); if (smb_fname == NULL) { return NT_STATUS_NO_MEMORY; } @@ -143,10 +141,10 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, filename - so don't convert them */ if (!(smb_fname->base_name = talloc_strdup(smb_fname, orig_path))) { - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } - *smb_fname_out = smb_fname; - return NT_STATUS_OK; + goto done; } DEBUG(5, ("unix_convert called on file \"%s\"\n", orig_path)); @@ -174,15 +172,16 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, */ if (!*orig_path) { - if (!(name = talloc_strdup(ctx,"."))) { - return NT_STATUS_NO_MEMORY; + if (!(smb_fname->base_name = talloc_strdup(smb_fname, "."))) { + status = NT_STATUS_NO_MEMORY; + goto err; } - if (vfs_stat_smb_fname(conn,name,&st) == 0) { - smb_fname->st = st; - } else { - return map_nt_error_from_unix(errno); + if (SMB_VFS_STAT(conn, smb_fname) != 0) { + status = map_nt_error_from_unix(errno); + goto err; } - DEBUG(5,("conversion finished \"\" -> %s\n",name)); + DEBUG(5, ("conversion finished \"\" -> %s\n", + smb_fname->base_name)); goto done; } @@ -190,17 +189,19 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, orig_path[1] == '\0')) { /* Start of pathname can't be "." only. */ if (orig_path[1] == '\0' || orig_path[2] == '\0') { - result = NT_STATUS_OBJECT_NAME_INVALID; + status = NT_STATUS_OBJECT_NAME_INVALID; } else { - result =determine_path_error( - &orig_path[2], allow_wcard_last_component); + status =determine_path_error(&orig_path[2], + allow_wcard_last_component); } - return result; + goto err; } - if (!(name = talloc_strdup(ctx, orig_path))) { + /* Start with the full orig_path as given by the caller. */ + if (!(smb_fname->base_name = talloc_strdup(smb_fname, orig_path))) { DEBUG(0, ("talloc_strdup failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } /* @@ -214,7 +215,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, if (conn->case_sensitive && !conn->case_preserve && !conn->short_case_preserve) { - strnorm(name, lp_defaultcase(SNUM(conn))); + strnorm(smb_fname->base_name, lp_defaultcase(SNUM(conn))); } /* @@ -222,44 +223,60 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, */ if(save_last_component) { - end = strrchr_m(name, '/'); + end = strrchr_m(smb_fname->base_name, '/'); if (end) { - smb_fname->original_lcomp = talloc_strdup(ctx, + smb_fname->original_lcomp = talloc_strdup(smb_fname, end + 1); } else { - smb_fname->original_lcomp = talloc_strdup(ctx, name); + smb_fname->original_lcomp = + talloc_strdup(smb_fname, smb_fname->base_name); + } + if (smb_fname->original_lcomp == NULL) { + status = NT_STATUS_NO_MEMORY; + goto err; } } posix_pathnames = lp_posix_pathnames(); - /* Strip off the stream. Should we use any of the other stream parsing - * at this point? Also, should we set the is_stream bit? */ + /* + * Strip off the stream, and add it back when we're done with the + * base_name. + */ if (!posix_pathnames) { - stream = strchr_m(name, ':'); + stream = strchr_m(smb_fname->base_name, ':'); if (stream != NULL) { - char *tmp = talloc_strdup(ctx, stream); + char *tmp = talloc_strdup(smb_fname, stream); if (tmp == NULL) { - TALLOC_FREE(name); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } + /* + * Since this is actually pointing into + * smb_fname->base_name this truncates base_name. + */ *stream = '\0'; stream = tmp; } } - start = name; + start = smb_fname->base_name; - /* If we're providing case insentive semantics or + /* + * If we're providing case insentive semantics or * the underlying filesystem is case insensitive, * then a case-normalized hit in the stat-cache is * authoratitive. JRA. + * + * Note: We're only checking base_name. The stream_name will be + * added and verified in build_stream_path(). */ - if((!conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) && - stat_cache_lookup(conn, &name, &dirpath, &start, &st)) { - smb_fname->st = st; + if((!conn->case_sensitive || !(conn->fs_capabilities & + FILE_CASE_SENSITIVE_SEARCH)) && + stat_cache_lookup(conn, &smb_fname->base_name, &dirpath, &start, + &smb_fname->st)) { goto done; } @@ -270,43 +287,46 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, if ((dirpath == NULL) && (!(dirpath = talloc_strdup(ctx,"")))) { DEBUG(0, ("talloc_strdup failed\n")); - TALLOC_FREE(name); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } /* - * stat the name - if it exists then we are all done! + * stat the name - if it exists then we can add the stream back (if + * there was one) and be done! */ if (posix_pathnames) { - ret = vfs_lstat_smb_fname(conn,name,&st); + ret = SMB_VFS_LSTAT(conn, smb_fname); } else { - ret = vfs_stat_smb_fname(conn,name,&st); + ret = SMB_VFS_STAT(conn, smb_fname); } if (ret == 0) { /* Ensure we catch all names with in "/." this is disallowed under Windows. */ - const char *p = strstr(name, "/."); /* mb safe. */ + const char *p = strstr(smb_fname->base_name, "/."); /*mb safe*/ if (p) { if (p[2] == '/') { /* Error code within a pathname. */ - result = NT_STATUS_OBJECT_PATH_NOT_FOUND; + status = NT_STATUS_OBJECT_PATH_NOT_FOUND; goto fail; } else if (p[2] == '\0') { /* Error code at the end of a pathname. */ - result = NT_STATUS_OBJECT_NAME_INVALID; + status = NT_STATUS_OBJECT_NAME_INVALID; goto fail; } } - stat_cache_add(orig_path, name, conn->case_sensitive); - DEBUG(5,("conversion finished %s -> %s\n",orig_path, name)); - smb_fname->st = st; + /* Add the path (not including the stream) to the cache. */ + stat_cache_add(orig_path, smb_fname->base_name, + conn->case_sensitive); + DEBUG(5,("conversion of base_name finished %s -> %s\n", + orig_path, smb_fname->base_name)); goto done; } DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n", - name, dirpath, start)); + smb_fname->base_name, dirpath, start)); /* * A special case - if we don't have any mangling chars and are case @@ -314,8 +334,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, * won't help. */ - if ((conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) && - !mangle_is_mangled(name, conn->params)) { + if ((conn->case_sensitive || !(conn->fs_capabilities & + FILE_CASE_SENSITIVE_SEARCH)) && + !mangle_is_mangled(smb_fname->base_name, conn->params)) { goto done; } @@ -354,11 +375,12 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, if (save_last_component) { TALLOC_FREE(smb_fname->original_lcomp); - smb_fname->original_lcomp = talloc_strdup(ctx, + smb_fname->original_lcomp = talloc_strdup(smb_fname, end ? end + 1 : start); if (!smb_fname->original_lcomp) { DEBUG(0, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } } @@ -367,9 +389,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, if (ISDOT(start)) { if (!end) { /* Error code at the end of a pathname. */ - result = NT_STATUS_OBJECT_NAME_INVALID; + status = NT_STATUS_OBJECT_NAME_INVALID; } else { - result = determine_path_error(end+1, + status = determine_path_error(end+1, allow_wcard_last_component); } goto fail; @@ -382,13 +404,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, /* Wildcard not valid anywhere. */ if (name_has_wildcard && !allow_wcard_last_component) { - result = NT_STATUS_OBJECT_NAME_INVALID; + status = NT_STATUS_OBJECT_NAME_INVALID; goto fail; } /* Wildcards never valid within a pathname. */ if (name_has_wildcard && end) { - result = NT_STATUS_OBJECT_NAME_INVALID; + status = NT_STATUS_OBJECT_NAME_INVALID; goto fail; } @@ -397,9 +419,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, */ if (posix_pathnames) { - ret = vfs_lstat_smb_fname(conn,name, &st); + ret = SMB_VFS_LSTAT(conn, smb_fname); } else { - ret = vfs_stat_smb_fname(conn,name, &st); + ret = SMB_VFS_STAT(conn, smb_fname); } if (ret == 0) { @@ -407,7 +429,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, * It exists. it must either be a directory or this must * be the last part of the path for it to be OK. */ - if (end && !S_ISDIR(st.st_ex_mode)) { + if (end && !S_ISDIR(smb_fname->st.st_ex_mode)) { /* * An intermediate part of the name isn't * a directory. @@ -422,25 +444,15 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, * applications depend on the difference between * these two errors. */ - result = NT_STATUS_OBJECT_PATH_NOT_FOUND; + status = NT_STATUS_OBJECT_PATH_NOT_FOUND; goto fail; } - if (!end) { - /* - * We just scanned for, and found the end of - * the path. We must return the valid stat - * struct. JRA. - */ - - smb_fname->st = st; - } - } else { char *found_name = NULL; /* Stat failed - ensure we don't use it. */ - SET_STAT_INVALID(st); + SET_STAT_INVALID(smb_fname->st); /* * Reset errno so we can detect @@ -486,11 +498,11 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, if (errno == ENOENT || errno == ENOTDIR || errno == ELOOP) { - result = + status = NT_STATUS_OBJECT_PATH_NOT_FOUND; } else { - result = + status = map_nt_error_from_unix(errno); } goto fail; @@ -511,10 +523,10 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, */ if (errno == ENOTDIR || errno == ELOOP) { - result = + status = NT_STATUS_OBJECT_PATH_NOT_FOUND; } else { - result = + status = map_nt_error_from_unix(errno); } goto fail; @@ -546,12 +558,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, &unmangled, conn->params)) { char *tmp; - size_t start_ofs = start - name; + size_t start_ofs = + start - smb_fname->base_name; if (*dirpath != '\0') { - tmp = talloc_asprintf(ctx, - "%s/%s", dirpath, - unmangled); + tmp = talloc_asprintf( + smb_fname, "%s/%s", + dirpath, unmangled); TALLOC_FREE(unmangled); } else { @@ -559,11 +572,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, } if (tmp == NULL) { DEBUG(0, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } - TALLOC_FREE(name); - name = tmp; - start = name + start_ofs; + TALLOC_FREE(smb_fname->base_name); + smb_fname->base_name = tmp; + start = + smb_fname->base_name + start_ofs; end = start + strlen(start); } @@ -578,46 +593,50 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, */ if (end) { char *tmp; - size_t start_ofs = start - name; + size_t start_ofs = + start - smb_fname->base_name; if (*dirpath != '\0') { - tmp = talloc_asprintf(ctx, + tmp = talloc_asprintf(smb_fname, "%s/%s/%s", dirpath, found_name, end+1); } else { - tmp = talloc_asprintf(ctx, + tmp = talloc_asprintf(smb_fname, "%s/%s", found_name, end+1); } if (tmp == NULL) { DEBUG(0, ("talloc_asprintf failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } - TALLOC_FREE(name); - name = tmp; - start = name + start_ofs; + TALLOC_FREE(smb_fname->base_name); + smb_fname->base_name = tmp; + start = smb_fname->base_name + start_ofs; end = start + strlen(found_name); *end = '\0'; } else { char *tmp; - size_t start_ofs = start - name; + size_t start_ofs = + start - smb_fname->base_name; if (*dirpath != '\0') { - tmp = talloc_asprintf(ctx, + tmp = talloc_asprintf(smb_fname, "%s/%s", dirpath, found_name); } else { - tmp = talloc_strdup(ctx, + tmp = talloc_strdup(smb_fname, found_name); } if (tmp == NULL) { DEBUG(0, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } - TALLOC_FREE(name); - name = tmp; - start = name + start_ofs; + TALLOC_FREE(smb_fname->base_name); + smb_fname->base_name = tmp; + start = smb_fname->base_name + start_ofs; /* * We just scanned for, and found the end of @@ -626,17 +645,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, */ if (posix_pathnames) { - ret = vfs_lstat_smb_fname(conn,name, - &st); + ret = SMB_VFS_LSTAT(conn, smb_fname); } else { - ret = vfs_stat_smb_fname(conn,name, - &st); + ret = SMB_VFS_STAT(conn, smb_fname); } - if (ret == 0) { - smb_fname->st = st; - } else { - SET_STAT_INVALID(st); + if (ret != 0) { + SET_STAT_INVALID(smb_fname->st); } } @@ -649,12 +664,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, * We should never provide different behaviors * depending on DEVELOPER!!! */ - if (VALID_STAT(st)) { + if (VALID_STAT(smb_fname->st)) { bool delete_pending; - get_file_infos(vfs_file_id_from_sbuf(conn, &st), + get_file_infos(vfs_file_id_from_sbuf(conn, + &smb_fname->st), &delete_pending, NULL); if (delete_pending) { - result = NT_STATUS_DELETE_PENDING; + status = NT_STATUS_DELETE_PENDING; goto fail; } } @@ -669,7 +685,8 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, "%s/%s", dirpath, start); if (!tmp) { DEBUG(0, ("talloc_asprintf failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } TALLOC_FREE(dirpath); dirpath = tmp; @@ -678,15 +695,15 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, TALLOC_FREE(dirpath); if (!(dirpath = talloc_strdup(ctx,start))) { DEBUG(0, ("talloc_strdup failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } } /* - * Don't cache a name with mangled or wildcard components - * as this can change the size. + * Cache the dirpath thus far. Don't cache a name with mangled + * or wildcard components as this can change the size. */ - if(!component_was_mangled && !name_has_wildcard) { stat_cache_add(orig_path, dirpath, conn->case_sensitive); @@ -701,29 +718,30 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, } /* - * Don't cache a name with mangled or wildcard components - * as this can change the size. + * Cache the full path. Don't cache a name with mangled or wildcard + * components as this can change the size. */ if(!component_was_mangled && !name_has_wildcard) { - stat_cache_add(orig_path, name, conn->case_sensitive); + stat_cache_add(orig_path, smb_fname->base_name, + conn->case_sensitive); } /* * The name has been resolved. */ - DEBUG(5,("conversion finished %s -> %s\n",orig_path, name)); + DEBUG(5,("conversion finished %s -> %s\n", orig_path, + smb_fname->base_name)); done: - smb_fname->base_name = name; - + /* Add back the stream if one was stripped off originally. */ if (stream != NULL) { smb_fname->stream_name = stream; /* Check path now that the base_name has been converted. */ - result = build_stream_path(ctx, conn, orig_path, smb_fname); - if (!NT_STATUS_IS_OK(result)) { + status = build_stream_path(ctx, conn, orig_path, smb_fname); + if (!NT_STATUS_IS_OK(status)) { goto fail; } } @@ -733,20 +751,23 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, fail: DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start)); if (*dirpath != '\0') { - smb_fname->base_name = talloc_asprintf(ctx, "%s/%s", dirpath, - start); + smb_fname->base_name = talloc_asprintf(smb_fname, "%s/%s", + dirpath, start); } else { - smb_fname->base_name = talloc_strdup(ctx, start); + smb_fname->base_name = talloc_strdup(smb_fname, start); } if (!smb_fname->base_name) { DEBUG(0, ("talloc_asprintf failed\n")); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto err; } *smb_fname_out = smb_fname; - TALLOC_FREE(name); TALLOC_FREE(dirpath); - return result; + return status; + err: + TALLOC_FREE(smb_fname); + return status; } /**************************************************************************** @@ -942,6 +963,7 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, struct stream_struct *streams = NULL; if (SMB_VFS_STAT(conn, smb_fname) == 0) { + DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname))); return NT_STATUS_OK; } @@ -988,21 +1010,16 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, TALLOC_FREE(smb_fname->stream_name); - smb_fname->stream_name = talloc_strdup(mem_ctx, streams[i].name); + smb_fname->stream_name = talloc_strdup(smb_fname, streams[i].name); + if (smb_fname->stream_name == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } SET_STAT_INVALID(smb_fname->st); if (SMB_VFS_STAT(conn, smb_fname) == 0) { - char *result = NULL; - - status = get_full_smb_filename(mem_ctx, smb_fname, &result); - if (!NT_STATUS_IS_OK(status)) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - stat_cache_add(orig_path, result, conn->case_sensitive); - TALLOC_FREE(result); + DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname))); } status = NT_STATUS_OK; fail: diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c index daed9f8225..da52cc05d4 100644 --- a/source3/smbd/statcache.c +++ b/source3/smbd/statcache.c @@ -175,6 +175,8 @@ bool stat_cache_lookup(connection_struct *conn, DATA_BLOB data_val; char *name; TALLOC_CTX *ctx = talloc_tos(); + struct smb_filename *smb_fname = NULL; + NTSTATUS status; *pp_dirpath = NULL; *pp_start = *pp_name; @@ -274,14 +276,25 @@ bool stat_cache_lookup(connection_struct *conn, "-> [%s]\n", chk_name, translated_path )); DO_PROFILE_INC(statcache_hits); - if (vfs_stat_smb_fname(conn, translated_path, pst) != 0) { + status = create_synthetic_smb_fname(talloc_tos(), translated_path, + NULL, NULL, &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(chk_name); + TALLOC_FREE(translated_path); + return false; + } + + if (SMB_VFS_STAT(conn, smb_fname) != 0) { /* Discard this entry - it doesn't exist in the filesystem. */ memcache_delete(smbd_memcache(), STAT_CACHE, data_blob_const(chk_name, strlen(chk_name))); TALLOC_FREE(chk_name); TALLOC_FREE(translated_path); + TALLOC_FREE(smb_fname); return False; } + *pst = smb_fname->st; + TALLOC_FREE(smb_fname); if (!sizechanged) { memcpy(*pp_name, translated_path, -- cgit