libsmb: Pass "account_name/flags" through nb_getdc
[metze/samba/wip.git] / source3 / libsmb / clidgram.c
index 92f381e87b4f1215c392b9ee0ddd0d221115a432..bed507626c1ec1d073c714b555871a87c020347b 100644 (file)
 */
 
 #include "includes.h"
+#include "libsmb/libsmb.h"
+#include "../lib/util/tevent_ntstatus.h"
 #include "libsmb/clidgram.h"
 #include "libsmb/nmblib.h"
+#include "libsmb/unexpected.h"
 #include "messages.h"
+#include "librpc/gen_ndr/samr.h"
+#include "../lib/util/pidfile.h"
 
 /*
  * cli_send_mailslot, send a mailslot for client code ...
  */
 
 static bool cli_prep_mailslot(bool unique, const char *mailslot,
-                      uint16 priority,
+                      uint16_t priority,
                       char *buf, int len,
                       const char *srcname, int src_type,
                       const char *dstname, int dest_type,
@@ -115,6 +120,8 @@ static char *mailslot_name(TALLOC_CTX *mem_ctx, struct in_addr dc_ip)
 }
 
 static bool prep_getdc_request(const struct sockaddr_storage *dc_ss,
+                              const char *account_name,
+                              uint32_t account_flags,
                               const char *domain_name,
                               const struct dom_sid *sid,
                               uint32_t nt_version,
@@ -123,7 +130,6 @@ static bool prep_getdc_request(const struct sockaddr_storage *dc_ss,
                               struct packet_struct *p)
 {
        TALLOC_CTX *frame = talloc_stackframe();
-       const char *my_acct_name;
        struct nbt_netlogon_packet packet;
        struct NETLOGON_SAM_LOGON_REQUEST *s;
        enum ndr_err_code ndr_err;
@@ -138,19 +144,14 @@ static bool prep_getdc_request(const struct sockaddr_storage *dc_ss,
                my_sid = *sid;
        }
 
-       my_acct_name = talloc_asprintf(talloc_tos(), "%s$", global_myname());
-       if (my_acct_name == NULL) {
-               goto fail;
-       }
-
        packet.command  = LOGON_SAM_LOGON_REQUEST;
        s               = &packet.req.logon;
 
        s->request_count        = 0;
-       s->computer_name        = global_myname();
-       s->user_name            = my_acct_name;
+       s->computer_name        = lp_netbios_name();
+       s->user_name            = account_name;
        s->mailslot_name        = my_mailslot;
-       s->acct_control         = ACB_WSTRUST;
+       s->acct_control         = account_flags;
        s->sid                  = my_sid;
        s->nt_version           = nt_version;
        s->lmnt_token           = 0xffff;
@@ -168,7 +169,7 @@ static bool prep_getdc_request(const struct sockaddr_storage *dc_ss,
 
        ret = cli_prep_mailslot(false, NBT_MAILSLOT_NTLOGON, 0,
                                (char *)blob.data, blob.length,
-                               global_myname(), 0, domain_name, 0x1c,
+                               lp_netbios_name(), 0, domain_name, 0x1c,
                                dc_ss, dgm_id, p);
 fail:
        TALLOC_FREE(frame);
@@ -225,7 +226,7 @@ static bool parse_getdc_response(
 
        blob = p.smb.body.trans.data;
 
-       r = TALLOC_ZERO_P(mem_ctx, struct netlogon_samlogon_response);
+       r = talloc_zero(mem_ctx, struct netlogon_samlogon_response);
        if (!r) {
                return false;
        }
@@ -298,11 +299,14 @@ struct tevent_req *nbt_getdc_send(TALLOC_CTX *mem_ctx,
                                  const struct sockaddr_storage *dc_addr,
                                  const char *domain_name,
                                  const struct dom_sid *sid,
+                                 const char *account_name,
+                                 uint32_t account_flags,
                                  uint32_t nt_version)
 {
        struct tevent_req *req, *subreq;
        struct nbt_getdc_state *state;
        uint16_t dgm_id;
+       bool ok;
 
        req = tevent_req_create(mem_ctx, &state, struct nbt_getdc_state);
        if (req == NULL) {
@@ -320,11 +324,11 @@ struct tevent_req *nbt_getdc_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
        state->my_mailslot = mailslot_name(
-               state, ((struct sockaddr_in *)dc_addr)->sin_addr);
+               state, ((const struct sockaddr_in *)dc_addr)->sin_addr);
        if (tevent_req_nomem(state->my_mailslot, req)) {
                return tevent_req_post(req, ev);
        }
-       state->nmbd_pid = pidfile_pid("nmbd");
+       state->nmbd_pid = pidfile_pid(lp_pid_directory(), "nmbd");
        if (state->nmbd_pid == 0) {
                DEBUG(3, ("No nmbd found\n"));
                tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
@@ -333,9 +337,12 @@ struct tevent_req *nbt_getdc_send(TALLOC_CTX *mem_ctx,
 
        generate_random_buffer((uint8_t *)(void *)&dgm_id, sizeof(dgm_id));
 
-       if (!prep_getdc_request(dc_addr, domain_name, sid, nt_version,
+       ok = prep_getdc_request(dc_addr, account_name, account_flags,
+                               domain_name, sid, nt_version,
                                state->my_mailslot, dgm_id & 0x7fff,
-                               &state->p)) {
+                               &state->p);
+
+       if (!ok) {
                DEBUG(3, ("prep_getdc_request failed\n"));
                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
                return tevent_req_post(req, ev);
@@ -392,7 +399,7 @@ static void nbt_getdc_got_response(struct tevent_req *subreq)
        NTSTATUS status;
        bool ret;
 
-       status = nb_packet_read_recv(subreq, &p);
+       status = nb_packet_read_recv(subreq, state, &p);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
@@ -401,7 +408,6 @@ static void nbt_getdc_got_response(struct tevent_req *subreq)
        ret = parse_getdc_response(p, state, state->domain_name,
                                   &state->nt_version, &state->dc_name,
                                   &state->samlogon_response);
-       free_packet(p);
        if (!ret) {
                tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
                return;
@@ -434,9 +440,12 @@ NTSTATUS nbt_getdc_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 }
 
 NTSTATUS nbt_getdc(struct messaging_context *msg_ctx,
+                  uint32_t timeout_in_seconds,
                   const struct sockaddr_storage *dc_addr,
                   const char *domain_name,
                   const struct dom_sid *sid,
+                  const char *account_name,
+                  uint32_t account_flags,
                   uint32_t nt_version,
                   TALLOC_CTX *mem_ctx,
                   uint32_t *pnt_version,
@@ -448,15 +457,19 @@ NTSTATUS nbt_getdc(struct messaging_context *msg_ctx,
        struct tevent_req *req;
        NTSTATUS status = NT_STATUS_NO_MEMORY;
 
-       ev = tevent_context_init(frame);
+       ev = samba_tevent_context_init(frame);
        if (ev == NULL) {
                goto fail;
        }
        req = nbt_getdc_send(ev, ev, msg_ctx, dc_addr, domain_name,
-                            sid, nt_version);
+                            sid, account_name, account_flags, nt_version);
        if (req == NULL) {
                goto fail;
        }
+       if (!tevent_req_set_endtime(req, ev,
+                       timeval_current_ofs(timeout_in_seconds, 0))) {
+               goto fail;
+       }
        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
                goto fail;
        }