Пример #1
0
static void scan_memory(int i, unsigned char *p, off_t size)
{
	unsigned char *p0 = p;
	int found = 0;
	
	while ((p = memmem(p, size - (p-p0), GZIP_HEADER, strlen(GZIP_HEADER)))) {
		char *fname=NULL;

		if (p[8] > 4) {
			p++;
			continue;
		}

		/* only want unix gzip output */
		if (p[9] > 11) {
			p++;
			continue;
		}

		found++;
		asprintf(&fname, "extract-%d-%d.gz", i, found);
		file_save(fname, p, size - (p-p0));
		printf("Extracted %d bytes to %s\n", (int)(size - (p-p0)), fname);
		free(fname);
		p++;
	}
}
Пример #2
0
void fsave_callback (GtkAction *action, gpointer p)
{
    const gchar *s = gtk_action_get_name(action);
    int ci = fsave_code(s);

    file_save(p, ci);
}
Пример #3
0
bool MainWindow::askSaveChanges()
{
	QString message;
	QMessageBox response;

	if (existing_filename)
		message = tr("Do you want to save the changes you made in the file %1?").arg(existing_filename);
	else
		message = tr("Do you want to save the changes you made in the datafile?");

	response.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
	response.setDefaultButton(QMessageBox::Save);
	response.setText(message);
	response.setWindowTitle(tr("Save Changes?")); // Not displayed on MacOSX as described in Qt API
	response.setInformativeText(tr("Changes will be lost if you don't save them."));
	response.setIcon(QMessageBox::Warning);
	int ret = response.exec();

	switch (ret) {
	case QMessageBox::Save:
		file_save();
		return true;
	case QMessageBox::Discard:
		return true;
	}
	return false;
}
Пример #4
0
static bool test_file_load_save(struct torture_context *tctx)
{
	size_t len;
	char *data;
	TALLOC_CTX *mem_ctx = tctx;
	
	torture_assert(tctx, file_save(TEST_FILENAME, TEST_DATA, strlen(TEST_DATA)),
				   "saving file");

	torture_assert_file_contains_text(tctx, TEST_FILENAME, TEST_DATA, 
								      "file contents");

	data = file_load(TEST_FILENAME, &len, 0, mem_ctx);
	torture_assert(tctx, data, "loading file");

	torture_assert_int_equal(tctx, len, strlen(TEST_DATA), "Length");
	
	torture_assert_mem_equal(tctx, data, TEST_DATA, len, "Contents");

	data = file_load(TEST_FILENAME, &len, 5, mem_ctx);

	torture_assert_int_equal(tctx, len, 5, "Length");

	torture_assert_mem_equal(tctx, data, TEST_DATA, len, "Contents");

	unlink(TEST_FILENAME);
	return true;
}
Пример #5
0
static bool test_afdgets(struct torture_context *tctx)
{
	int fd;
	char *line;
	TALLOC_CTX *mem_ctx = tctx;
	bool ret = false;
	
	torture_assert(tctx, file_save(TEST_FILENAME, (const void *)TEST_DATA, 
							 strlen(TEST_DATA)),
				   "saving file");

	fd = open(TEST_FILENAME, O_RDONLY);
	
	torture_assert(tctx, fd != -1, "opening file");

	line = afdgets(fd, mem_ctx, 8);
	torture_assert_goto(tctx, strcmp(line, TEST_LINE1) == 0, ret, done,
			    "line 1 mismatch");

	line = afdgets(fd, mem_ctx, 8);
	torture_assert_goto(tctx, strcmp(line, TEST_LINE2) == 0, ret, done,
			    "line 2 mismatch");

	line = afdgets(fd, mem_ctx, 8);
	torture_assert_goto(tctx, strcmp(line, TEST_LINE3) == 0, ret, done,
			    "line 3 mismatch");
	ret = true;
done:
	close(fd);

	unlink(TEST_FILENAME);
	return ret;
}
Пример #6
0
/*****************************************************************************
* 函 数 名  : file_save_lcs
*
* 功能描述  : 将内存lcs数据保存到文件中
*
* 输入参数  : u32 offset_addr          基于TLPHT_IMAGE基址的偏移地址
*             u32 data_size            TLPHT_IMAGE大小
*
* 返 回 值  : s32  返回值:0为成功,-1为失败。
*
* 修改记录  : 2012年11月27日
*****************************************************************************/
long file_save_lcs(u32 offset_addr, u32 data_size)
{
    unsigned count = 0;
    unsigned export_phy_addr = 0;
    unsigned export_virt_addr = 0;
    char export_file_name[] = "lcs_data.bin";

    if(offset_addr + data_size > DDR_LCS_SIZE)
    {
        printk("%s: parameter error.\n", __FUNCTION__);
        return -1;
    }

    if(0 != addr_ioremap(DDR_TYPE_LCS, DDR_LCS_ADDR, DDR_LCS_SIZE))
    {
        printk("%s: cannot map IO.\n", __FUNCTION__);
        return -1;
    }

    count = data_size;
    export_phy_addr = DDR_LCS_ADDR + offset_addr;
    printk("export data address is %#x, and the size is %#x.\n", \
           export_phy_addr, data_size);

    export_virt_addr = virt_addr[DDR_TYPE_LCS] + offset_addr;
    printk("DDR_LCS_ADDR = %#x, DDR_LCS_ADDR_VIRT = %#x, DDR_LCS_SIZE = %#x.\n", \
           DDR_LCS_ADDR, virt_addr[DDR_TYPE_LCS], DDR_LCS_SIZE);

    return file_save(export_file_name, export_virt_addr, count);
}
Пример #7
0
/*****************************************************************************
* 函 数 名  : file_save_lphy_sdr
*
* 功能描述  : 将lphy内存数据保存到文件中
*
* 输入参数  : u32 offset_addr          基于lphy基址的偏移地址
*             u32 data_size            lphy大小
*             u32 anten_num            采数天线编号
*
* 返 回 值  : s32  返回值:0为成功,-1为失败。
*
* 修改记录  : 2012年11月27日
*****************************************************************************/
long file_save_lphy_sdr(u32 offset_addr, u32 data_size, u32 anten_num)
{
    unsigned count = 0;
    unsigned export_phy_addr = 0;
    unsigned export_virt_addr = 0;
    char export_file_name[60] = "";

    if(offset_addr + data_size > DDR_LPHY_SDR_SIZE)
    {
        printk("%s: parameter error.\n", __FUNCTION__);
        return -1;
    }

    if(0 != addr_ioremap(DDR_TYPE_LPHY_SDR, DDR_LPHY_SDR_ADDR, DDR_LPHY_SDR_SIZE))
    {
        printk("%s: cannot map IO.\n", __FUNCTION__);
        return -1;
    }

    count = data_size;
    export_phy_addr = DDR_LPHY_SDR_ADDR + offset_addr;
    snprintf(export_file_name, 60,"lphy_sdr_data_anten%d.bin", anten_num);
    printk("export data address is %#x, and the size is %#x.\n", \
           export_phy_addr, data_size);

    export_virt_addr = virt_addr[DDR_TYPE_LPHY_SDR] + offset_addr;
    printk("DDR_LPHY_SDR_ADDR = %#x, DDR_LPHY_SDR_ADDR_VIRT = %#x, DDR_LPHY_SDR_SIZE = %#x.\n", \
           DDR_LPHY_SDR_ADDR, virt_addr[DDR_TYPE_LPHY_SDR], DDR_LPHY_SDR_SIZE);

    return file_save(export_file_name, export_virt_addr, count);
}
Пример #8
0
static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
			     int length, int bufsize,
			     DATA_BLOB blob1)
{
	DATA_BLOB auth, auth_reply;
	NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER;

	if (!spnego_parse_auth(blob1, &auth)) {
#if 0
		file_save("auth.dat", blob1.data, blob1.length);
#endif
		return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
	}
	
	if (!global_ntlmssp_state) {
		/* auth before negotiatiate? */
		return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
	}
	
	nt_status = auth_ntlmssp_update(global_ntlmssp_state, 
						auth, &auth_reply);

	data_blob_free(&auth);

	reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state,
			     &auth_reply, nt_status);
		
	data_blob_free(&auth_reply);

	/* and tell smbd that we have already replied to this packet */
	return -1;
}
Пример #9
0
void main()
{
	while(1)
	{
		system("cls");
		printf("*** MENU ***\n");
		printf("1. INPUT\n");
		printf("2. PRINT\n");
		printf("   21. SORT PRINT(by name)\n");
		printf("3. SEARCH\n");
		printf("4. MODIFY\n");
		printf("5. DELETE\n");
		printf("6. FILE SAVE\n");
		printf("7. FILE LOAD\n");
		printf("8. EXIT\n");
		printf("CHOICE [  ]\b\b\b");

		switch(getnum())
		{
		case 1 : input(); break;
		case 2 : print(); break;
		case 3 : search(0); break;
		case 4 : modify_del(1); break;
		case 5 : modify_del(2); break;
		case 6 : file_save(); break;
		case 7 : file_load(); break;
		case 8 : end();
		case 21 : sort_print(); break;
		default : printf("Please choice again...\n");
			getch();
		}
	}
}
Пример #10
0
void command_mode() {
    while(1) {
        char c;
        console_title("Command mode");
        console_status(status_str);
        c = getchar();
        if (c == '\n')
            edit_mode();
        else if (c == 'q' || c == 'Q') {
            extern int fileModified;
            if (!fileModified)
                return;
            console_status("Save changes? (y/n/c)");
            while(1) {
                c = getchar();
                if (c == 'y' || c == 'Y') {
                    if (file_save()) {
                        console_status(failure);
                        getchar();
                        break;
                    }
                    return; /* done. */
                } else if (c == 'n' || c == 'N') {
                    return; /* just return; */
                } else if (c == 'c' || c == 'C') {
                    break;  /* cancel; */
                }
            }
        }
    }
}
Пример #11
0
int file_save( const char* fname, void *buff, int size )
{
  FILE *f = fopen( fname, "wb" );
  if (!f) return 1;
  int res = file_save( f, buff, size );
  fclose( f );
  return res;
};
Пример #12
0
GLADE_CB void
on_save_clicked                        (GtkToolButton   *toolbutton,
                                        gpointer         user_data)
{
	gchar *fn = NULL, *ext = NULL;
	gchar *filename = NULL;

	if(GFMFile.filename != NULL)
		filename = g_strdup(GFMFile.filename);

	if(GFMFile.type & TIFILE_TIGROUP)
	{
		ext = g_strdup("*.tig");
	}
	else if(GFMFile.type & TIFILE_GROUP)
	{
		if(ticalcs_dirlist_ve_count(GFMFile.trees.vars) > 1)
		{
			// Group file
			ext = g_strconcat("*.", tifiles_vartype2fext(GFMFile.model, 0x00), NULL);
			ext[4] = 'g';
		}
		else if(ticalcs_dirlist_ve_count(GFMFile.trees.vars) == 1)
		{
			// Single file
			GNode *parent, *child;
			VarEntry *ve;

			parent = g_node_nth_child(GFMFile.trees.vars, 0);
			child = g_node_nth_child(parent, 0);
			ve = (VarEntry *) (child->data);

			filename = g_strconcat(ticonv_varname_to_filename(GFMFile.model, ve->name, ve->type), ".", 
				tifiles_vartype2fext(GFMFile.model, ve->type), NULL);
			ext = g_strconcat("*.", tifiles_vartype2fext(GFMFile.model, ve->type), NULL);
		}
		else
		{
			g_free(filename);
			return;
		}
	}

	fn = (char *)create_fsel(inst_paths.home_dir, filename, ext, TRUE);
	if(fn == NULL)
		return;
	g_free(filename);
	g_free(ext);

	file_save(fn);

	g_free(GFMFile.filename);
	GFMFile.filename = g_strdup(fn);

	enable_save(FALSE);
}
Пример #13
0
void
read_chip(void)
{
    int             r;

    power_up();
    r = chips[chipindex].read_func(buffersize, pagesize);
    file_save(); 
    power_down();
}
Пример #14
0
static BOOL afs_settoken(const char *cell,
			 const struct ClearToken *ctok,
			 DATA_BLOB ticket)
{
	int ret;
	struct {
		char *in, *out;
		uint16 in_size, out_size;
	} iob;

	char buf[1024];
	char *p = buf;
	int tmp;

	memcpy(p, &ticket.length, sizeof(uint32));
	p += sizeof(uint32);
	memcpy(p, ticket.data, ticket.length);
	p += ticket.length;

	tmp = sizeof(struct ClearToken);
	memcpy(p, &tmp, sizeof(uint32));
	p += sizeof(uint32);
	memcpy(p, ctok, tmp);
	p += tmp;

	tmp = 0;

	memcpy(p, &tmp, sizeof(uint32));
	p += sizeof(uint32);

	tmp = strlen(cell);
	if (tmp >= MAXKTCREALMLEN) {
		DEBUG(1, ("Realm too long\n"));
		return False;
	}

	strncpy(p, cell, tmp);
	p += tmp;
	*p = 0;
	p +=1;

	iob.in = buf;
	iob.in_size = PTR_DIFF(p,buf);
	iob.out = buf;
	iob.out_size = sizeof(buf);

#if 0
	file_save("/tmp/ioctlbuf", iob.in, iob.in_size);
#endif

	ret = afs_syscall(AFSCALL_PIOCTL, 0, VIOCSETTOK, (char *)&iob, 0);

	DEBUG(10, ("afs VIOCSETTOK returned %d\n", ret));
	return (ret == 0);
}
Пример #15
0
void
cedit_commands_save_document (CeditWindow   *window,
                              CeditDocument *document)
{
	CeditTab *tab;

	g_return_if_fail (CEDIT_IS_WINDOW (window));
	g_return_if_fail (CEDIT_IS_DOCUMENT (document));
	
	cedit_debug (DEBUG_COMMANDS);
	
	tab = cedit_tab_get_from_document (document);
	file_save (tab, window);
}
Пример #16
0
void
_cedit_cmd_file_save (GtkAction   *action,
		     CeditWindow *window)
{
	CeditTab *tab;

	cedit_debug (DEBUG_COMMANDS);

	tab = cedit_window_get_active_tab (window);
	if (tab == NULL)
		return;

	file_save (tab, window);
}
Пример #17
0
static void
save_and_close (CeditTab    *tab,
		CeditWindow *window)
{
	cedit_debug (DEBUG_COMMANDS);

	/* Trace tab state changes */
	g_signal_connect (tab,
			  "notify::state",
			  G_CALLBACK (tab_state_changed_while_saving),
			  window);

	file_save (tab, window);
}
QMenuBar *win_char_editor::setup_menuBar()
{
	file_new_Act = new QAction(tr("New"), this); 
    connect(file_new_Act, SIGNAL(triggered()), this, SLOT(file_new()));

	file_open_Act = new QAction(tr("Open"), this); 
    connect(file_open_Act, SIGNAL(triggered()), this, SLOT(file_open()));

	file_saveAct = new QAction(tr("Save"), this); 
	file_saveAct->setEnabled(FALSE);
    connect(file_saveAct, SIGNAL(triggered()), this, SLOT(file_save()));

	file_save_asAct = new QAction(tr("Save &As..."), this); 
	file_save_asAct->setEnabled(TRUE);
    connect(file_save_asAct, SIGNAL(triggered()), this, SLOT(file_save_as()));

	file_exitAct = new QAction(tr("Exit"), this); 
    connect(file_exitAct, SIGNAL(triggered()), this, SLOT(close()));

	edit_undoAct = new QAction(tr("Undo"), this); 
	edit_undoAct->setShortcut(tr("Ctrl+Z"));
	connect(edit_undoAct, SIGNAL(triggered()), this, SLOT(edit_undo()));
	edit_undoAct->setEnabled(FALSE);
    
	edit_redoAct = new QAction(tr("Redo"), this); 
	edit_redoAct->setShortcut(tr("Ctrl+Y"));
	connect(edit_redoAct, SIGNAL(triggered()), this, SLOT(edit_redo()));
	edit_redoAct->setEnabled(FALSE);

	fileMenu = new QMenu(tr("&File"));
	fileMenu->addAction(file_new_Act);
	fileMenu->addSeparator();
	fileMenu->addAction(file_open_Act);
	fileMenu->addSeparator();
	fileMenu->addAction(file_saveAct);
	fileMenu->addAction(file_save_asAct);
	fileMenu->addSeparator();
	fileMenu->addAction(file_exitAct);
	connect(fileMenu,SIGNAL(aboutToShow()),this,SLOT(menu_file_open()));
	editMenu = new QMenu(tr("&Edit"));
	editMenu->addAction(edit_undoAct);
	editMenu->addAction(edit_redoAct);
	
	mb = new QMenuBar(this);
	mb->clear();
	mb->addMenu(fileMenu);
	mb->addMenu(editMenu);
	return mb;
}
Пример #19
0
static void ask_save_changes()
{
	GtkWidget *dialog, *label, *content;
	dialog = gtk_dialog_new_with_buttons("Save Changes?",
		GTK_WINDOW(main_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
		GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
		GTK_STOCK_NO, GTK_RESPONSE_NO,
		NULL);
	content = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
	label = gtk_label_new ("You have unsaved changes\nWould you like to save those before exiting the program?");
	gtk_container_add (GTK_CONTAINER (content), label);
	gtk_widget_show_all (dialog);
	gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
		file_save(NULL,NULL);
	}
	gtk_widget_destroy(dialog);
}
Пример #20
0
/** Change document name and save. */
static void file_save_as(void)
{
	const char *old_fname = (doc.file_name != NULL) ? doc.file_name : "";
	char *fname;
	
	fname = filename_prompt("Save As", old_fname);
	if (fname == NULL) {
		status_display("Save cancelled.");
		return;
	}

	int rc = file_save(fname);
	if (rc != EOK)
		return;

	if (doc.file_name != NULL)
		free(doc.file_name);
	doc.file_name = fname;
}
Пример #21
0
/** Handle Ctrl-key combination. */
static void key_handle_ctrl(kbd_event_t const *ev)
{
	switch (ev->key) {
	case KC_Q:
		done = true;
		break;
	case KC_S:
		if (doc.file_name != NULL)
			file_save(doc.file_name);
		else
			file_save_as();
		break;
	case KC_E:
		file_save_as();
		break;
	case KC_C:
		selection_copy();
		break;
	case KC_V:
		selection_delete();
		insert_clipboard_data();
		pane.rflags |= REDRAW_TEXT;
		caret_update();
		break;
	case KC_X:
		selection_copy();
		selection_delete();
		pane.rflags |= REDRAW_TEXT;
		caret_update();
		break;
	case KC_A:
		selection_sel_all();
		break;
	default:
		break;
	}
}
bool	win_char_editor::ask_if_save()
{
	if (!isWindowModified())
		return TRUE;
	
	switch (QMessageBox::warning(this, "Itecad", tr("The char has been modified. Do you want to save it now?"), tr("&Yes"), tr("&No"), tr("&Cancel"), 0, 1))
	{
	case 0:		// 0 = YES
		if (never_saved)
			{
			file_save_as();
			return TRUE;
			}
		else
			{
			file_save();
			return TRUE;
			}
	case 1:		// 1 = NO
		return TRUE;
	case 2:		// 2 = CANCEL
		return FALSE;
	}		
}
Пример #23
0
/*
  this is a paranoid NDR input validator. For every packet we pull
  from the wire we push it back again then pull and push it
  again. Then we compare the raw NDR data for that to the NDR we
  initially generated. If they don't match then we know we must have a
  bug in either the pull or push side of our code
*/
static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
					struct ndr_pull *pull_in,
					void *struct_ptr,
					size_t struct_size,
					ndr_push_flags_fn_t ndr_push,
					ndr_pull_flags_fn_t ndr_pull,
					ndr_print_function_t ndr_print)
{
	void *st;
	struct ndr_pull *pull;
	struct ndr_push *push;
	DATA_BLOB blob, blob2;
	TALLOC_CTX *mem_ctx = pull_in;
	char *s1, *s2;
	enum ndr_err_code ndr_err;

	st = talloc_size(mem_ctx, struct_size);
	if (!st) {
		return NT_STATUS_NO_MEMORY;
	}
	memcpy(st, struct_ptr, struct_size);

	push = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
	if (!push) {
		return NT_STATUS_NO_MEMORY;
	}	

	ndr_err = ndr_push(push, NDR_OUT, struct_ptr);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
		ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
					 "failed output validation push - %s",
					 nt_errstr(status));
		return ndr_map_error2ntstatus(ndr_err);
	}

	blob = ndr_push_blob(push);

	pull = ndr_pull_init_flags(c, &blob, mem_ctx);
	if (!pull) {
		return NT_STATUS_NO_MEMORY;
	}

	pull->flags |= LIBNDR_FLAG_REF_ALLOC;
	ndr_err = ndr_pull(pull, NDR_OUT, st);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
		ndr_err = ndr_pull_error(pull, NDR_ERR_VALIDATE,
					 "failed output validation pull - %s",
					 nt_errstr(status));
		return ndr_map_error2ntstatus(ndr_err);
	}

	push = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
	if (!push) {
		return NT_STATUS_NO_MEMORY;
	}	

	ndr_err = ndr_push(push, NDR_OUT, st);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
		ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
					 "failed output validation push2 - %s",
					 nt_errstr(status));
		return ndr_map_error2ntstatus(ndr_err);
	}

	blob2 = ndr_push_blob(push);

	if (data_blob_cmp(&blob, &blob2) != 0) {
		DEBUG(3,("original:\n"));
		dump_data(3, blob.data, blob.length);
		DEBUG(3,("secondary:\n"));
		dump_data(3, blob2.data, blob2.length);
		ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
					 "failed output validation blobs doesn't match");
		return ndr_map_error2ntstatus(ndr_err);
	}

	/* this checks the printed forms of the two structures, which effectively
	   tests all of the value() attributes */
	s1 = ndr_print_function_string(mem_ctx, ndr_print, "VALIDATE", 
				       NDR_OUT, struct_ptr);
	s2 = ndr_print_function_string(mem_ctx, ndr_print, "VALIDATE", 
				       NDR_OUT, st);
	if (strcmp(s1, s2) != 0) {
#if 1
		DEBUG(3,("VALIDATE ERROR:\nWIRE:\n%s\n GEN:\n%s\n", s1, s2));
#else
		/* this is sometimes useful */
		printf("VALIDATE ERROR\n");
		file_save("wire.dat", s1, strlen(s1));
		file_save("gen.dat", s2, strlen(s2));
		system("diff -u wire.dat gen.dat");
#endif
		ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
					 "failed output validation strings doesn't match");
		return ndr_map_error2ntstatus(ndr_err);
	}

	return NT_STATUS_OK;
}
Пример #24
0
static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
				    const DATA_BLOB request, DATA_BLOB *reply) 
{
	DATA_BLOB encrypted_session_key = data_blob_null;
	DATA_BLOB user_session_key = data_blob_null;
	DATA_BLOB lm_session_key = data_blob_null;
	DATA_BLOB session_key = data_blob_null;
	uint32 ntlmssp_command, auth_flags;
	NTSTATUS nt_status = NT_STATUS_OK;

	/* used by NTLM2 */
	bool doing_ntlm2 = False;

	uchar session_nonce[16];
	uchar session_nonce_hash[16];

	const char *parse_string;
	char *domain = NULL;
	char *user = NULL;
	char *workstation = NULL;

	/* parse the NTLMSSP packet */
	*reply = data_blob_null;

#if 0
	file_save("ntlmssp_auth.dat", request.data, request.length);
#endif

	if (ntlmssp_state->unicode) {
		parse_string = "CdBBUUUBd";
	} else {
		parse_string = "CdBBAAABd";
	}

	data_blob_free(&ntlmssp_state->lm_resp);
	data_blob_free(&ntlmssp_state->nt_resp);

	ntlmssp_state->user = NULL;
	ntlmssp_state->domain = NULL;
	ntlmssp_state->workstation = NULL;

	/* now the NTLMSSP encoded auth hashes */
	if (!msrpc_parse(&request, parse_string,
			 "NTLMSSP", 
			 &ntlmssp_command, 
			 &ntlmssp_state->lm_resp,
			 &ntlmssp_state->nt_resp,
			 &domain, 
			 &user, 
			 &workstation,
			 &encrypted_session_key,
			 &auth_flags)) {
		SAFE_FREE(domain);
		SAFE_FREE(user);
		SAFE_FREE(workstation);
		data_blob_free(&encrypted_session_key);
		auth_flags = 0;
		
		/* Try again with a shorter string (Win9X truncates this packet) */
		if (ntlmssp_state->unicode) {
			parse_string = "CdBBUUU";
		} else {
			parse_string = "CdBBAAA";
		}

		/* now the NTLMSSP encoded auth hashes */
		if (!msrpc_parse(&request, parse_string,
				 "NTLMSSP", 
				 &ntlmssp_command, 
				 &ntlmssp_state->lm_resp,
				 &ntlmssp_state->nt_resp,
				 &domain, 
				 &user, 
				 &workstation)) {
			DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
			dump_data(2, request.data, request.length);
			SAFE_FREE(domain);
			SAFE_FREE(user);
			SAFE_FREE(workstation);

			return NT_STATUS_INVALID_PARAMETER;
		}
	}

	if (auth_flags)
		ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth());

	if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
		SAFE_FREE(domain);
		SAFE_FREE(user);
		SAFE_FREE(workstation);
		data_blob_free(&encrypted_session_key);
		return nt_status;
	}

	if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
		SAFE_FREE(domain);
		SAFE_FREE(user);
		SAFE_FREE(workstation);
		data_blob_free(&encrypted_session_key);
		return nt_status;
	}

	if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
		SAFE_FREE(domain);
		SAFE_FREE(user);
		SAFE_FREE(workstation);
		data_blob_free(&encrypted_session_key);
		return nt_status;
	}

	SAFE_FREE(domain);
	SAFE_FREE(user);
	SAFE_FREE(workstation);

	DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
		 ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));

#if 0
	file_save("nthash1.dat",  &ntlmssp_state->nt_resp.data,  &ntlmssp_state->nt_resp.length);
	file_save("lmhash1.dat",  &ntlmssp_state->lm_resp.data,  &ntlmssp_state->lm_resp.length);
#endif

	/* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a 
	   client challenge 
	
	   However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
	*/
	if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
		if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
			struct MD5Context md5_session_nonce_ctx;
			SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
			
			doing_ntlm2 = True;

			memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8);
			memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8);
			
			MD5Init(&md5_session_nonce_ctx);
			MD5Update(&md5_session_nonce_ctx, session_nonce, 16);
			MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
			
			ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8);

			/* LM response is no longer useful */
			data_blob_free(&ntlmssp_state->lm_resp);

			/* We changed the effective challenge - set it */
			if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) {
				data_blob_free(&encrypted_session_key);
				return nt_status;
			}

			/* LM Key is incompatible. */
			ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
		}
	}

	/*
	 * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
	 * is required (by "ntlm auth = no" and "lm auth = no" being set in the
	 * smb.conf file) and no NTLMv2 response was sent then the password check
	 * will fail here. JRA.
	 */

	/* Finally, actually ask if the password is OK */

	if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, 
								       &user_session_key, &lm_session_key))) {
		data_blob_free(&encrypted_session_key);
		return nt_status;
	}

	dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
	dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);

	/* Handle the different session key derivation for NTLM2 */
	if (doing_ntlm2) {
		if (user_session_key.data && user_session_key.length == 16) {
			session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
			hmac_md5(user_session_key.data, session_nonce, 
				 sizeof(session_nonce), session_key.data);
			DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
			dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
			
		} else {
			DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
			session_key = data_blob_null;
		}
	} else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
		if (lm_session_key.data && lm_session_key.length >= 8) {
			if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
				session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
				if (session_key.data == NULL) {
					return NT_STATUS_NO_MEMORY;
				}
				SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, 
							  session_key.data);
				DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
			} else {
				uint8 zeros[24];
				ZERO_STRUCT(zeros);
				session_key = data_blob_talloc(
					ntlmssp_state->mem_ctx, NULL, 16);
				if (session_key.data == NULL) {
					return NT_STATUS_NO_MEMORY;
				}
				SMBsesskeygen_lm_sess_key(
					lm_session_key.data, zeros,
					session_key.data);
			}
			dump_data_pw("LM session key:\n", session_key.data,
				     session_key.length);
		} else {
			DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
			session_key = data_blob_null;
		}
	} else if (user_session_key.data) {
		session_key = user_session_key;
		DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
		dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
	} else if (lm_session_key.data) {
		session_key = lm_session_key;
		DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
		dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
	} else {
		DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
		session_key = data_blob_null;
	}

	/* With KEY_EXCH, the client supplies the proposed session key, 
	   but encrypts it with the long-term key */
	if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
		if (!encrypted_session_key.data || encrypted_session_key.length != 16) {
			data_blob_free(&encrypted_session_key);
			DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", 
				  (unsigned int)encrypted_session_key.length));
			return NT_STATUS_INVALID_PARAMETER;
		} else if (!session_key.data || session_key.length != 16) {
			DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", 
				  (unsigned int)session_key.length));
			ntlmssp_state->session_key = session_key;
		} else {
			dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
			SamOEMhash(encrypted_session_key.data, 
				   session_key.data, 
				   encrypted_session_key.length);
			ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, 
								      encrypted_session_key.data, 
								      encrypted_session_key.length);
			dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, 
				     encrypted_session_key.length);
		}
	} else {
		ntlmssp_state->session_key = session_key;
	}

	if (!NT_STATUS_IS_OK(nt_status)) {
		ntlmssp_state->session_key = data_blob_null;
	} else if (ntlmssp_state->session_key.length) {
		nt_status = ntlmssp_sign_init(ntlmssp_state);
	}

	data_blob_free(&encrypted_session_key);
	
	/* Only one authentication allowed per server state. */
	ntlmssp_state->expected_state = NTLMSSP_DONE;

	return nt_status;
}
Пример #25
0
int turn(board_t *board) {
    int attack_lane, put_lane, put_num, i, check_card;
    switch(turn_options()) {
    case 1:
        i = 0;
        check_card=0;
        while(i < NUM_OF_CARDS_IN_HAND) {
            ++i;
            if((board->p[P_ONE].hand[i].name[0]!='\0')&&(board->p[P_ONE].hand[i].force!=0)&&
                    (board->p[P_ONE].hand[i].life!=0)&&(board->p[P_ONE].hand[i].cost!=0)&&
                    (board->p[P_ONE].hand[i].cost <= board->p[P_ONE].manapool.current_mana)) {
                check_card=1;
                break;
            }
        }
        if(check_card==0) {
            printf("Not enough mana\n");
            break;
        }
        printf("Choose a lane\n");
        while(1)
        {
            put_lane = validate_input(1, 5);
            // if the lane is not taken
            if(is_card_empty(board->lanes[P_ONE][put_lane-1]))
            {
                break;
            }
            printf("This line is taken.\n");
        }

        --put_lane; // the counting is 1-based
        while(1)
        {
            print_hand(board->p[P_ONE]);
            printf("Choose number of corresponding card\n");
            put_num = validate_input(1, num_of_cards_in_hand(board->p[P_ONE]));
            --put_num;  // the actual game uses 0-based counting
            // mostly needed for when this function is used for the AI
            if(can_play_card(board, P_ONE, get_card_from_hand(&board->p[P_ONE], put_num), put_lane)) {
                break;
            }
            sleep(2);
        }

        play_card(board, P_ONE, get_card_from_hand(&board->p[P_ONE], put_num), put_lane);
        break;
    case 2:
        // yep, empty case; SUE ME mwahahaha
        break;
    case 3:
        return 1;
    case 4:
        switch(shuffleChoice()) {
        case 1: {
            if(RandomShuffling(&(board->p[P_ONE].deck))) {
                file_save(&(board->p[P_ONE].deck));
            }
            break;
        }
        case 2: {
            if(manaOrder(&(board->p[P_ONE].deck))) {
                file_save(&(board->p[P_ONE].deck));
            }
            break;
        }
        case 3: {
            if(lifeOrder(&(board->p[P_ONE].deck))) {
                file_save(&(board->p[P_ONE].deck));
            }
            break;
        }
        case 4: {
            if(attackOrder(&(board->p[P_ONE].deck))) {
                file_save(&(board->p[P_ONE].deck));
            }
            break;
        }
        case 5: {
            if(costattackOrder(&(board->p[P_ONE].deck))) {
                file_save(&(board->p[P_ONE].deck));
            }
            break;
        }
        }
        break;
    }
    return 0;
}
Пример #26
0
static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
					 const DATA_BLOB request, DATA_BLOB *reply) 
{
	DATA_BLOB struct_blob;
	const char *dnsname;
	char *dnsdomname = NULL;
	uint32 neg_flags = 0;
	uint32 ntlmssp_command, chal_flags;
	const uint8 *cryptkey;
	const char *target_name;

	/* parse the NTLMSSP packet */
#if 0
	file_save("ntlmssp_negotiate.dat", request.data, request.length);
#endif

	if (request.length) {
		if ((request.length < 16) || !msrpc_parse(&request, "Cdd",
							"NTLMSSP",
							&ntlmssp_command,
							&neg_flags)) {
			DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
				(unsigned int)request.length));
			dump_data(2, request.data, request.length);
			return NT_STATUS_INVALID_PARAMETER;
		}
		debug_ntlmssp_flags(neg_flags);
	}

	ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());

	/* Ask our caller what challenge they would like in the packet */
	cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);

	/* Check if we may set the challenge */
	if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
	}

	/* The flags we send back are not just the negotiated flags,
	 * they are also 'what is in this packet'.  Therfore, we
	 * operate on 'chal_flags' from here on
	 */

	chal_flags = ntlmssp_state->neg_flags;

	/* get the right name to fill in as 'target' */
	target_name = ntlmssp_target_name(ntlmssp_state,
					  neg_flags, &chal_flags);
	if (target_name == NULL) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
	ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);

	/* This should be a 'netbios domain -> DNS domain' mapping */
	dnsdomname = get_mydnsdomname(ntlmssp_state->mem_ctx);
	if (!dnsdomname) {
		dnsdomname = talloc_strdup(ntlmssp_state->mem_ctx, "");
	}
	if (!dnsdomname) {
		return NT_STATUS_NO_MEMORY;
	}
	strlower_m(dnsdomname);

	dnsname = get_mydnsfullname();
	if (!dnsname) {
		dnsname = "";
	}

	/* This creates the 'blob' of names that appears at the end of the packet */
	if (chal_flags & NTLMSSP_CHAL_TARGET_INFO)
	{
		msrpc_gen(&struct_blob, "aaaaa",
			  NTLMSSP_NAME_TYPE_DOMAIN, target_name,
			  NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
			  NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
			  NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
			  0, "");
	} else {
		struct_blob = data_blob_null;
	}

	{
		/* Marshel the packet in the right format, be it unicode or ASCII */
		const char *gen_string;
		if (ntlmssp_state->unicode) {
			gen_string = "CdUdbddB";
		} else {
			gen_string = "CdAdbddB";
		}

		msrpc_gen(reply, gen_string,
			  "NTLMSSP",
			  NTLMSSP_CHALLENGE,
			  target_name,
			  chal_flags,
			  cryptkey, 8,
			  0, 0,
			  struct_blob.data, struct_blob.length);
	}

	data_blob_free(&struct_blob);

	ntlmssp_state->expected_state = NTLMSSP_AUTH;

	return NT_STATUS_MORE_PROCESSING_REQUIRED;
}
Пример #27
0
/* this performs a SASL/gssapi bind
   we avoid using cyrus-sasl to make Samba more robust. cyrus-sasl
   is very dependent on correctly configured DNS whereas
   this routine is much less fragile
   see RFC2078 and RFC2222 for details
*/
static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv_name)
{
	uint32_t minor_status;
	gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL;
	gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT;
	gss_OID mech_type = GSS_C_NULL_OID;
	gss_buffer_desc output_token, input_token;
	uint32_t req_flags, ret_flags;
	int conf_state;
	struct berval cred;
	struct berval *scred = NULL;
	int i=0;
	int gss_rc, rc;
	uint8_t *p;
	uint32_t max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED;
	uint8_t wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
	ADS_STATUS status;
	struct ads_saslwrap *wrap = &ads->ldap_wrap_data;

	input_token.value = NULL;
	input_token.length = 0;

	status = ads_init_gssapi_cred(ads, &gss_cred);
	if (!ADS_ERR_OK(status)) {
		goto failed;
	}

	/*
	 * Note: here we always ask the gssapi for sign and seal
	 *       as this is negotiated later after the mutal
	 *       authentication
	 */
	req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG;

	for (i=0; i < MAX_GSS_PASSES; i++) {
		gss_rc = gss_init_sec_context(&minor_status,
					  gss_cred,
					  &context_handle,
					  serv_name,
					  mech_type,
					  req_flags,
					  0,
					  NULL,
					  &input_token,
					  NULL,
					  &output_token,
					  &ret_flags,
					  NULL);
		if (scred) {
			ber_bvfree(scred);
			scred = NULL;
		}
		if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) {
			status = ADS_ERROR_GSS(gss_rc, minor_status);
			goto failed;
		}

		cred.bv_val = (char *)output_token.value;
		cred.bv_len = output_token.length;

		rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSSAPI", &cred, NULL, NULL, 
				      &scred);
		if (rc != LDAP_SASL_BIND_IN_PROGRESS) {
			status = ADS_ERROR(rc);
			goto failed;
		}

		if (output_token.value) {
			gss_release_buffer(&minor_status, &output_token);
		}

		if (scred) {
			input_token.value = scred->bv_val;
			input_token.length = scred->bv_len;
		} else {
			input_token.value = NULL;
			input_token.length = 0;
		}

		if (gss_rc == 0) break;
	}

	gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token,
			    &conf_state,NULL);
	if (scred) {
		ber_bvfree(scred);
		scred = NULL;
	}
	if (gss_rc) {
		status = ADS_ERROR_GSS(gss_rc, minor_status);
		goto failed;
	}

	p = (uint8_t *)output_token.value;

#if 0
	file_save("sasl_gssapi.dat", output_token.value, output_token.length);
#endif

	if (p) {
		wrap_type = CVAL(p,0);
		SCVAL(p,0,0);
		max_msg_size = RIVAL(p,0);
	}

	gss_release_buffer(&minor_status, &output_token);

	if (!(wrap_type & wrap->wrap_type)) {
		/*
		 * the server doesn't supports the wrap
		 * type we want :-(
		 */
		DEBUG(0,("The ldap sasl wrap type doesn't match wanted[%d] server[%d]\n",
			wrap->wrap_type, wrap_type));
		DEBUGADD(0,("You may want to set the 'client ldap sasl wrapping' option\n"));
		status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED);
		goto failed;
	}

	/* 0x58 is the minimum windows accepts */
	if (max_msg_size < 0x58) {
		max_msg_size = 0x58;
	}

	output_token.length = 4;
	output_token.value = SMB_MALLOC(output_token.length);
	if (!output_token.value) {
		output_token.length = 0;
		status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
		goto failed;
	}
	p = (uint8_t *)output_token.value;

	RSIVAL(p,0,max_msg_size);
	SCVAL(p,0,wrap->wrap_type);

	/*
	 * we used to add sprintf("dn:%s", ads->config.bind_path) here.
	 * but using ads->config.bind_path is the wrong! It should be
	 * the DN of the user object!
	 *
	 * w2k3 gives an error when we send an incorrect DN, but sending nothing
	 * is ok and matches the information flow used in GSS-SPNEGO.
	 */

	gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
			&output_token, /* used as *input* here. */
			&conf_state,
			&input_token); /* Used as *output* here. */
	if (gss_rc) {
		status = ADS_ERROR_GSS(gss_rc, minor_status);
		output_token.length = 0;
		SAFE_FREE(output_token.value);
		goto failed;
	}

	/* We've finished with output_token. */
	SAFE_FREE(output_token.value);
	output_token.length = 0;

	cred.bv_val = (char *)input_token.value;
	cred.bv_len = input_token.length;

	rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSSAPI", &cred, NULL, NULL, 
			      &scred);
	gss_release_buffer(&minor_status, &input_token);
	status = ADS_ERROR(rc);
	if (!ADS_ERR_OK(status)) {
		goto failed;
	}

	if (wrap->wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
		gss_rc = gss_wrap_size_limit(&minor_status, context_handle,
					     (wrap->wrap_type == ADS_SASLWRAP_TYPE_SEAL),
					     GSS_C_QOP_DEFAULT,
					     max_msg_size, &wrap->out.max_unwrapped);
		if (gss_rc) {
			status = ADS_ERROR_GSS(gss_rc, minor_status);
			goto failed;
		}

		wrap->out.sig_size = max_msg_size - wrap->out.max_unwrapped;
		wrap->in.min_wrapped = 0x2C; /* taken from a capture with LDAP unbind */
		wrap->in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED;
		status = ads_setup_sasl_wrapping(wrap->wrap_private_data, ads->ldap.ld,
						 &ads_sasl_gssapi_ops,
						 context_handle);
		if (!ADS_ERR_OK(status)) {
			DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n",
				ads_errstr(status)));
			goto failed;
		}
		/* make sure we don't free context_handle */
		context_handle = GSS_C_NO_CONTEXT;
	}

failed:
	if (gss_cred != GSS_C_NO_CREDENTIAL)
		gss_release_cred(&minor_status, &gss_cred);
	if (context_handle != GSS_C_NO_CONTEXT)
		gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER);

	if(scred)
		ber_bvfree(scred);
	return status;
}
Пример #28
0
/* 
   this performs a SASL/SPNEGO bind
*/
static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
{
	TALLOC_CTX *frame = talloc_stackframe();
	struct ads_service_principal p = {0};
	struct berval *scred=NULL;
	int rc, i;
	ADS_STATUS status;
	DATA_BLOB blob = data_blob_null;
	char *given_principal = NULL;
	char *OIDs[ASN1_MAX_OIDS];
#ifdef HAVE_KRB5
	bool got_kerberos_mechanism = False;
#endif
	const char *mech = NULL;

	rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred);

	if (rc != LDAP_SASL_BIND_IN_PROGRESS) {
		status = ADS_ERROR(rc);
		goto done;
	}

	blob = data_blob(scred->bv_val, scred->bv_len);

	ber_bvfree(scred);

#if 0
	file_save("sasl_spnego.dat", blob.data, blob.length);
#endif

	/* the server sent us the first part of the SPNEGO exchange in the negprot 
	   reply */
	if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &given_principal, NULL) ||
			OIDs[0] == NULL) {
		status = ADS_ERROR(LDAP_OPERATIONS_ERROR);
		goto done;
	}
	TALLOC_FREE(given_principal);

	/* make sure the server understands kerberos */
	for (i=0;OIDs[i];i++) {
		DEBUG(3,("ads_sasl_spnego_bind: got OID=%s\n", OIDs[i]));
#ifdef HAVE_KRB5
		if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
		    strcmp(OIDs[i], OID_KERBEROS5) == 0) {
			got_kerberos_mechanism = True;
		}
#endif
		talloc_free(OIDs[i]);
	}

	status = ads_generate_service_principal(ads, &p);
	if (!ADS_ERR_OK(status)) {
		goto done;
	}

#ifdef HAVE_KRB5
	if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) &&
	    got_kerberos_mechanism) 
	{
		mech = "KRB5";

		if (ads->auth.password == NULL ||
		    ads->auth.password[0] == '\0')
		{

			status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO",
							     CRED_MUST_USE_KERBEROS,
							     p.service, p.hostname,
							     blob);
			if (ADS_ERR_OK(status)) {
				ads_free_service_principal(&p);
				goto done;
			}

			DEBUG(10,("ads_sasl_spnego_gensec_bind(KRB5) failed with: %s, "
				  "calling kinit\n", ads_errstr(status)));
		}

		status = ADS_ERROR_KRB5(ads_kinit_password(ads)); 

		if (ADS_ERR_OK(status)) {
			status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO",
							CRED_MUST_USE_KERBEROS,
							p.service, p.hostname,
							blob);
			if (!ADS_ERR_OK(status)) {
				DEBUG(0,("kinit succeeded but "
					"ads_sasl_spnego_gensec_bind(KRB5) failed "
					"for %s/%s with user[%s] realm[%s]: %s\n",
					p.service, p.hostname,
					ads->auth.user_name,
					ads->auth.realm,
					ads_errstr(status)));
			}
		}

		/* only fallback to NTLMSSP if allowed */
		if (ADS_ERR_OK(status) || 
		    !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) {
			goto done;
		}

		DEBUG(1,("ads_sasl_spnego_gensec_bind(KRB5) failed "
			 "for %s/%s with user[%s] realm[%s]: %s, "
			 "fallback to NTLMSSP\n",
			 p.service, p.hostname,
			 ads->auth.user_name,
			 ads->auth.realm,
			 ads_errstr(status)));
	}
#endif

	/* lets do NTLMSSP ... this has the big advantage that we don't need
	   to sync clocks, and we don't rely on special versions of the krb5 
	   library for HMAC_MD4 encryption */
	mech = "NTLMSSP";
	status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO",
					     CRED_DONT_USE_KERBEROS,
					     p.service, p.hostname,
					     data_blob_null);
done:
	if (!ADS_ERR_OK(status)) {
		DEBUG(1,("ads_sasl_spnego_gensec_bind(%s) failed "
			 "for %s/%s with user[%s] realm=[%s]: %s\n", mech,
			  p.service, p.hostname,
			  ads->auth.user_name,
			  ads->auth.realm,
			  ads_errstr(status)));
	}
	ads_free_service_principal(&p);
	TALLOC_FREE(frame);
	if (blob.data != NULL) {
		data_blob_free(&blob);
	}
	return status;
}
Пример #29
0
static void reply_sesssetup_and_X_spnego(struct smb_request *req)
{
	const uint8_t *p;
	DATA_BLOB in_blob;
	DATA_BLOB out_blob = data_blob_null;
	size_t bufrem;
	char *tmp;
	const char *native_os;
	const char *native_lanman;
	const char *primary_domain;
	uint16_t data_blob_len = SVAL(req->vwv+7, 0);
	enum remote_arch_types ra_type = get_remote_arch();
	uint64_t vuid = req->vuid;
	NTSTATUS status = NT_STATUS_OK;
	struct smbXsrv_connection *xconn = req->xconn;
	struct smbd_server_connection *sconn = req->sconn;
	uint16_t action = 0;
	bool is_authenticated = false;
	NTTIME now = timeval_to_nttime(&req->request_time);
	struct smbXsrv_session *session = NULL;
	uint16_t smb_bufsize = SVAL(req->vwv+2, 0);
	uint32_t client_caps = IVAL(req->vwv+10, 0);
	struct smbXsrv_session_auth0 *auth;

	DEBUG(3,("Doing spnego session setup\n"));

	if (!xconn->smb1.sessions.done_sesssetup) {
		global_client_caps = client_caps;

		if (!(global_client_caps & CAP_STATUS32)) {
			remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
		}
	}

	p = req->buf;

	if (data_blob_len == 0) {
		/* an invalid request */
		reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
		return;
	}

	bufrem = smbreq_bufrem(req, p);
	/* pull the spnego blob */
	in_blob = data_blob_const(p, MIN(bufrem, data_blob_len));

#if 0
	file_save("negotiate.dat", in_blob.data, in_blob.length);
#endif

	p = req->buf + in_blob.length;

	p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
				     STR_TERMINATE);
	native_os = tmp ? tmp : "";

	p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
				     STR_TERMINATE);
	native_lanman = tmp ? tmp : "";

	p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
				     STR_TERMINATE);
	primary_domain = tmp ? tmp : "";

	DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
		native_os, native_lanman, primary_domain));

	if ( ra_type == RA_WIN2K ) {
		/* Vista sets neither the OS or lanman strings */

		if ( !strlen(native_os) && !strlen(native_lanman) )
			set_remote_arch(RA_VISTA);

		/* Windows 2003 doesn't set the native lanman string,
		   but does set primary domain which is a bug I think */

		if ( !strlen(native_lanman) ) {
			ra_lanman_string( primary_domain );
		} else {
			ra_lanman_string( native_lanman );
		}
	} else if ( ra_type == RA_VISTA ) {
		if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
			set_remote_arch(RA_OSX);
		}
	}

	if (vuid != 0) {
		status = smb1srv_session_lookup(xconn,
						vuid, now,
						&session);
		if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
			reply_force_doserror(req, ERRSRV, ERRbaduid);
			return;
		}
		if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
			status = NT_STATUS_OK;
		}
		if (NT_STATUS_IS_OK(status)) {
			session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
			status = NT_STATUS_MORE_PROCESSING_REQUIRED;
			TALLOC_FREE(session->pending_auth);
		}
		if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
			reply_nterror(req, nt_status_squash(status));
			return;
		}
	}

	if (session == NULL) {
		/* create a new session */
		status = smbXsrv_session_create(xconn,
					        now, &session);
		if (!NT_STATUS_IS_OK(status)) {
			reply_nterror(req, nt_status_squash(status));
			return;
		}
	}

	status = smbXsrv_session_find_auth(session, xconn, now, &auth);
	if (!NT_STATUS_IS_OK(status)) {
		status = smbXsrv_session_create_auth(session, xconn, now,
						     0, /* flags */
						     0, /* security */
						     &auth);
		if (!NT_STATUS_IS_OK(status)) {
			reply_nterror(req, nt_status_squash(status));
			return;
		}
	}

	if (auth->gensec == NULL) {
		status = auth_generic_prepare(session,
					      xconn->remote_address,
					      xconn->local_address,
					      "SMB",
					      &auth->gensec);
		if (!NT_STATUS_IS_OK(status)) {
			TALLOC_FREE(session);
			reply_nterror(req, nt_status_squash(status));
			return;
		}

		gensec_want_feature(auth->gensec, GENSEC_FEATURE_SESSION_KEY);
		gensec_want_feature(auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
		gensec_want_feature(auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);

		status = gensec_start_mech_by_oid(auth->gensec,
						  GENSEC_OID_SPNEGO);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("Failed to start SPNEGO handler!\n"));
			TALLOC_FREE(session);;
			reply_nterror(req, nt_status_squash(status));
			return;
		}
	}

	become_root();
	status = gensec_update(auth->gensec,
			       talloc_tos(),
			       in_blob, &out_blob);
	unbecome_root();
	if (!NT_STATUS_IS_OK(status) &&
	    !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
		TALLOC_FREE(session);
		reply_nterror(req, nt_status_squash(status));
		return;
	}

	if (NT_STATUS_IS_OK(status) && session->global->auth_session_info == NULL) {
		struct auth_session_info *session_info = NULL;

		status = gensec_session_info(auth->gensec,
					     session,
					     &session_info);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(1,("Failed to generate session_info "
				 "(user and group token) for session setup: %s\n",
				 nt_errstr(status)));
			data_blob_free(&out_blob);
			TALLOC_FREE(session);
			reply_nterror(req, nt_status_squash(status));
			return;
		}

		if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
			action |= SMB_SETUP_GUEST;
		}

		if (session_info->session_key.length > 0) {
			struct smbXsrv_session *x = session;

			/*
			 * Note: the SMB1 signing key is not truncated to 16 byte!
			 */
			x->global->signing_key =
				data_blob_dup_talloc(x->global,
						     session_info->session_key);
			if (x->global->signing_key.data == NULL) {
				data_blob_free(&out_blob);
				TALLOC_FREE(session);
				reply_nterror(req, NT_STATUS_NO_MEMORY);
				return;
			}

			/*
			 * clear the session key
			 * the first tcon will add setup the application key
			 */
			data_blob_clear_free(&session_info->session_key);
		}

		session->compat = talloc_zero(session, struct user_struct);
		if (session->compat == NULL) {
			data_blob_free(&out_blob);
			TALLOC_FREE(session);
			reply_nterror(req, NT_STATUS_NO_MEMORY);
			return;
		}
		session->compat->session = session;
		session->compat->homes_snum = -1;
		session->compat->session_info = session_info;
		session->compat->session_keystr = NULL;
		session->compat->vuid = session->global->session_wire_id;
		DLIST_ADD(sconn->users, session->compat);
		sconn->num_users++;

		if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
			is_authenticated = true;
			session->compat->homes_snum =
				register_homes_share(session_info->unix_info->unix_name);
		}

		if (srv_is_signing_negotiated(xconn) &&
		    is_authenticated &&
		    session->global->signing_key.length > 0)
		{
			/*
			 * Try and turn on server signing on the first non-guest
			 * sessionsetup.
			 */
			srv_set_signing(xconn,
				session->global->signing_key,
				data_blob_null);
		}

		set_current_user_info(session_info->unix_info->sanitized_username,
				      session_info->unix_info->unix_name,
				      session_info->info->domain_name);

		session->status = NT_STATUS_OK;
		session->global->auth_session_info = talloc_move(session->global,
								 &session_info);
		session->global->auth_session_info_seqnum += 1;
		session->global->channels[0].auth_session_info_seqnum =
			session->global->auth_session_info_seqnum;
		session->global->auth_time = now;
		if (client_caps & CAP_DYNAMIC_REAUTH) {
			session->global->expiration_time =
				gensec_expire_time(auth->gensec);
		} else {
			session->global->expiration_time =
				GENSEC_EXPIRE_TIME_INFINITY;
		}

		if (!session_claim(session)) {
			DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
				  (unsigned long long)session->compat->vuid));
			data_blob_free(&out_blob);
			TALLOC_FREE(session);
			reply_nterror(req, NT_STATUS_LOGON_FAILURE);
			return;
		}

		status = smbXsrv_session_update(session);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
				  (unsigned long long)session->compat->vuid,
				  nt_errstr(status)));
			data_blob_free(&out_blob);
			TALLOC_FREE(session);
			reply_nterror(req, NT_STATUS_LOGON_FAILURE);
			return;
		}

		if (!xconn->smb1.sessions.done_sesssetup) {
			if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
				reply_force_doserror(req, ERRSRV, ERRerror);
				return;
			}
			xconn->smb1.sessions.max_send = smb_bufsize;
			xconn->smb1.sessions.done_sesssetup = true;
		}

		/* current_user_info is changed on new vuid */
		reload_services(sconn, conn_snum_used, true);
	} else if (NT_STATUS_IS_OK(status)) {
Пример #30
0
/* 
   this performs a SASL/SPNEGO bind
*/
static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
{
	struct berval *scred=NULL;
	int rc, i;
	ADS_STATUS status;
	DATA_BLOB blob;
	char *given_principal = NULL;
	char *OIDs[ASN1_MAX_OIDS];
#ifdef HAVE_KRB5
	bool got_kerberos_mechanism = False;
#endif

	rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred);

	if (rc != LDAP_SASL_BIND_IN_PROGRESS) {
		status = ADS_ERROR(rc);
		goto failed;
	}

	blob = data_blob(scred->bv_val, scred->bv_len);

	ber_bvfree(scred);

#if 0
	file_save("sasl_spnego.dat", blob.data, blob.length);
#endif

	/* the server sent us the first part of the SPNEGO exchange in the negprot 
	   reply */
	if (!spnego_parse_negTokenInit(blob, OIDs, &given_principal)) {
		data_blob_free(&blob);
		status = ADS_ERROR(LDAP_OPERATIONS_ERROR);
		goto failed;
	}
	data_blob_free(&blob);

	/* make sure the server understands kerberos */
	for (i=0;OIDs[i];i++) {
		DEBUG(3,("ads_sasl_spnego_bind: got OID=%s\n", OIDs[i]));
#ifdef HAVE_KRB5
		if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
		    strcmp(OIDs[i], OID_KERBEROS5) == 0) {
			got_kerberos_mechanism = True;
		}
#endif
		talloc_free(OIDs[i]);
	}
	DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", given_principal));

#ifdef HAVE_KRB5
	if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) &&
	    got_kerberos_mechanism) 
	{
		struct ads_service_principal p;

		status = ads_generate_service_principal(ads, given_principal, &p);
		TALLOC_FREE(given_principal);
		if (!ADS_ERR_OK(status)) {
			return status;
		}

		status = ads_sasl_spnego_krb5_bind(ads, &p);
		if (ADS_ERR_OK(status)) {
			ads_free_service_principal(&p);
			return status;
		}

		DEBUG(10,("ads_sasl_spnego_krb5_bind failed with: %s, "
			  "calling kinit\n", ads_errstr(status)));

		status = ADS_ERROR_KRB5(ads_kinit_password(ads)); 

		if (ADS_ERR_OK(status)) {
			status = ads_sasl_spnego_krb5_bind(ads, &p);
			if (!ADS_ERR_OK(status)) {
				DEBUG(0,("kinit succeeded but "
					"ads_sasl_spnego_krb5_bind failed: %s\n",
					ads_errstr(status)));
			}
		}

		ads_free_service_principal(&p);

		/* only fallback to NTLMSSP if allowed */
		if (ADS_ERR_OK(status) || 
		    !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) {
			return status;
		}
	} else
#endif
	{
		TALLOC_FREE(given_principal);
	}

	/* lets do NTLMSSP ... this has the big advantage that we don't need
	   to sync clocks, and we don't rely on special versions of the krb5 
	   library for HMAC_MD4 encryption */
	return ads_sasl_spnego_ntlmssp_bind(ads);

failed:
	return status;
}