util_str: Don't return memory from talloc_tos(), use mem_ctx instead.
[samba.git] / source3 / utils / ntlm_auth.c
index 0b50ced0b97ab01be5445559af0739bf280f310a..68bf24fec76b83c894c041b0ee2adffdac16937d 100644 (file)
@@ -252,7 +252,7 @@ static bool get_require_membership_sid(void) {
 }
 /* Authenticate a user with a plaintext password */
 
-static bool check_plaintext_auth(const char *user, const char *pass, 
+static bool check_plaintext_auth(const char *user, const char *pass,
                                 bool stdout_diagnostics)
 {
        struct winbindd_request request;
@@ -270,49 +270,52 @@ static bool check_plaintext_auth(const char *user, const char *pass,
 
        fstrcpy(request.data.auth.user, user);
        fstrcpy(request.data.auth.pass, pass);
-       if (require_membership_of_sid)
-               pstrcpy(request.data.auth.require_membership_of_sid, require_membership_of_sid);
+       if (require_membership_of_sid) {
+               strlcpy(request.data.auth.require_membership_of_sid,
+                       require_membership_of_sid,
+                       sizeof(request.data.auth.require_membership_of_sid));
+       }
 
        result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response);
 
        /* Display response */
-       
+
        if (stdout_diagnostics) {
                if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
                        d_printf("Reading winbind reply failed! (0x01)\n");
                }
-               
-               d_printf("%s: %s (0x%x)\n", 
-                        response.data.auth.nt_status_string, 
-                        response.data.auth.error_string, 
+
+               d_printf("%s: %s (0x%x)\n",
+                        response.data.auth.nt_status_string,
+                        response.data.auth.error_string,
                         response.data.auth.nt_status);
        } else {
                if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
                        DEBUG(1, ("Reading winbind reply failed! (0x01)\n"));
                }
-               
-               DEBUG(3, ("%s: %s (0x%x)\n", 
-                         response.data.auth.nt_status_string, 
+
+               DEBUG(3, ("%s: %s (0x%x)\n",
+                         response.data.auth.nt_status_string,
                          response.data.auth.error_string,
-                         response.data.auth.nt_status));               
+                         response.data.auth.nt_status));
        }
-               
+
         return (result == NSS_STATUS_SUCCESS);
 }
 
 /* authenticate a user with an encrypted username/password */
 
-NTSTATUS contact_winbind_auth_crap(const char *username, 
-                                  const char *domain, 
+NTSTATUS contact_winbind_auth_crap(const char *username,
+                                  const char *domain,
                                   const char *workstation,
-                                  const DATA_BLOB *challenge, 
-                                  const DATA_BLOB *lm_response, 
-                                  const DATA_BLOB *nt_response, 
-                                  uint32 flags, 
-                                  uint8 lm_key[8], 
-                                  uint8 user_session_key[16], 
-                                  char **error_string, 
-                                  char **unix_name) 
+                                  const DATA_BLOB *challenge,
+                                  const DATA_BLOB *lm_response,
+                                  const DATA_BLOB *nt_response,
+                                  uint32 flags,
+                                  uint8 lm_key[8],
+                                  uint8 user_session_key[16],
+                                  char **error_string,
+                                  char **unix_name)
 {
        NTSTATUS nt_status;
         NSS_STATUS result;
@@ -736,7 +739,8 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod
        } else if (strncmp(buf, "GK", 2) == 0) {
                DEBUG(10, ("Requested NTLMSSP session key\n"));
                if(have_session_key) {
-                       char *key64 = base64_encode_data_blob(session_key);
+                       char *key64 = base64_encode_data_blob(talloc_tos(),
+                                       session_key);
                        x_fprintf(x_stdout, "GK %s\n", key64?key64:"<NULL>");
                        TALLOC_FREE(key64);
                } else {
@@ -765,7 +769,8 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod
        nt_status = ntlmssp_update(ntlmssp_state, request, &reply);
        
        if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
-               char *reply_base64 = base64_encode_data_blob(reply);
+               char *reply_base64 = base64_encode_data_blob(talloc_tos(),
+                               reply);
                x_fprintf(x_stdout, "TT %s\n", reply_base64);
                TALLOC_FREE(reply_base64);
                data_blob_free(&reply);
@@ -886,7 +891,8 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
                DEBUG(10, ("Requested session key\n"));
 
                if(have_session_key) {
-                       char *key64 = base64_encode_data_blob(session_key);
+                       char *key64 = base64_encode_data_blob(talloc_tos(),
+                                       session_key);
                        x_fprintf(x_stdout, "GK %s\n", key64?key64:"<NULL>");
                        TALLOC_FREE(key64);
                }
@@ -922,7 +928,8 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
        }
        
        if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
-               char *reply_base64 = base64_encode_data_blob(reply);
+               char *reply_base64 = base64_encode_data_blob(talloc_tos(),
+                               reply);
                if (first) {
                        x_fprintf(x_stdout, "YR %s\n", reply_base64);
                } else { 
@@ -936,7 +943,8 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
                }
                DEBUG(10, ("NTLMSSP challenge\n"));
        } else if (NT_STATUS_IS_OK(nt_status)) {
-               char *reply_base64 = base64_encode_data_blob(reply);
+               char *reply_base64 = base64_encode_data_blob(talloc_tos(),
+                               reply);
                x_fprintf(x_stdout, "AF %s\n", reply_base64);
                TALLOC_FREE(reply_base64);
 
@@ -994,16 +1002,22 @@ static void offer_gss_spnego_mechs(void) {
        SPNEGO_DATA spnego;
        ssize_t len;
        char *reply_base64;
-
-       pstring principal;
-       pstring myname_lower;
+       TALLOC_CTX *ctx = talloc_tos();
+       char *principal;
+       char *myname_lower;
 
        ZERO_STRUCT(spnego);
 
-       pstrcpy(myname_lower, global_myname());
+       myname_lower = talloc_strdup(ctx, global_myname());
+       if (!myname_lower) {
+               return;
+       }
        strlower_m(myname_lower);
 
-       pstr_sprintf(principal, "%s$@%s", myname_lower, lp_realm());
+       principal = talloc_asprintf(ctx, "%s$@%s", myname_lower, lp_realm());
+       if (!principal) {
+               return;
+       }
 
        /* Server negTokenInit (mech offerings) */
        spnego.type = SPNEGO_NEG_TOKEN_INIT;
@@ -1030,7 +1044,7 @@ static void offer_gss_spnego_mechs(void) {
                return;
        }
 
-       reply_base64 = base64_encode_data_blob(token);
+       reply_base64 = base64_encode_data_blob(talloc_tos(), token);
        x_fprintf(x_stdout, "TT %s *\n", reply_base64);
 
        TALLOC_FREE(reply_base64);
@@ -1047,13 +1061,14 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
        DATA_BLOB token;
        NTSTATUS status;
        ssize_t len;
+       TALLOC_CTX *ctx = talloc_tos();
 
        char *user = NULL;
        char *domain = NULL;
 
        const char *reply_code;
        char       *reply_base64;
-       pstring     reply_argument;
+       char *reply_argument = NULL;
 
        if (strlen(buf) < 2) {
                DEBUG(1, ("SPENGO query [%s] invalid", buf));
@@ -1065,7 +1080,7 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
                if (ntlmssp_state)
                        ntlmssp_end(&ntlmssp_state);
        } else if (strncmp(buf, "KK", 2) == 0) {
-               
+               ;
        } else {
                DEBUG(1, ("SPENGO query [%s] invalid", buf));
                x_fprintf(x_stdout, "BH\n");
@@ -1153,6 +1168,7 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
                        char *principal;
                        DATA_BLOB ap_rep;
                        DATA_BLOB session_key;
+                       PAC_DATA *pac_data = NULL;
 
                        if ( request.negTokenInit.mechToken.data == NULL ) {
                                DEBUG(1, ("Client did not provide Kerberos data\n"));
@@ -1167,7 +1183,7 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
 
                        status = ads_verify_ticket(mem_ctx, lp_realm(), 0,
                                                   &request.negTokenInit.mechToken,
-                                                  &principal, NULL, &ap_rep,
+                                                  &principal, &pac_data, &ap_rep,
                                                   &session_key, True);
 
                        talloc_destroy(mem_ctx);
@@ -1235,16 +1251,22 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
        if (NT_STATUS_IS_OK(status)) {
                response.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED;
                reply_code = "AF";
-               pstr_sprintf(reply_argument, "%s\\%s", domain, user);
+               reply_argument = talloc_asprintf(ctx, "%s\\%s", domain, user);
        } else if (NT_STATUS_EQUAL(status,
                                   NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                response.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
                reply_code = "TT";
-               pstr_sprintf(reply_argument, "*");
+               reply_argument = talloc_strdup(ctx, "*");
        } else {
                response.negTokenTarg.negResult = SPNEGO_REJECT;
                reply_code = "NA";
-               pstrcpy(reply_argument, nt_errstr(status));
+               reply_argument = talloc_strdup(ctx, nt_errstr(status));
+       }
+
+       if (!reply_argument) {
+               DEBUG(1, ("Could not write SPNEGO data blob\n"));
+               x_fprintf(x_stdout, "BH\n");
+               return;
        }
 
        SAFE_FREE(user);
@@ -1259,7 +1281,7 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
                return;
        }
 
-       reply_base64 = base64_encode_data_blob(token);
+       reply_base64 = base64_encode_data_blob(talloc_tos(), token);
 
        x_fprintf(x_stdout, "%s %s %s\n",
                  reply_code, reply_base64, reply_argument);
@@ -1326,7 +1348,7 @@ static bool manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        write_spnego_data(&to_server, &spnego);
        data_blob_free(&spnego.negTokenInit.mechToken);
 
-       to_server_base64 = base64_encode_data_blob(to_server);
+       to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server);
        data_blob_free(&to_server);
        x_fprintf(x_stdout, "KK %s\n", to_server_base64);
        TALLOC_FREE(to_server_base64);
@@ -1384,7 +1406,7 @@ static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego)
        write_spnego_data(&to_server, &spnego);
        data_blob_free(&request);
 
-       to_server_base64 = base64_encode_data_blob(to_server);
+       to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server);
        data_blob_free(&to_server);
        x_fprintf(x_stdout, "KK %s\n", to_server_base64);
        TALLOC_FREE(to_server_base64);
@@ -1401,7 +1423,7 @@ static bool manage_client_krb5_init(SPNEGO_DATA spnego)
        SPNEGO_DATA reply;
        char *reply_base64;
        int retval;
-       
+
        const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL};
        ssize_t len;
 
@@ -1426,8 +1448,7 @@ static bool manage_client_krb5_init(SPNEGO_DATA spnego)
        retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL, NULL);
 
        if (retval) {
-
-               pstring user;
+               char *user = NULL;
 
                /* Let's try to first get the TGT, for that we need a
                    password. */
@@ -1438,7 +1459,10 @@ static bool manage_client_krb5_init(SPNEGO_DATA spnego)
                        return True;
                }
 
-               pstr_sprintf(user, "%s@%s", opt_username, opt_domain);
+               user = talloc_asprintf(talloc_tos(), "%s@%s", opt_username, opt_domain);
+               if (!user) {
+                       return false;
+               }
 
                if ((retval = kerberos_kinit_password(user, opt_password, 0, NULL))) {
                        DEBUG(10, ("Requesting TGT failed: %s\n", error_message(retval)));
@@ -1471,7 +1495,7 @@ static bool manage_client_krb5_init(SPNEGO_DATA spnego)
                return False;
        }
 
-       reply_base64 = base64_encode_data_blob(to_server);
+       reply_base64 = base64_encode_data_blob(talloc_tos(), to_server);
        x_fprintf(x_stdout, "KK %s *\n", reply_base64);
 
        TALLOC_FREE(reply_base64);
@@ -2180,6 +2204,7 @@ enum {
 
  int main(int argc, const char **argv)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        int opt;
        static const char *helper_protocol;
        static int diagnostics;
@@ -2224,9 +2249,9 @@ enum {
        
        /* Samba client initialisation */
 
-       if (!lp_load(dyn_CONFIGFILE, True, False, False, True)) {
+       if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, True)) {
                d_fprintf(stderr, "ntlm_auth: error opening config file %s. Error was %s\n",
-                       dyn_CONFIGFILE, strerror(errno));
+                       get_dyn_CONFIGFILE(), strerror(errno));
                exit(1);
        }
 
@@ -2361,5 +2386,6 @@ enum {
        /* Exit code */
 
        poptFreeContext(pc);
+       TALLOC_FREE(frame);
        return 0;
 }