Пример #1
0
static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ports)
{
	int num_interfaces = iface_count();
	int num_sockets = 0;
	int fd_listenset[FD_SETSIZE];
	fd_set listen_set;
	int s;
	int maxfd = 0;
	int i;
	char *ports;

	if (!is_daemon) {
		return open_sockets_inetd();
	}

		
#ifdef HAVE_ATEXIT
	{
		static int atexit_set;
		if(atexit_set == 0) {
			atexit_set=1;
			atexit(killkids);
		}
	}
#endif

#ifndef _XBOX
	/* Stop zombies */
	CatchChild();
#endif

	FD_ZERO(&listen_set);

	/* use a reasonable default set of ports - listing on 445 and 139 */
	if (!smb_ports) {
		ports = lp_smb_ports();
		if (!ports || !*ports) {
			ports = smb_xstrdup(SMB_PORTS);
		} else {
			ports = smb_xstrdup(ports);
		}
	} else {
		ports = smb_xstrdup(smb_ports);
	}

	if (lp_interfaces() && lp_bind_interfaces_only()) {
		/* We have been given an interfaces line, and been 
		   told to only bind to those interfaces. Create a
		   socket per interface and bind to only these.
		*/
		
		/* Now open a listen socket for each of the
		   interfaces. */
		for(i = 0; i < num_interfaces; i++) {
			struct in_addr *ifip = iface_n_ip(i);
			fstring tok;
			const char *ptr;

			if(ifip == NULL) {
				DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
				continue;
			}

			for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
				unsigned port = atoi(tok);
				if (port == 0) {
					continue;
				}
				s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
				if(s == -1)
					return False;

				/* ready to listen */
				set_socket_options(s,"SO_KEEPALIVE"); 
				set_socket_options(s,user_socket_options);
     
				/* Set server socket to non-blocking for the accept. */
				set_blocking(s,False); 
 
				if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
					DEBUG(0,("listen: %s\n",strerror(errno)));
					close(s);
					return False;
				}
				FD_SET(s,&listen_set);
				maxfd = MAX( maxfd, s);

				num_sockets++;
				if (num_sockets >= FD_SETSIZE) {
					DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
					return False;
				}
			}
		}
	} else {
		/* Just bind to 0.0.0.0 - accept connections
		   from anywhere. */

		fstring tok;
		const char *ptr;

		num_interfaces = 1;
		
		for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
			unsigned port = atoi(tok);
			if (port == 0) continue;
			/* open an incoming socket */
			s = open_socket_in(SOCK_STREAM, port, 0,
					   interpret_addr(lp_socket_address()),True);
			if (s == -1)
				return(False);
		
			/* ready to listen */
#ifndef _XBOX
			set_socket_options(s,"SO_KEEPALIVE"); 
#endif
			set_socket_options(s,user_socket_options);
			
			/* Set server socket to non-blocking for the accept. */
			set_blocking(s,False); 
 
			if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
				DEBUG(0,("open_sockets_smbd: listen: %s\n",
					 strerror(errno)));
				close(s);
				return False;
			}

			fd_listenset[num_sockets] = s;
			FD_SET(s,&listen_set);
			maxfd = MAX( maxfd, s);

			num_sockets++;

			if (num_sockets >= FD_SETSIZE) {
				DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
				return False;
			}
		}
	} 

	SAFE_FREE(ports);

        /* Listen to messages */

        message_register(MSG_SMB_SAM_SYNC, msg_sam_sync);
        message_register(MSG_SMB_SAM_REPL, msg_sam_repl);
        message_register(MSG_SHUTDOWN, msg_exit_server);
        message_register(MSG_SMB_FILE_RENAME, msg_file_was_renamed);
	message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated); 

#ifdef DEVELOPER
	message_register(MSG_SMB_INJECT_FAULT, msg_inject_fault); 
#endif

	/* now accept incoming connections - forking a new process
	   for each incoming connection */
	DEBUG(2,("waiting for a connection\n"));
	while (1) {
		fd_set lfds;
		int num;
		
		/* Free up temporary memory from the main smbd. */
		lp_TALLOC_FREE();

		/* Ensure we respond to PING and DEBUG messages from the main smbd. */
		message_dispatch();

		memcpy((char *)&lfds, (char *)&listen_set, 
		       sizeof(listen_set));
		
		num = sys_select(maxfd+1,&lfds,NULL,NULL,NULL);
		
		if (num == -1 && errno == EINTR) {
			if (got_sig_term) {
				exit_server_cleanly(NULL);
			}

			/* check for sighup processing */
			if (reload_after_sighup) {
				change_to_root_user();
				DEBUG(1,("Reloading services after SIGHUP\n"));
				reload_services(False);
				reload_after_sighup = 0;
			}

			continue;
		}
		
		/* check if we need to reload services */
		check_reload(time(NULL));

		/* Find the sockets that are read-ready -
		   accept on these. */
		for( ; num > 0; num--) {
			struct sockaddr addr;
			socklen_t in_addrlen = sizeof(addr);

			s = -1;
			for(i = 0; i < num_sockets; i++) {
				if(FD_ISSET(fd_listenset[i],&lfds)) {
					s = fd_listenset[i];
					/* Clear this so we don't look
					   at it again. */
					FD_CLR(fd_listenset[i],&lfds);
					break;
				}
			}

			smbd_set_server_fd(accept(s,&addr,&in_addrlen));
			
			if (smbd_server_fd() == -1 && errno == EINTR)
				continue;
			
			if (smbd_server_fd() == -1) {
				DEBUG(0,("open_sockets_smbd: accept: %s\n",
					 strerror(errno)));
				continue;
			}

			/* Ensure child is set to blocking mode */
			set_blocking(smbd_server_fd(),True);

			if (smbd_server_fd() != -1 && interactive) {
#ifdef _XBOX
				xb_IncClientCount();
#endif
				return True;
			}
			
			if (allowable_number_of_smbd_processes() && smbd_server_fd() != -1 && sys_fork()==0) {


				/* Child code ... */			

				/* close the listening socket(s) */
				for(i = 0; i < num_sockets; i++)
					close(fd_listenset[i]);
				
				/* close our standard file
				   descriptors */
				close_low_fds(False);
				am_parent = 0;
				
				set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
				set_socket_options(smbd_server_fd(),user_socket_options);
				
				/* this is needed so that we get decent entries
				   in smbstatus for port 445 connects */
				set_remote_machine_name(get_peer_addr(smbd_server_fd()), False);
				
				/* Reset the state of the random
				 * number generation system, so
				 * children do not get the same random
				 * numbers as each other */

				set_need_random_reseed();
				/* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */
				if (tdb_reopen_all(1) == -1) {
					DEBUG(0,("tdb_reopen_all failed.\n"));
					smb_panic("tdb_reopen_all failed.");
				}

				return True; 
			}
			/* The parent doesn't need this socket */
			close(smbd_server_fd()); 

			/* Sun May 6 18:56:14 2001 [email protected]:
				Clear the closed fd info out of server_fd --
				and more importantly, out of client_fd in
				util_sock.c, to avoid a possible
				getpeername failure if we reopen the logs
				and use %I in the filename.
			*/

			smbd_set_server_fd(-1);

			/* Force parent to check log size after
			 * spawning child.  Fix from
			 * [email protected].  The
			 * parent smbd will log to logserver.smb.  It
			 * writes only two messages for each child
			 * started/finished. But each child writes,
			 * say, 50 messages also in logserver.smb,
			 * begining with the debug_count of the
			 * parent, before the child opens its own log
			 * file logserver.client. In a worst case
			 * scenario the size of logserver.smb would be
			 * checked after about 50*50=2500 messages
			 * (ca. 100kb).
			 * */
			force_check_log_size();
 
		} /* end for num */
	} /* end while 1 */

/* NOTREACHED	return True; */
}
Пример #2
0
INT_PTR CALLBACK DlgProcIconImport(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	static HWND hwndParent, hwndDragOver;
	static int dragging;
	static int dragItem, dropHiLite;
	static HWND hPreview = NULL;

	switch (msg) {
	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);
		hwndParent = (HWND)lParam;
		hPreview = GetDlgItem(hwndDlg, IDC_PREVIEW);
		dragging = dragItem = 0;
		ListView_SetImageList(hPreview, ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32|ILC_MASK, 0, 100), LVSIL_NORMAL);
		ListView_SetIconSpacing(hPreview, 56, 67);
		{
			RECT rcThis, rcParent;
			int cxScreen = GetSystemMetrics(SM_CXSCREEN);

			GetWindowRect(hwndDlg, &rcThis);
			GetWindowRect(hwndParent, &rcParent);
			OffsetRect(&rcThis, rcParent.right-rcThis.left, 0);
			OffsetRect(&rcThis, 0, rcParent.top-rcThis.top);
			GetWindowRect(GetParent(hwndParent), &rcParent);
			if (rcThis.right > cxScreen) {
				OffsetRect(&rcParent, cxScreen-rcThis.right, 0);
				OffsetRect(&rcThis, cxScreen-rcThis.right, 0);
				MoveWindow(GetParent(hwndParent), rcParent.left, rcParent.top, rcParent.right-rcParent.left, rcParent.bottom-rcParent.top, TRUE);
			}
			MoveWindow(hwndDlg, rcThis.left, rcThis.top, rcThis.right-rcThis.left, rcThis.bottom-rcThis.top, FALSE);
			GetClientRect(hwndDlg, &rcThis);
			SendMessage(hwndDlg, WM_SIZE, 0, MAKELPARAM(rcThis.right-rcThis.left, rcThis.bottom-rcThis.top));
		}

		SHAutoComplete( GetDlgItem(hwndDlg, IDC_ICONSET), 1);

		SetDlgItemText(hwndDlg, IDC_ICONSET, _T("icons.dll"));
		return TRUE;

	case DM_REBUILDICONSPREVIEW:
		{
			MySetCursor(IDC_WAIT);
			ListView_DeleteAllItems(hPreview);
			HIMAGELIST hIml = ListView_GetImageList(hPreview, LVSIL_NORMAL);
			ImageList_RemoveAll(hIml);

			TCHAR filename[MAX_PATH], caption[64];
			GetDlgItemText(hwndDlg, IDC_ICONSET, filename, SIZEOF(filename));
			{
				RECT rcPreview, rcGroup;

				GetWindowRect(hPreview, &rcPreview);
				GetWindowRect( GetDlgItem(hwndDlg, IDC_IMPORTMULTI), &rcGroup);
				//SetWindowPos(hPreview, 0, 0, 0, rcPreview.right-rcPreview.left, rcGroup.bottom-rcPreview.top, SWP_NOZORDER|SWP_NOMOVE);
			}

			if ( _taccess(filename, 0) != 0) {
				MySetCursor(IDC_ARROW);
				break;
			}

			LVITEM lvi;
			lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
			lvi.iSubItem = 0;
			lvi.iItem = 0;
			int count = (int)_ExtractIconEx(filename, -1, 16, 16, NULL, LR_DEFAULTCOLOR);
			for (int i=0; i < count; lvi.iItem++, i++) {
				mir_sntprintf(caption, SIZEOF(caption), _T("%d"), i+1);
				lvi.pszText = caption;

				HICON hIcon;
				_ExtractIconEx(filename, i, 16, 16, &hIcon, LR_DEFAULTCOLOR);
				lvi.iImage = ImageList_AddIcon(hIml, hIcon);
				DestroyIcon(hIcon);
				lvi.lParam = i;
				ListView_InsertItem(hPreview, &lvi);
			}
			MySetCursor(IDC_ARROW);
		}
		break;

	case WM_COMMAND:
		switch(LOWORD(wParam)) {
		case IDC_BROWSE:
			{
				TCHAR str[MAX_PATH], *file;
				GetDlgItemText(hwndDlg, IDC_ICONSET, str, SIZEOF(str));
				if (!(file = OpenFileDlg(GetParent(hwndDlg), str, TRUE)))
					break;
				SetDlgItemText(hwndDlg, IDC_ICONSET, file);
				SAFE_FREE((void**)&file);
			}
			break;

		case IDC_GETMORE:
			OpenIconsPage();
			break;

		case IDC_ICONSET:
			if (HIWORD(wParam) == EN_CHANGE)
				SendMessage(hwndDlg, DM_REBUILDICONSPREVIEW, 0, 0);
			break;
		}
		break;

	case WM_MOUSEMOVE:
		if (dragging) {
			LVHITTESTINFO lvhti;
			int onItem = 0;
			HWND hwndOver;
			RECT rc;
			POINT ptDrag;
			HWND hPPreview = GetDlgItem(hwndParent, IDC_PREVIEW);

			lvhti.pt.x = (short)LOWORD(lParam); lvhti.pt.y = (short)HIWORD(lParam);
			ClientToScreen(hwndDlg, &lvhti.pt);
			hwndOver = WindowFromPoint(lvhti.pt);
			GetWindowRect(hwndOver, &rc);
			ptDrag.x = lvhti.pt.x - rc.left; ptDrag.y = lvhti.pt.y - rc.top;
			if (hwndOver != hwndDragOver) {
				ImageList_DragLeave(hwndDragOver);
				hwndDragOver = hwndOver;
				ImageList_DragEnter(hwndDragOver, ptDrag.x, ptDrag.y);
			}

			ImageList_DragMove(ptDrag.x, ptDrag.y);
			if (hwndOver == hPPreview) {
				ScreenToClient(hPPreview, &lvhti.pt);

				if (ListView_HitTest(hPPreview, &lvhti) != -1) {
					if (lvhti.iItem != dropHiLite) {
						ImageList_DragLeave(hwndDragOver);
						if (dropHiLite != -1)
							ListView_SetItemState(hPPreview, dropHiLite, 0, LVIS_DROPHILITED);
						dropHiLite = lvhti.iItem;
						ListView_SetItemState(hPPreview, dropHiLite, LVIS_DROPHILITED, LVIS_DROPHILITED);
						UpdateWindow(hPPreview);
						ImageList_DragEnter(hwndDragOver, ptDrag.x, ptDrag.y);
					}
					onItem = 1;
				}
			}

			if (!onItem && dropHiLite != -1) {
				ImageList_DragLeave(hwndDragOver);
				ListView_SetItemState(hPPreview, dropHiLite, 0, LVIS_DROPHILITED);
				UpdateWindow(hPPreview);
				ImageList_DragEnter(hwndDragOver, ptDrag.x, ptDrag.y);
				dropHiLite = -1;
			}
			MySetCursor(onItem ? IDC_ARROW : IDC_NO);
		}
		break;

	case WM_LBUTTONUP:
		if (dragging) {
			ReleaseCapture();
			ImageList_EndDrag();
			dragging = 0;
			if (dropHiLite != -1) {
				TCHAR path[MAX_PATH], fullPath[MAX_PATH], filename[MAX_PATH];
				LVITEM lvi;

				GetDlgItemText(hwndDlg, IDC_ICONSET, fullPath, SIZEOF(fullPath));
				PathToRelativeT(fullPath, filename);
				lvi.mask = LVIF_PARAM;
				lvi.iItem = dragItem; lvi.iSubItem = 0;
				ListView_GetItem(hPreview, &lvi);
				mir_sntprintf(path, SIZEOF(path), _T("%s,%d"), filename, (int)lvi.lParam);
				SendMessage(hwndParent, DM_CHANGEICON, dropHiLite, (LPARAM)path);
				ListView_SetItemState( GetDlgItem(hwndParent, IDC_PREVIEW), dropHiLite, 0, LVIS_DROPHILITED);
			}
		}
		break;

	case WM_NOTIFY:
		switch (((LPNMHDR)lParam)->idFrom) {
		case IDC_PREVIEW:
			switch (((LPNMHDR)lParam)->code) {
			case LVN_BEGINDRAG:
				SetCapture(hwndDlg);
				dragging = 1;
				dragItem = ((LPNMLISTVIEW)lParam)->iItem;
				dropHiLite = -1;
				ImageList_BeginDrag(ListView_GetImageList(hPreview, LVSIL_NORMAL), dragItem, GetSystemMetrics(SM_CXICON)/2, GetSystemMetrics(SM_CYICON)/2);
				{
					POINT pt;
					RECT rc;

					GetCursorPos(&pt);
					GetWindowRect(hwndDlg, &rc);
					ImageList_DragEnter(hwndDlg, pt.x - rc.left, pt.y - rc.top);
					hwndDragOver = hwndDlg;
				}
				break;
			}
			break;
		}
		break;

	case WM_SIZE: // make the dlg resizeable
		if (!IsIconic(hwndDlg)) {
			UTILRESIZEDIALOG urd = {0};
			urd.cbSize = sizeof(urd);
			urd.hInstance = hInst;
			urd.hwndDlg = hwndDlg;
			urd.lParam = 0; // user-defined
			urd.lpTemplate = MAKEINTRESOURCEA(IDD_ICOLIB_IMPORT);
			urd.pfnResizer = IconDlg_Resize;
			CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd);
		}
		break;

	case WM_CLOSE:
		DestroyWindow(hwndDlg);
		EnableWindow( GetDlgItem(hwndParent, IDC_IMPORT), TRUE);
		break;

	}

	return FALSE;
}
Пример #3
0
/* for keeping the connection list in sync with the conntrack list */
static gboolean refresh_connections(gpointer data)
{
   struct row_pairs *lastconn = NULL, *cache = NULL;
   GtkTreeModel *model = GTK_TREE_MODEL (ls_conns);
   void *list, *next, *listend;
   char *desc;                  /* holds line from conntrack_print */
   GtkTreeIter iter;            /* points to a specific row */
   char flags[2], status[8];
   unsigned int xferred = 0;
   struct row_pairs *row = NULL, *nextrow = NULL, top, bottom;

   /* null terminate strings */
   flags[1] = 0;
   status[7] = 0;

   /* make sure the list has been created and window is visible */
   if(ls_conns) {
      if (!GTK_WIDGET_VISIBLE(conns_window))
         return(FALSE);
   } else {
      /* Columns:   Flags, Host, Port, "-",   Host, Port,
                    Proto, State, Bytes, (hidden) pointer */
      ls_conns = gtk_list_store_new (10, 
                    G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, 
                    G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, 
                    G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, 
                    G_TYPE_POINTER);
      connections = NULL;
   }

   /* remove old connections */
   for(row = connections; row; row = nextrow) {
       nextrow = row->next;
       if(conntrack_print(0, row->conn, NULL, 0) == NULL) {
          /* remove row from the GTK list */
          gtk_list_store_remove(GTK_LIST_STORE(ls_conns), &row->iter);

          /* remove pointers from the linked-list and free */
          if(row->next)
              row->next->prev = row->prev;

          if(row->prev)
              row->prev->next = row->next;
          else
              connections = row->next;
          free(row);
          row = NULL;
       }
       if(row)
           lastconn = row;
   }

   /* make sure we have a place to start searching for new rows */
   if(!lastconn) {
      listend = conntrack_print(0, NULL, NULL, 0);
      if(listend == NULL)
         return(TRUE);
   } else {
      listend = lastconn->conn;
   }

   /* allocate space for conntrack_print to pass connection data */
   SAFE_CALLOC(desc, 100, sizeof(char));

   /* add new connections */
   for(list = conntrack_print(+1, listend, NULL, 0); list; list = next) {
      next = conntrack_print(+1, list, &desc, 99);
      cache = gtkui_connections_add(desc, list, &connections);
      if(cache)
         lastconn = cache;
   }

   /* find the first and last visible rows */
   gtkui_connection_list_row(1, &top);
   gtkui_connection_list_row(0, &bottom);

   if(top.conn == NULL) 
      return(TRUE);

   iter = top.iter; /* copy iter by value */

   /* update visible part of list */
   do {
      /* get the conntrack pointer for this row */
      gtk_tree_model_get (model, &iter, 9, &list, -1);
      conntrack_print(0, list, &desc, 99);

      /* extract changing values from conntrack_print string */
      flags[0] = desc[0];
      strncpy(status, desc+50, 7);
      int i =sscanf(desc+62, "%u", &xferred);
      BUG_IF(i!=1);  

      gtk_list_store_set (ls_conns, &iter, 0, flags, 7, status, 8, xferred, -1);

      /* when we reach the bottom of the visible part, stop updating */
      if(bottom.conn == list)
         break;
   } while(gtk_tree_model_iter_next(model, &iter));
  
   SAFE_FREE(desc); 
   return(TRUE);
}
Пример #4
0
static int _csync_remove_dir(CSYNC *ctx, csync_file_stat_t *st) {
  c_list_t *list = NULL;
  char errbuf[256] = {0};
  char *uri = NULL;
  int rc = -1;

  switch (ctx->current) {
    case LOCAL_REPLICA:
      if (asprintf(&uri, "%s/%s", ctx->local.uri, st->path) < 0) {
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        return -1;
      }
      break;
    case REMOTE_REPLICA:
      if (asprintf(&uri, "%s/%s", ctx->remote.uri, st->path) < 0) {
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        return -1;
      }
      break;
    default:
      break;
  }

  if (csync_vio_rmdir(ctx, uri) < 0) {
    ctx->status_code = csync_errno_to_status(errno,
                                             CSYNC_STATUS_PROPAGATE_ERROR);
    switch (errno) {
      case ENOMEM:
        strerror_r(errno, errbuf, sizeof(errbuf));
        CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
            "dir: %s, command: rmdir, error: %s",
            uri,
            errbuf);
        rc = -1;
        break;
      case ENOTEMPTY:
        switch (ctx->current) {
          case LOCAL_REPLICA:
            list = c_list_prepend(ctx->local.list, (void *) st);
            if (list == NULL) {
              ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
              return -1;
            }
            ctx->local.list = list;
            break;
          case REMOTE_REPLICA:
            list = c_list_prepend(ctx->remote.list, (void *) st);
            if (list == NULL) {
              ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
              return -1;
            }
            ctx->remote.list = list;
            break;
          default:
            break;
        }
        rc = 0;
        break;
      default:
        strerror_r(errno, errbuf, sizeof(errbuf));
        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
            "dir: %s, command: rmdir, error: %s",
            uri,
            errbuf);
        rc = 1;
        break;
    }
    goto out;
  }

  /* set instruction for the statedb merger */
  st->instruction = CSYNC_INSTRUCTION_DELETED;

  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "REMOVED  dir: %s", uri);

  rc = 0;
out:
  SAFE_FREE(uri);

  /* set instruction for the statedb merger */
  if (rc != 0) {
    st->instruction = CSYNC_INSTRUCTION_NONE;
  }

  return rc;
}
Пример #5
0
static acl_t smb_acl_to_posix(const struct smb_acl_t *acl)
{
	acl_t result;
	int i;

	result = acl_init(acl->count);
	if (result == NULL) {
		DEBUG(10, ("acl_init failed\n"));
		return NULL;
	}

	for (i=0; i<acl->count; i++) {
		const struct smb_acl_entry *entry = &acl->acl[i];
		acl_entry_t e;
		acl_tag_t tag;

		if (acl_create_entry(&result, &e) != 0) {
			DEBUG(1, ("acl_create_entry failed: %s\n",
				  strerror(errno)));
			goto fail;
		}

		switch (entry->a_type) {
		case SMB_ACL_USER:
			tag = ACL_USER;
			break;
		case SMB_ACL_USER_OBJ:
			tag = ACL_USER_OBJ;
			break;
		case SMB_ACL_GROUP:
			tag = ACL_GROUP;
			break;
		case SMB_ACL_GROUP_OBJ:
			tag = ACL_GROUP_OBJ;
			break;
		case SMB_ACL_OTHER:
			tag = ACL_OTHER;
			break;
		case SMB_ACL_MASK:
			tag = ACL_MASK;
			break;
		default:
			DEBUG(1, ("Unknown tag value %d\n", entry->a_type));
			goto fail;
		}

		if (acl_set_tag_type(e, tag) != 0) {
			DEBUG(10, ("acl_set_tag_type(%d) failed: %s\n",
				   tag, strerror(errno)));
			goto fail;
		}

		switch (entry->a_type) {
		case SMB_ACL_USER:
			if (acl_set_qualifier(e, &entry->info.user.uid) != 0) {
				DEBUG(1, ("acl_set_qualifiier failed: %s\n",
					  strerror(errno)));
				goto fail;
			}
			break;
		case SMB_ACL_GROUP:
			if (acl_set_qualifier(e, &entry->info.group.gid) != 0) {
				DEBUG(1, ("acl_set_qualifiier failed: %s\n",
					  strerror(errno)));
				goto fail;
			}
			break;
		default: 	/* Shut up, compiler! :-) */
			break;
		}

		if (smb_acl_set_mode(e, entry->a_perm) != 0) {
			goto fail;
		}
	}

	if (acl_valid(result) != 0) {
		char *acl_string = sys_acl_to_text(acl, NULL);
		DEBUG(0, ("smb_acl_to_posix: ACL %s is invalid for set (%s)\n",
			  acl_string, strerror(errno)));
		SAFE_FREE(acl_string);
		goto fail;
	}

	return result;

 fail:
	if (result != NULL) {
		acl_free(result);
	}
	return NULL;
}
/*!
 * @brief Initialise the HTTP(S) connection.
 * @param remote Pointer to the remote instance with the HTTP(S) transport details wired in.
 * @param sock Reference to the original socket FD passed to metsrv (ignored);
 * @return Indication of success or failure.
 */
static BOOL server_init_wininet(Transport* transport)
{
	URL_COMPONENTS bits;
	wchar_t tmpHostName[URL_SIZE];
	wchar_t tmpUrlPath[URL_SIZE];
	HttpTransportContext* ctx = (HttpTransportContext*)transport->ctx;

	dprintf("[WININET] Initialising ...");

	// configure proxy
	if (ctx->proxy)
	{
		dprintf("[DISPATCH] Configuring with proxy: %S", ctx->proxy);
		ctx->internet = InternetOpenW(ctx->ua, INTERNET_OPEN_TYPE_PROXY, ctx->proxy, NULL, 0);
	}
	else
	{
		ctx->internet = InternetOpenW(ctx->ua, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	}

	if (!ctx->internet)
	{
		dprintf("[DISPATCH] Failed InternetOpenW: %d", GetLastError());
		return FALSE;
	}

	dprintf("[DISPATCH] Configured hInternet: 0x%.8x", ctx->internet);

	// The InternetCrackUrl method was poorly designed...
	ZeroMemory(tmpHostName, sizeof(tmpHostName));
	ZeroMemory(tmpUrlPath, sizeof(tmpUrlPath));

	ZeroMemory(&bits, sizeof(bits));
	bits.dwStructSize = sizeof(bits);

	bits.dwHostNameLength = URL_SIZE - 1;
	bits.lpszHostName = tmpHostName;

	bits.dwUrlPathLength = URL_SIZE - 1;
	bits.lpszUrlPath = tmpUrlPath;

	dprintf("[DISPATCH] About to crack URL: %S", transport->url);
	InternetCrackUrlW(transport->url, 0, 0, &bits);

	SAFE_FREE(ctx->uri);
	ctx->uri = _wcsdup(tmpUrlPath);
	transport->comms_last_packet = current_unix_timestamp();

	dprintf("[DISPATCH] Configured URI: %S", ctx->uri);
	dprintf("[DISPATCH] Host: %S Port: %u", tmpHostName, bits.nPort);

	// Allocate the connection handle
	ctx->connection = InternetConnectW(ctx->internet, tmpHostName, bits.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
	if (!ctx->connection)
	{
		dprintf("[DISPATCH] Failed InternetConnect: %d", GetLastError());
		return FALSE;
	}

	if (ctx->proxy)
	{
		if (ctx->proxy_user)
		{
			InternetSetOptionW(ctx->connection, INTERNET_OPTION_PROXY_USERNAME, ctx->proxy_user,  (DWORD)wcslen(ctx->proxy_user));
		}
		if (ctx->proxy_pass)
		{
			InternetSetOptionW(ctx->connection, INTERNET_OPTION_PROXY_PASSWORD, ctx->proxy_pass, (DWORD)wcslen(ctx->proxy_pass));
		}
	}

	dprintf("[DISPATCH] Configured hConnection: 0x%.8x", ctx->connection);

	return TRUE;
}
Пример #7
0
static int _csync_push_file(CSYNC *ctx, csync_file_stat_t *st) {
  enum csync_replica_e srep = -1;
  enum csync_replica_e drep = -1;
  enum csync_replica_e rep_bak = -1;

  char *suri = NULL;
  char *duri = NULL;
  char *turi = NULL;
  char *tdir = NULL;

  csync_vio_handle_t *sfp = NULL;
  csync_vio_handle_t *dfp = NULL;

  csync_vio_file_stat_t *tstat = NULL;

  char errbuf[256] = {0};
  char buf[MAX_XFER_BUF_SIZE] = {0};
  ssize_t bread = 0;
  ssize_t bwritten = 0;
  struct timeval times[2];

  int rc = -1;
  int count = 0;
  int flags = 0;

  rep_bak = ctx->replica;

  switch (ctx->current) {
    case LOCAL_REPLICA:
      srep = ctx->local.type;
      drep = ctx->remote.type;
      if (asprintf(&suri, "%s/%s", ctx->local.uri, st->path) < 0) {
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        rc = -1;
        goto out;
      }
      if (asprintf(&duri, "%s/%s", ctx->remote.uri, st->path) < 0) {
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        rc = -1;
        goto out;
      }
      break;
    case REMOTE_REPLICA:
      srep = ctx->remote.type;
      drep = ctx->local.type;
      if (asprintf(&suri, "%s/%s", ctx->remote.uri, st->path) < 0) {
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        rc = -1;
        goto out;
      }
      if (asprintf(&duri, "%s/%s", ctx->local.uri, st->path) < 0) {
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        rc = -1;
        goto out;
      }
      break;
    default:
      break;
  }

  /* Open the source file */
  ctx->replica = srep;
  flags = O_RDONLY|O_NOFOLLOW;
#ifdef O_NOATIME
  /* O_NOATIME can only be set by the owner of the file or the superuser */
  if (st->uid == ctx->pwd.uid || ctx->pwd.euid == 0) {
    flags |= O_NOATIME;
  }
#endif
  sfp = csync_vio_open(ctx, suri, flags, 0);
  if (sfp == NULL) {
    ctx->status_code = csync_errno_to_status(errno,
                                             CSYNC_STATUS_PROPAGATE_ERROR);
    if (errno == ENOMEM) {
      rc = -1;
    } else {
      rc = 1;
    }

    strerror_r(errno, errbuf, sizeof(errbuf));
    CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
        "file: %s, command: open(O_RDONLY), error: %s",
        suri, errbuf );

    goto out;
  }

  if (_push_to_tmp_first(ctx)) {
    /* create the temporary file name */
    if (asprintf(&turi, "%s.XXXXXX", duri) < 0) {
      ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
      rc = -1;
      goto out;
    }

    /* We just want a random file name here, open checks if the file exists. */
    if (c_tmpname(turi) < 0) {
      ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
      rc = -1;
      goto out;
    }
  } else {
    /* write to the target file directly as the HTTP server does it atomically */
    if (asprintf(&turi, "%s", duri) < 0) {
      ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
      rc = -1;
      goto out;
    }
    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,
              "Remote repository atomar push enabled for %s.", turi );
  }

  /* Create the destination file */
  ctx->replica = drep;
  while ((dfp = csync_vio_open(ctx, turi, O_CREAT|O_EXCL|O_WRONLY|O_NOCTTY,
          C_FILE_MODE)) == NULL) {
    ctx->status_code = csync_errno_to_status(errno,
                                             CSYNC_STATUS_PROPAGATE_ERROR);
    switch (errno) {
      case EEXIST:
        if (count++ > 10) {
          CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
              "file: %s, command: open(O_CREAT), error: max count exceeded",
              duri);
          ctx->status_code = CSYNC_STATUS_OPEN_ERROR;
          rc = 1;
          goto out;
        }
        if(_push_to_tmp_first(ctx)) {
          if (c_tmpname(turi) < 0) {
            ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
            rc = -1;
            goto out;
          }
        }
        break;
      case ENOENT:
        /* get the directory name */
        tdir = c_dirname(turi);
        if (tdir == NULL) {
          rc = -1;
          goto out;
        }

        if (csync_vio_mkdirs(ctx, tdir, C_DIR_MODE) < 0) {
          ctx->status_code = csync_errno_to_status(errno,
                                                   CSYNC_STATUS_PROPAGATE_ERROR);
          strerror_r(errno, errbuf, sizeof(errbuf));
          CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN,
              "dir: %s, command: mkdirs, error: %s",
              tdir, errbuf);
        }
        break;
      case ENOMEM:
        rc = -1;
        strerror_r(errno, errbuf, sizeof(errbuf));
        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
            "file: %s, command: open(O_CREAT), error: %s",
            turi, errbuf);
        goto out;
        break;
      default:
        strerror_r(errno, errbuf, sizeof(errbuf));
        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
            "file: %s, command: open(O_CREAT), error: %s",
            turi, errbuf);
        rc = 1;
        goto out;
        break;
    }

  }

  /* copy file */
  for (;;) {
    ctx->replica = srep;
    bread = csync_vio_read(ctx, sfp, buf, MAX_XFER_BUF_SIZE);

    if (bread < 0) {
      /* read error */
      ctx->status_code = csync_errno_to_status(errno,
                                               CSYNC_STATUS_PROPAGATE_ERROR);
      strerror_r(errno,  errbuf, sizeof(errbuf));
      CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
          "file: %s, command: read, error: %s",
          suri, errbuf);
      rc = 1;
      goto out;
    } else if (bread == 0) {
      /* done */
      break;
    }

    ctx->replica = drep;
    bwritten = csync_vio_write(ctx, dfp, buf, bread);

    if (bwritten < 0 || bread != bwritten) {
      ctx->status_code = csync_errno_to_status(errno,
                                               CSYNC_STATUS_PROPAGATE_ERROR);
      strerror_r(errno, errbuf, sizeof(errbuf));
      CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
          "file: %s, command: write, error: bread = %zu, bwritten = %zu - %s",
          duri,
          bread,
          bwritten,
          errbuf);
      rc = 1;
      goto out;
    }
  }

  ctx->replica = srep;
  if (csync_vio_close(ctx, sfp) < 0) {
    ctx->status_code = csync_errno_to_status(errno,
                                             CSYNC_STATUS_PROPAGATE_ERROR);
    strerror_r(errno, errbuf, sizeof(errbuf));
    CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
        "file: %s, command: close, error: %s",
        suri,
        errbuf);
  }
  sfp = NULL;

  ctx->replica = drep;
  if (csync_vio_close(ctx, dfp) < 0) {
    dfp = NULL;
    ctx->status_code = csync_errno_to_status(errno,
                                             CSYNC_STATUS_PROPAGATE_ERROR);
    switch (errno) {
      /* stop if no space left or quota exceeded */
      case ENOSPC:
      case EDQUOT:
        strerror_r(errno, errbuf, sizeof(errbuf));
        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
            "file: %s, command: close, error: %s",
            turi,
            errbuf);
        rc = -1;
        goto out;
        break;
      default:
        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
            "file: %s, command: close, error: %s",
            turi,
            strerror_r(errno, errbuf, sizeof(errbuf)));
        break;
    }
  }
  dfp = NULL;

  /*
   * Check filesize
   */
  ctx->replica = drep;
  tstat = csync_vio_file_stat_new();
  if (tstat == NULL) {
    ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
    rc = -1;
    goto out;
  }

  if (csync_vio_stat(ctx, turi, tstat) < 0) {
    ctx->status_code = csync_errno_to_status(errno,
                                             CSYNC_STATUS_PROPAGATE_ERROR);
    switch (errno) {
      case ENOMEM:
        rc = -1;
        break;
      default:
        rc = 1;
        break;
    }
    strerror_r(errno, errbuf, sizeof(errbuf));
    CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
        "file: %s, command: stat, error: %s",
        turi,
        errbuf);
    goto out;
  }

  if (st->size != tstat->size) {
    CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
        "file: %s, error: incorrect filesize (size: %jd should be %jd)",
        turi, tstat->size, st->size);
    ctx->status_code = CSYNC_STATUS_FILE_SIZE_ERROR;
    rc = 1;
    goto out;
  }

  if (_push_to_tmp_first(ctx)) {
    /* override original file */
    ctx->replica = drep;
    if (csync_vio_rename(ctx, turi, duri) < 0) {
      ctx->status_code = csync_errno_to_status(errno,
                                               CSYNC_STATUS_PROPAGATE_ERROR);
      switch (errno) {
      case ENOMEM:
        rc = -1;
        break;
      default:
        rc = 1;
        break;
      }
      strerror_r(errno, errbuf, sizeof(errbuf));
      CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
                "file: %s, command: rename, error: %s",
                duri,
                errbuf);
      goto out;
    }
  }

  /* set mode only if it is not the default mode */
  if ((st->mode & 07777) != C_FILE_MODE) {
    if (csync_vio_chmod(ctx, duri, st->mode) < 0) {
      ctx->status_code = csync_errno_to_status(errno,
                                               CSYNC_STATUS_PROPAGATE_ERROR);
      switch (errno) {
        case ENOMEM:
          rc = -1;
          break;
        default:
          rc = 1;
          break;
      }
      strerror_r(errno, errbuf, sizeof(errbuf));
      CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
          "file: %s, command: chmod, error: %s",
          duri,
          errbuf);
      goto out;
    }
  }

  /* set owner and group if possible */
  if (ctx->pwd.euid == 0) {
    csync_vio_chown(ctx, duri, st->uid, st->gid);
  }

  /* sync time */
  times[0].tv_sec = times[1].tv_sec = st->modtime;
  times[0].tv_usec = times[1].tv_usec = 0;

  ctx->replica = drep;
  csync_vio_utimes(ctx, duri, times);

  /* set instruction for the statedb merger */
  st->instruction = CSYNC_INSTRUCTION_UPDATED;

  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "PUSHED  file: %s", duri);

  rc = 0;

out:
  ctx->replica = srep;
  csync_vio_close(ctx, sfp);

  ctx->replica = drep;
  csync_vio_close(ctx, dfp);

  csync_vio_file_stat_destroy(tstat);

  /* set instruction for the statedb merger */
  if (rc != 0) {
    st->instruction = CSYNC_INSTRUCTION_ERROR;
    if (turi != NULL) {
      csync_vio_unlink(ctx, turi);
    }
  }

  SAFE_FREE(suri);
  SAFE_FREE(duri);
  SAFE_FREE(turi);
  SAFE_FREE(tdir);

  ctx->replica = rep_bak;

  return rc;
}
Пример #8
0
static bool _reg_perfcount_get_instance_info(struct PERF_INSTANCE_DEFINITION *inst,
					     TALLOC_CTX *mem_ctx,
					     int instId,
					     struct PERF_OBJECT_TYPE *obj,
					     TDB_CONTEXT *names)
{
	TDB_DATA key, data;
	char buf[PERFCOUNT_MAX_LEN], temp[PERFCOUNT_MAX_LEN];
	smb_ucs2_t *name = NULL;
	int pad;

	/* First grab the instance data from the data file */
	memset(temp, 0, PERFCOUNT_MAX_LEN);
	snprintf(temp, PERFCOUNT_MAX_LEN, "i%d", instId);
	_reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, obj->ObjectNameTitleIndex, temp);
	if (!_reg_perfcount_get_counter_data(key, &data)) {
		DEBUG(3, ("_reg_perfcount_get_counter_data failed\n"));
		return false;
	}
	if(data.dptr == NULL)
	{
		DEBUG(3, ("_reg_perfcount_get_instance_info: No instance data for instance [%s].\n",
			  buf));
		return False;
	}
	inst->counter_data.ByteLength = data.dsize + sizeof(inst->counter_data.ByteLength);
	inst->counter_data.data = TALLOC_REALLOC_ARRAY(mem_ctx,
						       inst->counter_data.data,
						       uint8,
						       data.dsize);
	if(inst->counter_data.data == NULL)
		return False;
	memset(inst->counter_data.data, 0, data.dsize);
	memcpy(inst->counter_data.data, data.dptr, data.dsize);
	SAFE_FREE(data.dptr);

	/* Fetch instance name */
	memset(temp, 0, PERFCOUNT_MAX_LEN);
	snprintf(temp, PERFCOUNT_MAX_LEN, "i%dname", instId);
	_reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, obj->ObjectNameTitleIndex, temp);
	data = tdb_fetch(names, key);
	if(data.dptr == NULL)
	{
		/* Not actually an error, but possibly unintended? -- just logging FYI */
		DEBUG(3, ("_reg_perfcount_get_instance_info: No instance name for instance [%s].\n",
			  buf));
		inst->NameLength = 0;
	}
	else
	{
		memset(buf, 0, PERFCOUNT_MAX_LEN);
		memcpy(buf, data.dptr, MIN(PERFCOUNT_MAX_LEN-1,data.dsize));
		buf[PERFCOUNT_MAX_LEN-1] = '\0';
		inst->NameLength = rpcstr_push_talloc(mem_ctx, &name, buf);
		if (inst->NameLength == (uint32_t)-1 || !name) {
			SAFE_FREE(data.dptr);
			return False;
		}
		inst->data = TALLOC_REALLOC_ARRAY(mem_ctx,
						  inst->data,
						  uint8,
						  inst->NameLength);
		if (inst->data == NULL) {
			SAFE_FREE(data.dptr);
			return False;
		}
		memcpy(inst->data, name, inst->NameLength);
		SAFE_FREE(data.dptr);
	}

	inst->ParentObjectTitleIndex = 0;
	inst->ParentObjectTitlePointer = 0;
	inst->UniqueID = PERF_NO_UNIQUE_ID;
	inst->NameOffset = 6 * sizeof(uint32);

	inst->ByteLength = inst->NameOffset + inst->NameLength;
	/* Need to be aligned on a 64-bit boundary here for counter_data */
	if((pad = (inst->ByteLength % 8)))
	{
		pad = 8 - pad;
		inst->data = TALLOC_REALLOC_ARRAY(mem_ctx,
						  inst->data,
						  uint8,
						  inst->NameLength + pad);
		memset(inst->data + inst->NameLength, 0, pad);
		inst->ByteLength += pad;
	}

	return True;
}
Пример #9
0
int c_rmdirs(const char *path) {
  _TDIR *d;
  struct _tdirent *dp;
  csync_stat_t sb;
  char *fname = NULL;
  const _TCHAR *wfname = NULL;
  const _TCHAR *wpath = c_multibyte(path);
  
  if ((d = _topendir(wpath)) != NULL) {
    while( _tstat(wpath, &sb) == 0) {
      /* if we can remove the directory we're done */
      if (_trmdir(path) == 0) {
        break;
      }
      switch (errno) {
        case ENOTEMPTY:
        case EEXIST:
        case EBADF:
          break; /* continue */
        default:
          _tclosedir(d);
          return 0;
      }

      while ((dp = _treaddir(d)) != NULL) {
        size_t len;
        /* skip '.' and '..' */
        if (dp->d_name[0] == '.' &&
            (dp->d_name[1] == '\0' ||
             (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) {
          continue;
        }

        len = strlen(path) + _tcslen(dp->d_name) + 2;
        fname = c_malloc(len);
        if (fname == NULL) {
          return -1;
        }
        snprintf(fname, len, "%s/%s", path, dp->d_name);
	wfname = c_multibyte(fname);
	
        /* stat the file */
        if (_tstat(wfname, &sb) != -1) {
#ifdef __unix__
          if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode)) {
#else
          if (S_ISDIR(sb.st_mode)) {
#endif
            if (_trmdir(wfname) < 0) { /* can't be deleted */
              if (errno == EACCES) {
                _tclosedir(d);
                SAFE_FREE(fname);
		c_free_multibyte(wfname);
                return -1;
              }
              c_rmdirs(fname);
            }
          } else {
            _tunlink(wfname);
          }
        } /* lstat */
        SAFE_FREE(fname);
	c_free_multibyte(wfname);
      } /* readdir */

      _trewinddir(d);
    }
  } else {
    return -1;
  }

  _tclosedir(d);
  return 0;
}
Пример #10
0
Lisp_Object
get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
{
  char *from, *to, *name, *p, *p1;
  int fd;
  int offset;
  EMACS_INT position;
  Lisp_Object file, tem, pos;
  ptrdiff_t count;
  USE_SAFE_ALLOCA;

  if (INTEGERP (filepos))
    {
      file = Vdoc_file_name;
      pos = filepos;
    }
  else if (CONSP (filepos))
    {
      file = XCAR (filepos);
      pos = XCDR (filepos);
    }
  else
    return Qnil;

  position = eabs (XINT (pos));

  if (!STRINGP (Vdoc_directory))
    return Qnil;

  if (!STRINGP (file))
    return Qnil;

  /* Put the file name in NAME as a C string.
     If it is relative, combine it with Vdoc_directory.  */

  tem = Ffile_name_absolute_p (file);
  file = ENCODE_FILE (file);
  Lisp_Object docdir
    = NILP (tem) ? ENCODE_FILE (Vdoc_directory) : empty_unibyte_string;
  ptrdiff_t docdir_sizemax = SBYTES (docdir) + 1;
#ifndef CANNOT_DUMP
  docdir_sizemax = max (docdir_sizemax, sizeof sibling_etc);
#endif
  name = SAFE_ALLOCA (docdir_sizemax + SBYTES (file));
  lispstpcpy (lispstpcpy (name, docdir), file);

  fd = emacs_open (name, O_RDONLY, 0);
  if (fd < 0)
    {
#ifndef CANNOT_DUMP
      if (!NILP (Vpurify_flag))
	{
	  /* Preparing to dump; DOC file is probably not installed.
	     So check in ../etc.  */
	  lispstpcpy (stpcpy (name, sibling_etc), file);

	  fd = emacs_open (name, O_RDONLY, 0);
	}
#endif
      if (fd < 0)
	{
	  SAFE_FREE ();
	  AUTO_STRING (cannot_open, "Cannot open doc string file \"");
	  AUTO_STRING (quote_nl, "\"\n");
	  return concat3 (cannot_open, file, quote_nl);
	}
    }
  count = SPECPDL_INDEX ();
  record_unwind_protect_int (close_file_unwind, fd);

  /* Seek only to beginning of disk block.  */
  /* Make sure we read at least 1024 bytes before `position'
     so we can check the leading text for consistency.  */
  offset = min (position, max (1024, position % (8 * 1024)));
  if (TYPE_MAXIMUM (off_t) < position
      || lseek (fd, position - offset, 0) < 0)
    error ("Position %"pI"d out of range in doc string file \"%s\"",
	   position, name);

  /* Read the doc string into get_doc_string_buffer.
     P points beyond the data just read.  */

  p = get_doc_string_buffer;
  while (1)
    {
      ptrdiff_t space_left = (get_doc_string_buffer_size - 1
			      - (p - get_doc_string_buffer));
      int nread;

      /* Allocate or grow the buffer if we need to.  */
      if (space_left <= 0)
	{
	  ptrdiff_t in_buffer = p - get_doc_string_buffer;
	  get_doc_string_buffer
	    = xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size,
		       16 * 1024, -1, 1);
	  p = get_doc_string_buffer + in_buffer;
	  space_left = (get_doc_string_buffer_size - 1
			- (p - get_doc_string_buffer));
	}

      /* Read a disk block at a time.
         If we read the same block last time, maybe skip this?  */
      if (space_left > 1024 * 8)
	space_left = 1024 * 8;
      nread = emacs_read (fd, p, space_left);
      if (nread < 0)
	report_file_error ("Read error on documentation file", file);
      p[nread] = 0;
      if (!nread)
	break;
      if (p == get_doc_string_buffer)
	p1 = strchr (p + offset, '\037');
      else
	p1 = strchr (p, '\037');
      if (p1)
	{
	  *p1 = 0;
	  p = p1;
	  break;
	}
      p += nread;
    }
  unbind_to (count, Qnil);
  SAFE_FREE ();

  /* Sanity checking.  */
  if (CONSP (filepos))
    {
      int test = 1;
      /* A dynamic docstring should be either at the very beginning of a "#@
	 comment" or right after a dynamic docstring delimiter (in case we
	 pack several such docstrings within the same comment).  */
      if (get_doc_string_buffer[offset - test] != '\037')
	{
	  if (get_doc_string_buffer[offset - test++] != ' ')
	    return Qnil;
	  while (get_doc_string_buffer[offset - test] >= '0'
		 && get_doc_string_buffer[offset - test] <= '9')
	    test++;
	  if (get_doc_string_buffer[offset - test++] != '@'
	      || get_doc_string_buffer[offset - test] != '#')
	    return Qnil;
	}
    }
  else
    {
      int test = 1;
      if (get_doc_string_buffer[offset - test++] != '\n')
	return Qnil;
      while (get_doc_string_buffer[offset - test] > ' ')
	test++;
      if (get_doc_string_buffer[offset - test] != '\037')
	return Qnil;
    }

  /* Scan the text and perform quoting with ^A (char code 1).
     ^A^A becomes ^A, ^A0 becomes a null char, and ^A_ becomes a ^_.  */
  from = get_doc_string_buffer + offset;
  to = get_doc_string_buffer + offset;
  while (from != p)
    {
      if (*from == 1)
	{
	  int c;

	  from++;
	  c = *from++;
	  if (c == 1)
	    *to++ = c;
	  else if (c == '0')
	    *to++ = 0;
	  else if (c == '_')
	    *to++ = 037;
	  else
	    {
	      unsigned char uc = c;
	      error ("\
Invalid data in documentation file -- %c followed by code %03o",
		     1, uc);
	    }
	}
      else
	*to++ = *from++;
    }

  /* If DEFINITION, read from this buffer
     the same way we would read bytes from a file.  */
  if (definition)
    {
      read_bytecode_pointer = (unsigned char *) get_doc_string_buffer + offset;
      return Fread (Qlambda);
    }

  if (unibyte)
    return make_unibyte_string (get_doc_string_buffer + offset,
				to - (get_doc_string_buffer + offset));
  else
    {
      /* The data determines whether the string is multibyte.  */
      ptrdiff_t nchars
	= multibyte_chars_in_text (((unsigned char *) get_doc_string_buffer
				    + offset),
				   to - (get_doc_string_buffer + offset));
      return make_string_from_bytes (get_doc_string_buffer + offset,
				     nchars,
				     to - (get_doc_string_buffer + offset));
    }
}
Пример #11
0
static bool _reg_perfcount_get_counter_info(struct PERF_DATA_BLOCK *block,
					    TALLOC_CTX *mem_ctx,
					    int CounterIndex,
					    struct PERF_OBJECT_TYPE *obj,
					    TDB_CONTEXT *names)
{
	TDB_DATA key, data;
	char buf[PERFCOUNT_MAX_LEN];
	size_t dsize, padding;
	long int data32, dbuf[2];
	int64_t data64;
	uint32 counter_size;

	obj->counters[obj->NumCounters].DefaultScale = 0;
	dbuf[0] = dbuf[1] = 0;
	padding = 0;

	_reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, CounterIndex, "type");
	data = tdb_fetch(names, key);
	if(data.dptr == NULL)
	{
		DEBUG(3, ("_reg_perfcount_get_counter_info: No type data for counter [%d].\n", CounterIndex));
		return False;
	}
	memset(buf, 0, PERFCOUNT_MAX_LEN);
	memcpy(buf, data.dptr, data.dsize);
	obj->counters[obj->NumCounters].CounterType = atoi(buf);
	DEBUG(10, ("_reg_perfcount_get_counter_info: Got type [%d] for counter [%d].\n",
		   obj->counters[obj->NumCounters].CounterType, CounterIndex));
	SAFE_FREE(data.dptr);

	/* Fetch the actual data */
	_reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, CounterIndex, "");
	_reg_perfcount_get_counter_data(key, &data);
	if(data.dptr == NULL)
	{
		DEBUG(3, ("_reg_perfcount_get_counter_info: No counter data for counter [%d].\n", CounterIndex));
		return False;
	}

	counter_size = _reg_perfcount_get_size_field(obj->counters[obj->NumCounters].CounterType);

	if(counter_size == PERF_SIZE_DWORD)
	{
		dsize = sizeof(data32);
		memset(buf, 0, PERFCOUNT_MAX_LEN);
		memcpy(buf, data.dptr, data.dsize);
		data32 = strtol(buf, NULL, 0);
		if((obj->counters[obj->NumCounters].CounterType & 0x00000F00) == PERF_TYPE_NUMBER)
			obj->counters[obj->NumCounters].DefaultScale = _reg_perfcount_compute_scale((int64_t)data32);
		else
			obj->counters[obj->NumCounters].DefaultScale = 0;
		dbuf[0] = data32;
		padding = (dsize - (obj->counter_data.ByteLength%dsize)) % dsize;
	}
	else if(counter_size == PERF_SIZE_LARGE)
	{
		dsize = sizeof(data64);
		memset(buf, 0, PERFCOUNT_MAX_LEN);
		memcpy(buf, data.dptr, data.dsize);
		data64 = atof(buf);
		if((obj->counters[obj->NumCounters].CounterType & 0x00000F00) == PERF_TYPE_NUMBER)
			obj->counters[obj->NumCounters].DefaultScale = _reg_perfcount_compute_scale(data64);
		else
			obj->counters[obj->NumCounters].DefaultScale = 0;
		memcpy((void *)dbuf, (const void *)&data64, dsize);
		padding = (dsize - (obj->counter_data.ByteLength%dsize)) % dsize;
	}
	else /* PERF_SIZE_VARIABLE_LEN */
	{
		dsize = data.dsize;
		memset(buf, 0, PERFCOUNT_MAX_LEN);
		memcpy(buf, data.dptr, data.dsize);
	}
	SAFE_FREE(data.dptr);

	obj->counter_data.ByteLength += dsize + padding;
	obj->counter_data.data = TALLOC_REALLOC_ARRAY(mem_ctx,
						      obj->counter_data.data,
						      uint8,
						      obj->counter_data.ByteLength - sizeof(uint32));
	if(obj->counter_data.data == NULL)
		return False;
	if(dbuf[0] != 0 || dbuf[1] != 0)
	{
		memcpy((void *)(obj->counter_data.data + 
				(obj->counter_data.ByteLength - (sizeof(uint32) + dsize))), 
		       (const void *)dbuf, dsize);
	}
	else
	{
		/* Handling PERF_SIZE_VARIABLE_LEN */
		memcpy((void *)(obj->counter_data.data +
				(obj->counter_data.ByteLength - (sizeof(uint32) + dsize))),
		       (const void *)buf, dsize);
	}
	obj->counters[obj->NumCounters].CounterOffset = obj->counter_data.ByteLength - dsize;
	if(obj->counters[obj->NumCounters].CounterOffset % dsize != 0)
	{
		DEBUG(3,("Improperly aligned counter [%d]\n", obj->NumCounters));
	}
	obj->counters[obj->NumCounters].CounterSize = dsize;

	return True;
}
Пример #12
0
BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const char *path,
                       struct cli_state **targetcli, pstring targetpath )
{
	CLIENT_DFS_REFERRAL *refs = NULL;
	size_t num_refs;
	uint16 consumed;
	struct cli_state *cli_ipc;
	pstring fullpath, cleanpath;
	int pathlen;
	fstring server, share;
	struct cli_state *newcli;
	pstring newpath;
	pstring newmount;
	char *ppath;
	
	SMB_STRUCT_STAT sbuf;
	uint32 attributes;
	
	if ( !rootcli || !path || !targetcli )
		return False;
		
	*targetcli = NULL;
	
	/* send a trans2_query_path_info to check for a referral */
	
	clean_path( cleanpath, 	path );
	cli_dfs_make_full_path( fullpath, rootcli->desthost, rootcli->share, cleanpath );

	/* don't bother continuing if this is not a dfs root */
	
	if ( !rootcli->dfsroot || cli_qpathinfo_basic( rootcli, cleanpath, &sbuf, &attributes ) ) {
		*targetcli = rootcli;
		pstrcpy( targetpath, path );
		return True;
	}

	/* special case where client asked for a path that does not exist */

	if ( cli_dfs_check_error(rootcli, NT_STATUS_OBJECT_NAME_NOT_FOUND) ) {
		*targetcli = rootcli;
		pstrcpy( targetpath, path );
		return True;
	}

	/* we got an error, check for DFS referral */
			
	if ( !cli_dfs_check_error(rootcli, NT_STATUS_PATH_NOT_COVERED) ) 
		return False;

	/* check for the referral */

	if ( !(cli_ipc = cli_cm_open( rootcli->desthost, "IPC$", False )) )
		return False;
	
	if ( !cli_dfs_get_referral(cli_ipc, fullpath, &refs, &num_refs, &consumed) 
		|| !num_refs )
	{
		return False;
	}
	
	/* just store the first referral for now
	   Make sure to recreate the original string including any wildcards */
	
	cli_dfs_make_full_path( fullpath, rootcli->desthost, rootcli->share, path );
	pathlen = strlen( fullpath )*2;
	consumed = MIN(pathlen, consumed );
	pstrcpy( targetpath, &fullpath[consumed/2] );

	split_dfs_path( refs[0].dfspath, server, share );
	SAFE_FREE( refs );
	
	/* open the connection to the target path */
	
	if ( (*targetcli = cli_cm_open(server, share, False)) == NULL ) {
		d_printf("Unable to follow dfs referral [//%s/%s]\n",
			server, share );
			
		return False;
	}
	
	/* parse out the consumed mount path */
	/* trim off the \server\share\ */

	fullpath[consumed/2] = '\0';
	dos_clean_name( fullpath );
	if ((ppath = strchr_m( fullpath, '\\' )) == NULL)
		return False;
	if ((ppath = strchr_m( ppath+1, '\\' )) == NULL)
		return False;
	if ((ppath = strchr_m( ppath+1, '\\' )) == NULL)
		return False;
	ppath++;
	
	pstr_sprintf( newmount, "%s\\%s", mountpt, ppath );
	cli_cm_set_mntpoint( *targetcli, newmount );

	/* check for another dfs referral, note that we are not 
	   checking for loops here */

	if ( !strequal( targetpath, "\\" ) ) {
		if ( cli_resolve_path( newmount, *targetcli, targetpath, &newcli, newpath ) ) {
			*targetcli = newcli;
			pstrcpy( targetpath, newpath );
		}
	}

	return True;
}
Пример #13
0
BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, 
                           CLIENT_DFS_REFERRAL**refs, size_t *num_refs,
			   uint16 *consumed)
{
	unsigned int data_len = 0;
	unsigned int param_len = 0;
	uint16 setup = TRANSACT2_GET_DFS_REFERRAL;
	char param[sizeof(pstring)+2];
	pstring data;
	char *rparam=NULL, *rdata=NULL;
	char *p;
	size_t pathlen = 2*(strlen(path)+1);
	uint16 num_referrals;
	CLIENT_DFS_REFERRAL *referrals = NULL;
	
	memset(param, 0, sizeof(param));
	SSVAL(param, 0, 0x03);	/* max referral level */
	p = &param[2];

	p += clistr_push(cli, p, path, MIN(pathlen, sizeof(param)-2), STR_TERMINATE);
	param_len = PTR_DIFF(p, param);

	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 */
		)) {
			return False;
	}

	if (!cli_receive_trans(cli, SMBtrans2,
		&rparam, &param_len,
		&rdata, &data_len)) {
			return False;
	}
	
	*consumed     = SVAL( rdata, 0 );
	num_referrals = SVAL( rdata, 2 );
	
	if ( num_referrals != 0 ) {
		uint16 ref_version;
		uint16 ref_size;
		int i;
		uint16 node_offset;
		
		
		referrals = SMB_XMALLOC_ARRAY( CLIENT_DFS_REFERRAL, num_referrals );
	
		/* start at the referrals array */
	
		p = rdata+8;
		for ( i=0; i<num_referrals; i++ ) {
			ref_version = SVAL( p, 0 );
			ref_size    = SVAL( p, 2 );
			node_offset = SVAL( p, 16 );
			
			if ( ref_version != 3 ) {
				p += ref_size;
				continue;
			}
			
			referrals[i].proximity = SVAL( p, 8 );
			referrals[i].ttl       = SVAL( p, 10 );

			clistr_pull( cli, referrals[i].dfspath, p+node_offset, 
				sizeof(referrals[i].dfspath), -1, STR_TERMINATE|STR_UNICODE );

			p += ref_size;
		}
	
	}
	
	*num_refs = num_referrals;
	*refs = referrals;

	SAFE_FREE(rdata);
	SAFE_FREE(rparam);

	return True;
}
Пример #14
0
unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) {
  struct ssh_cipher_struct *crypto = NULL;
  HMACCTX ctx = NULL;
  char *out = NULL;
  unsigned int finallen;
  uint32_t seq;
  enum ssh_hmac_e type;

  assert(len);

  assert(len);

  if (!session->current_crypto) {
    return NULL; /* nothing to do here */
  }
  if(len % session->current_crypto->in_cipher->blocksize != 0){
      ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len);
      return NULL;
  }
  out = malloc(len);
  if (out == NULL) {
    return NULL;
  }

  type = session->current_crypto->out_hmac;
  seq = ntohl(session->send_seq);
  crypto = session->current_crypto->out_cipher;

  if (crypto->set_encrypt_key(crypto, session->current_crypto->encryptkey,
      session->current_crypto->encryptIV) < 0) {
    SAFE_FREE(out);
    return NULL;
  }

  if (session->version == 2) {
    ctx = hmac_init(session->current_crypto->encryptMAC, hmac_digest_len(type), type);
    if (ctx == NULL) {
      SAFE_FREE(out);
      return NULL;
    }
    hmac_update(ctx,(unsigned char *)&seq,sizeof(uint32_t));
    hmac_update(ctx,data,len);
    hmac_final(ctx,session->current_crypto->hmacbuf,&finallen);
#ifdef DEBUG_CRYPTO
    ssh_print_hexa("mac: ",data,hmac_digest_len(type));
    if (finallen != hmac_digest_len(type)) {
      printf("Final len is %d\n",finallen);
    }
    ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, hmac_digest_len(type));
#endif
  }

  crypto->encrypt(crypto, data, out, len);

  memcpy(data, out, len);
  BURN_BUFFER(out, len);
  SAFE_FREE(out);

  if (session->version == 2) {
    return session->current_crypto->hmacbuf;
  }

  return NULL;
}
Пример #15
0
/**
 * @brief Free a SSH message.
 *
 * @param[in] msg       The message to release the memory.
 */
void ssh_message_free(ssh_message msg){
  if (msg == NULL) {
    return;
  }

  switch(msg->type) {
    case SSH_REQUEST_AUTH:
      SAFE_FREE(msg->auth_request.username);
      if (msg->auth_request.password) {
        memset(msg->auth_request.password, 0,
            strlen(msg->auth_request.password));
        SAFE_FREE(msg->auth_request.password);
      }
      ssh_key_free(msg->auth_request.pubkey);
      break;
    case SSH_REQUEST_CHANNEL_OPEN:
      SAFE_FREE(msg->channel_request_open.originator);
      SAFE_FREE(msg->channel_request_open.destination);
      break;
    case SSH_REQUEST_CHANNEL:
      SAFE_FREE(msg->channel_request.TERM);
      SAFE_FREE(msg->channel_request.modes);
      SAFE_FREE(msg->channel_request.var_name);
      SAFE_FREE(msg->channel_request.var_value);
      SAFE_FREE(msg->channel_request.command);
      SAFE_FREE(msg->channel_request.subsystem);
      break;
    case SSH_REQUEST_SERVICE:
      SAFE_FREE(msg->service_request.service);
      break;
    case SSH_REQUEST_GLOBAL:
      SAFE_FREE(msg->global_request.bind_address);
      break;
  }
  ZERO_STRUCTP(msg);
  SAFE_FREE(msg);
}
Пример #16
0
WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
			  const struct auth_session_info *session_info,
			  struct messaging_context *msg_ctx,
			  struct spoolss_PrinterInfo2 *pinfo2,
			  int action)
{
	uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ATTRIBUTES;
	struct spoolss_SetPrinterInfo2 *sinfo2;
	ADS_STATUS ads_rc;
	ADS_STRUCT *ads = NULL;
	WERROR win_rc;

	sinfo2 = talloc_zero(mem_ctx, struct spoolss_SetPrinterInfo2);
	if (!sinfo2) {
		return WERR_NOMEM;
	}

	switch (action) {
	case DSPRINT_PUBLISH:
	case DSPRINT_UPDATE:
		pinfo2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
		break;
	case DSPRINT_UNPUBLISH:
		pinfo2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
		break;
	default:
		win_rc = WERR_NOT_SUPPORTED;
		goto done;
	}

	sinfo2->attributes = pinfo2->attributes;

	win_rc = winreg_update_printer_internal(mem_ctx, session_info, msg_ctx,
					pinfo2->sharename, info2_mask,
					sinfo2, NULL, NULL);
	if (!W_ERROR_IS_OK(win_rc)) {
		DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc)));
		goto done;
	}

	TALLOC_FREE(sinfo2);

	ads = ads_init(lp_realm(), lp_workgroup(), NULL);
	if (!ads) {
		DEBUG(3, ("ads_init() failed\n"));
		win_rc = WERR_SERVER_UNAVAILABLE;
		goto done;
	}
	setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
	SAFE_FREE(ads->auth.password);
	ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
		NULL, NULL);

	/* ads_connect() will find the DC for us */
	ads_rc = ads_connect(ads);
	if (!ADS_ERR_OK(ads_rc)) {
		DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
		win_rc = WERR_ACCESS_DENIED;
		goto done;
	}

	switch (action) {
	case DSPRINT_PUBLISH:
	case DSPRINT_UPDATE:
		win_rc = nt_printer_publish_ads(msg_ctx, ads, pinfo2);
		break;
	case DSPRINT_UNPUBLISH:
		win_rc = nt_printer_unpublish_ads(ads, pinfo2->sharename);
		break;
	}

done:
	ads_destroy(&ads);
	return win_rc;
}
static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx,
				 const char *tdb_path,
				 struct rpc_pipe_client *winreg_pipe)
{
	const char *backup_suffix = ".bak";
	TDB_DATA kbuf, newkey, dbuf;
	TDB_CONTEXT *tdb;
	NTSTATUS status;
	int rc;

	tdb = tdb_open_log(tdb_path, 0, TDB_DEFAULT, O_RDONLY, 0600);
	if (tdb == NULL && errno == ENOENT) {
		/* if we have no printers database then migration is
		   considered successful */
		DEBUG(4, ("No printers database to migrate in %s\n", tdb_path));
		return NT_STATUS_OK;
	}
	if (tdb == NULL) {
		DEBUG(2, ("Failed to open tdb file: %s\n", tdb_path));
		return NT_STATUS_NO_SUCH_FILE;
	}

	for (kbuf = tdb_firstkey(tdb);
	     kbuf.dptr;
	     newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
	{
		dbuf = tdb_fetch(tdb, kbuf);
		if (!dbuf.dptr) {
			continue;
		}

		if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
			status = printing_tdb_migrate_form(mem_ctx,
					      winreg_pipe,
					      (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
					      dbuf.dptr,
					      dbuf.dsize);
			SAFE_FREE(dbuf.dptr);
			if (!NT_STATUS_IS_OK(status)) {
				tdb_close(tdb);
				return status;
			}
			continue;
		}

		if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
			status = printing_tdb_migrate_driver(mem_ctx,
						winreg_pipe,
						(const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
						dbuf.dptr,
						dbuf.dsize,
						false);
			SAFE_FREE(dbuf.dptr);
			if (!NT_STATUS_IS_OK(status)) {
				tdb_close(tdb);
				return status;
			}
			continue;
		}

		if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
			const char *printer_name = (const char *)(kbuf.dptr
						    + strlen(PRINTERS_PREFIX));
			status = printing_tdb_migrate_printer(mem_ctx,
						 winreg_pipe,
						 printer_name,
						 dbuf.dptr,
						 dbuf.dsize,
						 false);
			SAFE_FREE(dbuf.dptr);
			if (!NT_STATUS_IS_OK(status)) {
				tdb_close(tdb);
				return status;
			}
			continue;
		}
		SAFE_FREE(dbuf.dptr);
	}

	for (kbuf = tdb_firstkey(tdb);
	     kbuf.dptr;
	     newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
	{
		dbuf = tdb_fetch(tdb, kbuf);
		if (!dbuf.dptr) {
			continue;
		}

		if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
			const char *secdesc_name = (const char *)(kbuf.dptr
						    + strlen(SECDESC_PREFIX));
			status = printing_tdb_migrate_secdesc(mem_ctx,
						 winreg_pipe,
						 secdesc_name,
						 dbuf.dptr,
						 dbuf.dsize);
			SAFE_FREE(dbuf.dptr);
			if (NT_STATUS_EQUAL(status, werror_to_ntstatus(WERR_FILE_NOT_FOUND))) {
				DEBUG(2, ("Skipping secdesc migration for non-existent "
						"printer: %s\n", secdesc_name));
			} else if (!NT_STATUS_IS_OK(status)) {
				tdb_close(tdb);
				return status;
			}
			continue;
		}
		SAFE_FREE(dbuf.dptr);
	}

	tdb_close(tdb);

	rc = rename_file_with_suffix(mem_ctx, tdb_path, backup_suffix);
	if (rc != 0) {
		DEBUG(0, ("Error moving tdb to '%s%s'\n",
			  tdb_path, backup_suffix));
	}

	return NT_STATUS_OK;
}
Пример #18
0
WERROR check_published_printers(struct messaging_context *msg_ctx)
{
	ADS_STATUS ads_rc;
	ADS_STRUCT *ads = NULL;
	int snum;
	int n_services = lp_numservices();
	TALLOC_CTX *tmp_ctx = NULL;
	struct auth_session_info *session_info = NULL;
	struct spoolss_PrinterInfo2 *pinfo2;
	NTSTATUS status;
	WERROR result;

	tmp_ctx = talloc_new(NULL);
	if (!tmp_ctx) return WERR_NOMEM;

	ads = ads_init(lp_realm(), lp_workgroup(), NULL);
	if (!ads) {
		DEBUG(3, ("ads_init() failed\n"));
		return WERR_SERVER_UNAVAILABLE;
	}
	setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
	SAFE_FREE(ads->auth.password);
	ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
		NULL, NULL);

	/* ads_connect() will find the DC for us */
	ads_rc = ads_connect(ads);
	if (!ADS_ERR_OK(ads_rc)) {
		DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
		result = WERR_ACCESS_DENIED;
		goto done;
	}

	status = make_session_info_system(tmp_ctx, &session_info);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("check_published_printers: "
			  "Could not create system session_info\n"));
		result = WERR_ACCESS_DENIED;
		goto done;
	}

	for (snum = 0; snum < n_services; snum++) {
		if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
			continue;
		}

		result = winreg_get_printer_internal(tmp_ctx, session_info, msg_ctx,
					    lp_servicename(snum),
					    &pinfo2);
		if (!W_ERROR_IS_OK(result)) {
			continue;
		}

		if (pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
			nt_printer_publish_ads(msg_ctx, ads, pinfo2);
		}

		TALLOC_FREE(pinfo2);
	}

	result = WERR_OK;
done:
	ads_destroy(&ads);
	ads_kdestroy("MEMORY:prtpub_cache");
	talloc_free(tmp_ctx);
	return result;
}
Пример #19
0
static int _csync_backup_file(CSYNC *ctx, csync_file_stat_t *st, char **duri) {
  enum csync_replica_e drep = -1;
  enum csync_replica_e rep_bak = -1;

  char *suri = NULL;

  char errbuf[256] = {0};

  int rc = -1;

  rep_bak = ctx->replica;
  
  if(st->instruction==CSYNC_INSTRUCTION_CONFLICT)
  {
    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,"CSYNC_INSTRUCTION_CONFLICT");
    switch (ctx->current) {
    case LOCAL_REPLICA:
      drep = ctx->remote.type;
      if (asprintf(&suri, "%s/%s", ctx->remote.uri, st->path) < 0) {
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        rc = -1;
        goto out;
      }

      if (_backup_path(duri, ctx->remote.uri,st->path) < 0) {
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        rc = -1;
        goto out;
      }
      break;
    case REMOTE_REPLICA:
      drep = ctx->local.type;
      if (asprintf(&suri, "%s/%s", ctx->local.uri, st->path) < 0) {
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        rc = -1;
        goto out;
      }

      if ( _backup_path(duri, ctx->local.uri, st->path) < 0) {
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        rc = -1;
        goto out;
      }
      break;
    default:
      break;
    }
  }

  else
  {
      CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,"instruction not allowed: %i %s",
                st->instruction, csync_instruction_str(st->instruction));
      ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
      rc = -1;
      goto out;
  }
	
	CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,"suri: %s",suri);
    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,"duri: %s",*duri);


  /* rename the older file to conflict */
  ctx->replica = drep;
  if (csync_vio_rename(ctx, suri, *duri) < 0) {
    ctx->status_code = csync_errno_to_status(errno,
                                             CSYNC_STATUS_PROPAGATE_ERROR);
    switch (errno) {
      case ENOMEM:
        rc = -1;
        break;
      default:
        rc = 1;
        break;
    }
    strerror_r(errno, errbuf, sizeof(errbuf));
    CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
        "file: %s, command: rename, error: %s",
        *duri,
        errbuf);
    goto out;
  }


  /* set instruction for the statedb merger */
  st->instruction = CSYNC_INSTRUCTION_NONE;
 
  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "BACKUP  file: %s", *duri);

  rc = 0;

out:
  /* set instruction for the statedb merger */
  if (rc != 0) {
    st->instruction = CSYNC_INSTRUCTION_ERROR;
  }

  SAFE_FREE(suri);
 
  ctx->replica = rep_bak;

  return rc;
}
Пример #20
0
static WERROR nt_printer_publish_ads(struct messaging_context *msg_ctx,
				     ADS_STRUCT *ads,
				     struct spoolss_PrinterInfo2 *pinfo2)
{
	ADS_STATUS ads_rc;
	LDAPMessage *res;
	char *prt_dn = NULL, *srv_dn, *srv_cn_0, *srv_cn_escaped, *sharename_escaped;
	char *srv_dn_utf8, **srv_cn_utf8;
	TALLOC_CTX *ctx;
	ADS_MODLIST mods;
	const char *attrs[] = {"objectGUID", NULL};
	struct GUID guid;
	WERROR win_rc = WERR_OK;
	size_t converted_size;
	const char *printer = pinfo2->sharename;

	/* build the ads mods */
	ctx = talloc_init("nt_printer_publish_ads");
	if (ctx == NULL) {
		return WERR_NOMEM;
	}

	DEBUG(5, ("publishing printer %s\n", printer));

	/* figure out where to publish */
	ads_find_machine_acct(ads, &res, lp_netbios_name());

	/* We use ldap_get_dn here as we need the answer
	 * in utf8 to call ldap_explode_dn(). JRA. */

	srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
	if (!srv_dn_utf8) {
		TALLOC_FREE(ctx);
		return WERR_SERVER_UNAVAILABLE;
	}
	ads_msgfree(ads, res);
	srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
	if (!srv_cn_utf8) {
		TALLOC_FREE(ctx);
		ldap_memfree(srv_dn_utf8);
		return WERR_SERVER_UNAVAILABLE;
	}
	/* Now convert to CH_UNIX. */
	if (!pull_utf8_talloc(ctx, &srv_dn, srv_dn_utf8, &converted_size)) {
		TALLOC_FREE(ctx);
		ldap_memfree(srv_dn_utf8);
		ldap_memfree(srv_cn_utf8);
		return WERR_SERVER_UNAVAILABLE;
	}
	if (!pull_utf8_talloc(ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size)) {
		TALLOC_FREE(ctx);
		ldap_memfree(srv_dn_utf8);
		ldap_memfree(srv_cn_utf8);
		TALLOC_FREE(srv_dn);
		return WERR_SERVER_UNAVAILABLE;
	}

	ldap_memfree(srv_dn_utf8);
	ldap_memfree(srv_cn_utf8);

	srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
	if (!srv_cn_escaped) {
		TALLOC_FREE(ctx);
		return WERR_SERVER_UNAVAILABLE;
	}
	sharename_escaped = escape_rdn_val_string_alloc(printer);
	if (!sharename_escaped) {
		SAFE_FREE(srv_cn_escaped);
		TALLOC_FREE(ctx);
		return WERR_SERVER_UNAVAILABLE;
	}

	prt_dn = talloc_asprintf(ctx, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);

	SAFE_FREE(srv_cn_escaped);
	SAFE_FREE(sharename_escaped);

	mods = ads_init_mods(ctx);

	if (mods == NULL) {
		SAFE_FREE(prt_dn);
		TALLOC_FREE(ctx);
		return WERR_NOMEM;
	}

	ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, printer);

	/* publish it */
	ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
	if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) {
		int i;
		for (i=0; mods[i] != 0; i++)
			;
		mods[i] = (LDAPMod *)-1;
		ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
	}

	if (!ADS_ERR_OK(ads_rc)) {
		DEBUG(3, ("error publishing %s: %s\n",
			  printer, ads_errstr(ads_rc)));
	}

	/* retreive the guid and store it locally */
	if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
		bool guid_ok;
		ZERO_STRUCT(guid);
		guid_ok = ads_pull_guid(ads, res, &guid);
		ads_msgfree(ads, res);
		if (guid_ok) {
			store_printer_guid(msg_ctx, printer, guid);
		}
	}
	TALLOC_FREE(ctx);

	return win_rc;
}
Пример #21
0
static int _csync_sync_dir(CSYNC *ctx, csync_file_stat_t *st) {
  enum csync_replica_e dest = -1;
  enum csync_replica_e replica_bak;
  char errbuf[256] = {0};
  char *uri = NULL;
  struct timeval times[2];
  int rc = -1;

  replica_bak = ctx->replica;

  switch (ctx->current) {
    case LOCAL_REPLICA:
      dest = ctx->remote.type;
      if (asprintf(&uri, "%s/%s", ctx->remote.uri, st->path) < 0) {
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        return -1;
      }
      break;
    case REMOTE_REPLICA:
      dest = ctx->local.type;
      if (asprintf(&uri, "%s/%s", ctx->local.uri, st->path) < 0) {
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        return -1;
      }
      break;
    default:
      break;
  }

  ctx->replica = dest;

  /* chmod is if it is not the default mode */
  if ((st->mode & 07777) != C_DIR_MODE) {
    if (csync_vio_chmod(ctx, uri, st->mode) < 0) {
      ctx->status_code = csync_errno_to_status(errno,
                                               CSYNC_STATUS_PROPAGATE_ERROR);
      switch (errno) {
        case ENOMEM:
          rc = -1;
          break;
        default:
          rc = 1;
          break;
      }
      strerror_r(errno, errbuf, sizeof(errbuf));
      CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
          "dir: %s, command: chmod, error: %s",
          uri,
          errbuf);
      goto out;
    }
  }

  /* set owner and group if possible */
  if (ctx->pwd.euid == 0) {
    csync_vio_chown(ctx, uri, st->uid, st->gid);
  }

  times[0].tv_sec = times[1].tv_sec = st->modtime;
  times[0].tv_usec = times[1].tv_usec = 0;

  csync_vio_utimes(ctx, uri, times);

  /* set instruction for the statedb merger */
  st->instruction = CSYNC_INSTRUCTION_UPDATED;

  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "SYNCED   dir: %s", uri);
  ctx->replica = replica_bak;

  rc = 0;
out:
  SAFE_FREE(uri);

  /* set instruction for the statedb merger */
  if (rc != 0) {
    st->instruction = CSYNC_INSTRUCTION_ERROR;
  }

  return rc;
}
Пример #22
0
static SMBCSRV *
SMBC_server_internal(TALLOC_CTX *ctx,
            SMBCCTX *context,
            bool connect_if_not_found,
            const char *server,
            const char *share,
            char **pp_workgroup,
            char **pp_username,
            char **pp_password,
	    bool *in_cache)
{
	SMBCSRV *srv=NULL;
	char *workgroup = NULL;
	struct cli_state *c = NULL;
	const char *server_n = server;
        int is_ipc = (share != NULL && strcmp(share, "IPC$") == 0);
	uint32 fs_attrs = 0;
        const char *username_used;
 	NTSTATUS status;
	char *newserver, *newshare;
	int flags = 0;

	ZERO_STRUCT(c);
	*in_cache = false;

	if (server[0] == 0) {
		errno = EPERM;
		return NULL;
	}

        /* Look for a cached connection */
        srv = SMBC_find_server(ctx, context, server, share,
                               pp_workgroup, pp_username, pp_password);

        /*
         * If we found a connection and we're only allowed one share per
         * server...
         */
        if (srv &&
            *share != '\0' &&
            smbc_getOptionOneSharePerServer(context)) {

                /*
                 * ... then if there's no current connection to the share,
                 * connect to it.  SMBC_find_server(), or rather the function
                 * pointed to by context->get_cached_srv_fn which
                 * was called by SMBC_find_server(), will have issued a tree
                 * disconnect if the requested share is not the same as the
                 * one that was already connected.
                 */

		/*
		 * Use srv->cli->desthost and srv->cli->share instead of
		 * server and share below to connect to the actual share,
		 * i.e., a normal share or a referred share from
		 * 'msdfs proxy' share.
		 */
                if (!cli_state_has_tcon(srv->cli)) {
                        /* Ensure we have accurate auth info */
			SMBC_call_auth_fn(ctx, context,
					  smbXcli_conn_remote_name(srv->cli->conn),
					  srv->cli->share,
                                          pp_workgroup,
                                          pp_username,
                                          pp_password);

			if (!*pp_workgroup || !*pp_username || !*pp_password) {
				errno = ENOMEM;
				cli_shutdown(srv->cli);
				srv->cli = NULL;
				smbc_getFunctionRemoveCachedServer(context)(context,
                                                                            srv);
				return NULL;
			}

			/*
			 * We don't need to renegotiate encryption
			 * here as the encryption context is not per
			 * tid.
			 */

			status = cli_tree_connect(srv->cli,
						  srv->cli->share,
						  "?????",
						  *pp_password,
						  strlen(*pp_password)+1);
			if (!NT_STATUS_IS_OK(status)) {
                                errno = map_errno_from_nt_status(status);
                                cli_shutdown(srv->cli);
				srv->cli = NULL;
                                smbc_getFunctionRemoveCachedServer(context)(context,
                                                                            srv);
                                srv = NULL;
                        }

                        /* Determine if this share supports case sensitivity */
                        if (is_ipc) {
                                DEBUG(4,
                                      ("IPC$ so ignore case sensitivity\n"));
                                status = NT_STATUS_OK;
                        } else {
                                status = cli_get_fs_attr_info(c, &fs_attrs);
                        }

                        if (!NT_STATUS_IS_OK(status)) {
                                DEBUG(4, ("Could not retrieve "
                                          "case sensitivity flag: %s.\n",
                                          nt_errstr(status)));

                                /*
                                 * We can't determine the case sensitivity of
                                 * the share. We have no choice but to use the
                                 * user-specified case sensitivity setting.
                                 */
                                if (smbc_getOptionCaseSensitive(context)) {
                                        cli_set_case_sensitive(c, True);
                                } else {
                                        cli_set_case_sensitive(c, False);
                                }
                        } else if (!is_ipc) {
                                DEBUG(4,
                                      ("Case sensitive: %s\n",
                                       (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
                                        ? "True"
                                        : "False")));
                                cli_set_case_sensitive(
                                        c,
                                        (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
                                         ? True
                                         : False));
                        }

                        /*
                         * Regenerate the dev value since it's based on both
                         * server and share
                         */
                        if (srv) {
				const char *remote_name =
					smbXcli_conn_remote_name(srv->cli->conn);

				srv->dev = (dev_t)(str_checksum(remote_name) ^
                                                   str_checksum(srv->cli->share));
                        }
                }
        }

        /* If we have a connection... */
        if (srv) {

                /* ... then we're done here.  Give 'em what they came for. */
		*in_cache = true;
                goto done;
        }

        /* If we're not asked to connect when a connection doesn't exist... */
        if (! connect_if_not_found) {
                /* ... then we're done here. */
                return NULL;
        }

	if (!*pp_workgroup || !*pp_username || !*pp_password) {
		errno = ENOMEM;
		return NULL;
	}

	DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server));

	DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));

	status = NT_STATUS_UNSUCCESSFUL;

	if (smbc_getOptionUseKerberos(context)) {
		flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
	}

	if (smbc_getOptionFallbackAfterKerberos(context)) {
		flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
	}

	if (smbc_getOptionUseCCache(context)) {
		flags |= CLI_FULL_CONNECTION_USE_CCACHE;
	}

	if (smbc_getOptionUseNTHash(context)) {
		flags |= CLI_FULL_CONNECTION_USE_NT_HASH;
	}

        if (share == NULL || *share == '\0' || is_ipc) {
		/*
		 * Try 139 first for IPC$
		 */
		status = cli_connect_nb(server_n, NULL, NBT_SMB_PORT, 0x20,
					smbc_getNetbiosName(context),
					SMB_SIGNING_DEFAULT, flags, &c);
	}

	if (!NT_STATUS_IS_OK(status)) {
		/*
		 * No IPC$ or 139 did not work
		 */
		status = cli_connect_nb(server_n, NULL, 0, 0x20,
					smbc_getNetbiosName(context),
					SMB_SIGNING_DEFAULT, flags, &c);
	}

	if (!NT_STATUS_IS_OK(status)) {
		errno = map_errno_from_nt_status(status);
		return NULL;
	}

	cli_set_timeout(c, smbc_getTimeout(context));

	status = smbXcli_negprot(c->conn, c->timeout, PROTOCOL_CORE,
				 PROTOCOL_NT1);

	if (!NT_STATUS_IS_OK(status)) {
		cli_shutdown(c);
		errno = ETIMEDOUT;
		return NULL;
	}

        username_used = *pp_username;

	if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
					       *pp_password,
                                               strlen(*pp_password),
					       *pp_password,
                                               strlen(*pp_password),
					       *pp_workgroup))) {

                /* Failed.  Try an anonymous login, if allowed by flags. */
                username_used = "";

                if (smbc_getOptionNoAutoAnonymousLogin(context) ||
                    !NT_STATUS_IS_OK(cli_session_setup(c, username_used,
                                                       *pp_password, 1,
                                                       *pp_password, 0,
                                                       *pp_workgroup))) {

                        cli_shutdown(c);
                        errno = EPERM;
                        return NULL;
                }
	}

	status = cli_init_creds(c, username_used,
				*pp_workgroup, *pp_password);
	if (!NT_STATUS_IS_OK(status)) {
		errno = map_errno_from_nt_status(status);
		cli_shutdown(c);
		return NULL;
	}

	DEBUG(4,(" session setup ok\n"));

	/* here's the fun part....to support 'msdfs proxy' shares
	   (on Samba or windows) we have to issues a TRANS_GET_DFS_REFERRAL
	   here before trying to connect to the original share.
	   cli_check_msdfs_proxy() will fail if it is a normal share. */

	if ((smb1cli_conn_capabilities(c->conn) & CAP_DFS) &&
			cli_check_msdfs_proxy(ctx, c, share,
				&newserver, &newshare,
				/* FIXME: cli_check_msdfs_proxy() does
				   not support smbc_smb_encrypt_level type */
				context->internal->smb_encryption_level ?
					true : false,
				*pp_username,
				*pp_password,
				*pp_workgroup)) {
		cli_shutdown(c);
		srv = SMBC_server_internal(ctx, context, connect_if_not_found,
				newserver, newshare, pp_workgroup,
				pp_username, pp_password, in_cache);
		TALLOC_FREE(newserver);
		TALLOC_FREE(newshare);
		return srv;
	}

	/* must be a normal share */

	status = cli_tree_connect(c, share, "?????", *pp_password,
				  strlen(*pp_password)+1);
	if (!NT_STATUS_IS_OK(status)) {
		errno = map_errno_from_nt_status(status);
		cli_shutdown(c);
		return NULL;
	}

	DEBUG(4,(" tconx ok\n"));

        /* Determine if this share supports case sensitivity */
	if (is_ipc) {
                DEBUG(4, ("IPC$ so ignore case sensitivity\n"));
                status = NT_STATUS_OK;
        } else {
                status = cli_get_fs_attr_info(c, &fs_attrs);
        }

        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(4, ("Could not retrieve case sensitivity flag: %s.\n",
                          nt_errstr(status)));

                /*
                 * We can't determine the case sensitivity of the share. We
                 * have no choice but to use the user-specified case
                 * sensitivity setting.
                 */
                if (smbc_getOptionCaseSensitive(context)) {
                        cli_set_case_sensitive(c, True);
                } else {
                        cli_set_case_sensitive(c, False);
                }
	} else if (!is_ipc) {
                DEBUG(4, ("Case sensitive: %s\n",
                          (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
                           ? "True"
                           : "False")));
                cli_set_case_sensitive(c,
                                       (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
                                        ? True
                                        : False));
        }

	if (context->internal->smb_encryption_level) {
		/* Attempt UNIX smb encryption. */
		if (!NT_STATUS_IS_OK(cli_force_encryption(c,
                                                          username_used,
                                                          *pp_password,
                                                          *pp_workgroup))) {

			/*
			 * context->smb_encryption_level == 1
			 * means don't fail if encryption can't be negotiated,
			 * == 2 means fail if encryption can't be negotiated.
			 */

			DEBUG(4,(" SMB encrypt failed\n"));

			if (context->internal->smb_encryption_level == 2) {
	                        cli_shutdown(c);
				errno = EPERM;
				return NULL;
			}
		}
		DEBUG(4,(" SMB encrypt ok\n"));
	}

	/*
	 * Ok, we have got a nice connection
	 * Let's allocate a server structure.
	 */

	srv = SMB_MALLOC_P(SMBCSRV);
	if (!srv) {
		cli_shutdown(c);
		errno = ENOMEM;
		return NULL;
	}

	ZERO_STRUCTP(srv);
	srv->cli = c;
	srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
        srv->no_pathinfo = False;
        srv->no_pathinfo2 = False;
        srv->no_nt_session = False;

done:
	if (!pp_workgroup || !*pp_workgroup || !**pp_workgroup) {
		workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context));
	} else {
		workgroup = *pp_workgroup;
	}
	if(!workgroup) {
		if (c != NULL) {
			cli_shutdown(c);
		}
		SAFE_FREE(srv);
		return NULL;
	}

	/* set the credentials to make DFS work */
	smbc_set_credentials_with_fallback(context,
					   workgroup,
				    	   *pp_username,
				   	   *pp_password);

	return srv;
}
Пример #23
0
NTSTATUS file_new(connection_struct *conn, files_struct **result)
{
    int i;
    static int first_file;
    files_struct *fsp;

    /* we want to give out file handles differently on each new
       connection because of a common bug in MS clients where they try to
       reuse a file descriptor from an earlier smb connection. This code
       increases the chance that the errant client will get an error rather
       than causing corruption */
    if (first_file == 0) {
        first_file = (sys_getpid() ^ (int)time(NULL)) % real_max_open_files;
    }

    /* TODO: Port the id-tree implementation from Samba4 */

    i = bitmap_find(file_bmap, first_file);
    if (i == -1) {
        DEBUG(0,("ERROR! Out of file structures\n"));
        /* TODO: We have to unconditionally return a DOS error here,
         * W2k3 even returns ERRDOS/ERRnofids for ntcreate&x with
         * NTSTATUS negotiated */
        return NT_STATUS_TOO_MANY_OPENED_FILES;
    }

    fsp = SMB_MALLOC_P(files_struct);
    if (!fsp) {
        return NT_STATUS_NO_MEMORY;
    }

    ZERO_STRUCTP(fsp);

    fsp->fh = SMB_MALLOC_P(struct fd_handle);
    if (!fsp->fh) {
        SAFE_FREE(fsp);
        return NT_STATUS_NO_MEMORY;
    }

    ZERO_STRUCTP(fsp->fh);

    fsp->fh->ref_count = 1;
    fsp->fh->fd = -1;

    fsp->conn = conn;
    fsp->fh->gen_id = get_gen_count();
    GetTimeOfDay(&fsp->open_time);

    first_file = (i+1) % real_max_open_files;

    bitmap_set(file_bmap, i);
    files_used++;

    fsp->fnum = i + FILE_HANDLE_OFFSET;
    SMB_ASSERT(fsp->fnum < 65536);

    string_set(&fsp->fsp_name,"");

    DLIST_ADD(Files, fsp);

    DEBUG(5,("allocated file structure %d, fnum = %d (%d used)\n",
             i, fsp->fnum, files_used));

    chain_fsp = fsp;

    /* A new fsp invalidates the positive and
      negative fsp_fi_cache as the new fsp is pushed
      at the start of the list and we search from
      a cache hit to the *end* of the list. */

    ZERO_STRUCT(fsp_fi_cache);

    conn->num_files_open++;

    *result = fsp;
    return NT_STATUS_OK;
}
Пример #24
0
void AudioOutDriver::Close() {
     driver_->Close() ;
	SAFE_FREE(primarySoundBuffer_) ;
	SAFE_FREE(mixBuffer_) ;     
}
Пример #25
0
static void bluetooth_test_destroy(TestCase* thiz)
{
	SAFE_FREE(thiz);
}
Пример #26
0
static bool do_winbind_offline(struct messaging_context *msg_ctx,
			       const struct server_id pid,
			     const int argc, const char **argv)
{
	TDB_CONTEXT *tdb;
	bool ret = False;
	int retry = 0;

	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol winbindd offline\n");
		return False;
	}

	/* Create an entry in the winbindd_cache tdb to tell a later
	   starting winbindd that we're offline. We may actually create
	   it here... */

	tdb = tdb_open_log(cache_path("winbindd_cache.tdb"),
				WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
				TDB_DEFAULT /* TDB_CLEAR_IF_FIRST */, O_RDWR|O_CREAT, 0600);

	if (!tdb) {
		fprintf(stderr, "Cannot open the tdb %s for writing.\n",
			cache_path("winbindd_cache.tdb"));
		return False;
	}

	/* There's a potential race condition that if a child
	   winbindd detects a domain is online at the same time
	   we're trying to tell it to go offline that it might 
	   delete the record we add between us adding it and
	   sending the message. Minimize this by retrying up to
	   5 times. */

	for (retry = 0; retry < 5; retry++) {
		TDB_DATA d;
		uint8 buf[4];

		ZERO_STRUCT(d);

		SIVAL(buf, 0, time(NULL));
		d.dptr = buf;
		d.dsize = 4;

		tdb_store_bystring(tdb, "WINBINDD_OFFLINE", d, TDB_INSERT);

		ret = send_message(msg_ctx, pid, MSG_WINBIND_OFFLINE,
				   NULL, 0);

		/* Check that the entry "WINBINDD_OFFLINE" still exists. */
		d = tdb_fetch_bystring( tdb, "WINBINDD_OFFLINE" );
	
		if (!d.dptr || d.dsize != 4) {
			SAFE_FREE(d.dptr);
			DEBUG(10,("do_winbind_offline: offline state not set - retrying.\n"));
		} else {
			SAFE_FREE(d.dptr);
			break;
		}
	}

	tdb_close(tdb);
	return ret;
}
Пример #27
0
INT_PTR CALLBACK DlgProcIcoLibOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	struct IcoLibOptsData *dat;
	static HTREEITEM prevItem = 0;
	static HWND hPreview = NULL;

	dat = (struct IcoLibOptsData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
	switch (msg) {
	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);
		hPreview = GetDlgItem(hwndDlg, IDC_PREVIEW);
		dat = (struct IcoLibOptsData*)mir_alloc(sizeof(struct IcoLibOptsData));
		dat->hwndIndex = NULL;
		SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
		//
		//  Reset temporary data & upload sections list
		//
		{
			mir_cslock lck(csIconList);

			for (int indx = 0; indx < iconList.getCount(); indx++) {
				iconList[indx]->temp_file = NULL;
				iconList[indx]->temp_icon = NULL;
				iconList[indx]->temp_reset = FALSE;
			}
			bNeedRebuild = FALSE;
		}

		//
		//  Setup preview listview
		//
		ListView_SetUnicodeFormat(hPreview, TRUE);
		ListView_SetExtendedListViewStyleEx(hPreview, LVS_EX_INFOTIP, LVS_EX_INFOTIP);
		ListView_SetImageList(hPreview, ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32|ILC_MASK, 0, 30), LVSIL_NORMAL);
		ListView_SetIconSpacing(hPreview, 56, 67);

		SendMessage(hwndDlg, DM_REBUILD_CTREE, 0, 0);
		return TRUE;

	case DM_REBUILD_CTREE:
		{
			HWND hwndTree = GetDlgItem(hwndDlg, IDC_CATEGORYLIST);
			int indx;
			TCHAR itemName[1024];
			HTREEITEM hSection;

			if (!hwndTree) break;

			TreeView_SelectItem(hwndTree, NULL);
			TreeView_DeleteAllItems(hwndTree);

			for (indx = 0; indx < sectionList.getCount(); indx++) {
				TCHAR* sectionName;
				int sectionLevel = 0;

				hSection = NULL;
				mir_tstrcpy(itemName, sectionList[indx]->name);
				sectionName = itemName;

				while (sectionName) {
					// allow multi-level tree
					TCHAR* pItemName = sectionName;
					HTREEITEM hItem;

					if (sectionName = _tcschr(sectionName, '/')) {
						// one level deeper
						*sectionName = 0;
					}

					pItemName = TranslateTS(pItemName);
					hItem = FindNamedTreeItemAt(hwndTree, hSection, pItemName);
					if (!sectionName || !hItem) {
						if (!hItem) {
							TVINSERTSTRUCT tvis = {0};
							TreeItem *treeItem = (TreeItem *)mir_alloc(sizeof(TreeItem));
							treeItem->value = SECTIONPARAM_MAKE(indx, sectionLevel, sectionName ? 0 : SECTIONPARAM_HAVEPAGE);
							treeItem->paramName = mir_t2a(itemName);

							tvis.hParent = hSection;
							tvis.hInsertAfter = TVI_SORT;
							tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_STATE;
							tvis.item.pszText = pItemName;
							tvis.item.lParam = (LPARAM) treeItem;

							tvis.item.state = tvis.item.stateMask = db_get_b(NULL, "SkinIconsUI", treeItem->paramName, TVIS_EXPANDED);
							hItem = TreeView_InsertItem(hwndTree, &tvis);
						}
						else {
							TVITEM tvi = {0};
							tvi.hItem = hItem;
							tvi.mask = TVIF_HANDLE | TVIF_PARAM;
							TreeView_GetItem(hwndTree, &tvi);
							TreeItem *treeItem = (TreeItem *)tvi.lParam;
							treeItem->value = SECTIONPARAM_MAKE(indx, sectionLevel, SECTIONPARAM_HAVEPAGE);
						}
					}

					if (sectionName) {
						*sectionName = '/';
						sectionName++;
					}
					sectionLevel++;

					hSection = hItem;
				}
			}

			ShowWindow(hwndTree, SW_SHOW);

			TreeView_SelectItem(hwndTree, FindNamedTreeItemAt(hwndTree, 0, NULL));
		}
		break;

	//  Rebuild preview to new section
	case DM_REBUILDICONSPREVIEW:
		{
			SectionItem* sectionActive = (SectionItem*)lParam;
			EnableWindow(hPreview, sectionActive != NULL);

			ListView_DeleteAllItems(hPreview);
			HIMAGELIST hIml = ListView_GetImageList(hPreview, LVSIL_NORMAL);
			ImageList_RemoveAll(hIml);

			if (sectionActive == NULL)
				break;

			LVITEM lvi = {0};
			lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
			{
				mir_cslock lck(csIconList);

				for (int indx = 0; indx < iconList.getCount(); indx++) {
					IcolibItem *item = iconList[indx];
					if (item->section == sectionActive) {
						lvi.pszText = item->getDescr();
						HICON hIcon = item->temp_icon;
						if (!hIcon)
							hIcon = IconItem_GetIcon_Preview(item);
						lvi.iImage = ImageList_AddIcon(hIml, hIcon);
						lvi.lParam = indx;
						ListView_InsertItem(hPreview, &lvi);
						if (hIcon != item->temp_icon)
							SafeDestroyIcon(&hIcon);
					}
				}
			}

			if (sectionActive->flags & SIDF_SORTED)
				ListView_SortItems(hPreview, DoSortIconsFunc, 0);
			else
				ListView_SortItems(hPreview, DoSortIconsFuncByOrder, 0);
		}
		break;

	// Refresh preview to new section
	case DM_UPDATEICONSPREVIEW:
		{
			LVITEM lvi = {0};
			HICON hIcon;
			int indx, count;
			HIMAGELIST hIml = ListView_GetImageList(hPreview, LVSIL_NORMAL);

			lvi.mask = LVIF_IMAGE|LVIF_PARAM;
			count = ListView_GetItemCount(hPreview);

			for (indx = 0; indx < count; indx++) {
				lvi.iItem = indx;
				ListView_GetItem(hPreview, &lvi);
				{
					mir_cslock lck(csIconList);
					hIcon = iconList[lvi.lParam]->temp_icon;
					if (!hIcon)
						hIcon = IconItem_GetIcon_Preview(iconList[lvi.lParam]);
				}

				if (hIcon)
					ImageList_ReplaceIcon(hIml, lvi.iImage, hIcon);
				if (hIcon != iconList[lvi.lParam]->temp_icon) SafeDestroyIcon(&hIcon);
			}
			ListView_RedrawItems(hPreview, 0, count);
		}
		break;

	// Temporary change icon - only inside options dialog
	case DM_CHANGEICON:
		{
			LVITEM lvi = {0};
			lvi.mask = LVIF_PARAM;
			lvi.iItem = wParam;
			ListView_GetItem(hPreview, &lvi);
			{
				mir_cslock lck(csIconList);
				IcolibItem *item = iconList[ lvi.lParam ];

				SAFE_FREE((void**)&item->temp_file);
				SafeDestroyIcon(&item->temp_icon);

				TCHAR *path = (TCHAR*)lParam;
				item->temp_file = mir_tstrdup(path);
				item->temp_icon = (HICON)ExtractIconFromPath(path, item->cx, item->cy);
				item->temp_reset = FALSE;
			}
			DoOptionsChanged(hwndDlg);
		}
		break;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDC_IMPORT) {
			dat->hwndIndex = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ICOLIB_IMPORT), GetParent(hwndDlg), DlgProcIconImport, (LPARAM)hwndDlg);
			EnableWindow((HWND)lParam, FALSE);
		}
		else if (LOWORD(wParam) == IDC_GETMORE) {
			OpenIconsPage();
			break;
		}
		else if (LOWORD(wParam) == IDC_LOADICONS) {
			TCHAR filetmp[1] = {0};
			TCHAR *file;

			if (file = OpenFileDlg(hwndDlg, filetmp, FALSE)) {
				HWND htv = GetDlgItem(hwndDlg, IDC_CATEGORYLIST);
				TCHAR filename[ MAX_PATH ];

				PathToRelativeT(file, filename);
				SAFE_FREE((void**)&file);

				MySetCursor(IDC_WAIT);
				LoadSubIcons(htv, filename, TreeView_GetSelection(htv));
				MySetCursor(IDC_ARROW);

				DoOptionsChanged(hwndDlg);
			}
		}
		break;

	case WM_CONTEXTMENU:
		if ((HWND)wParam == hPreview) {
			UINT count = ListView_GetSelectedCount(hPreview);

			if (count > 0) {
				int cmd = OpenPopupMenu(hwndDlg);
				switch(cmd) {
				case ID_CANCELCHANGE:
				case ID_RESET:
					{
						LVITEM lvi = {0};
						int itemIndx = -1;

						while ((itemIndx = ListView_GetNextItem(hPreview, itemIndx, LVNI_SELECTED)) != -1) {
							lvi.mask = LVIF_PARAM;
							lvi.iItem = itemIndx; //lvhti.iItem;
							ListView_GetItem(hPreview, &lvi);

							UndoChanges(lvi.lParam, cmd);
						}

						DoOptionsChanged(hwndDlg);
						break;
					}
				}
			}
		}
		else {
			HWND htv = GetDlgItem(hwndDlg, IDC_CATEGORYLIST);
			if ((HWND)wParam == htv) {
				int cmd = OpenPopupMenu(hwndDlg);

				switch(cmd) {
				case ID_CANCELCHANGE:
				case ID_RESET:
					UndoSubItemChanges(htv, TreeView_GetSelection(htv), cmd);
					DoOptionsChanged(hwndDlg);
					break;
				}
			}
		}
		break;

	case WM_NOTIFY:
		switch(((LPNMHDR)lParam)->idFrom) {
		case 0:
			switch(((LPNMHDR)lParam)->code) {
			case PSN_APPLY:
				{
					mir_cslock lck(csIconList);

					for (int indx = 0; indx < iconList.getCount(); indx++) {
						IcolibItem *item = iconList[indx];
						if (item->temp_reset) {
							db_unset(NULL, "SkinIcons", item->name);
							if (item->source_small != item->default_icon) {
								IconSourceItem_Release(&item->source_small);
							}
						}
						else if (item->temp_file) {
							db_set_ts(NULL, "SkinIcons", item->name, item->temp_file);
							IconSourceItem_Release(&item->source_small);
							SafeDestroyIcon(&item->temp_icon);
						}
					}
				}

				DoIconsChanged(hwndDlg);
				return TRUE;
			}
			break;

		case IDC_PREVIEW:
			if (((LPNMHDR)lParam)->code == LVN_GETINFOTIP) {
				IcolibItem *item;
				NMLVGETINFOTIP *pInfoTip = (NMLVGETINFOTIP *)lParam;
				LVITEM lvi;
				lvi.mask = LVIF_PARAM;
				lvi.iItem = pInfoTip->iItem;
				ListView_GetItem(pInfoTip->hdr.hwndFrom, &lvi);

				if (lvi.lParam < iconList.getCount()) {
					item = iconList[lvi.lParam];
					if (item->temp_file)
						_tcsncpy(pInfoTip->pszText, item->temp_file, pInfoTip->cchTextMax);
					else if (item->default_file)
						mir_sntprintf(pInfoTip->pszText, pInfoTip->cchTextMax, _T("%s, %d"), item->default_file, item->default_indx);
				}
			}
			if (bNeedRebuild) {
				bNeedRebuild = FALSE;
				SendMessage(hwndDlg, DM_REBUILD_CTREE, 0, 0);
			}
			break;

		case IDC_CATEGORYLIST:
			switch(((NMHDR*)lParam)->code) {
			case TVN_SELCHANGEDA: // !!!! This needs to be here - both !!
			case TVN_SELCHANGEDW:
				{
					NMTREEVIEW *pnmtv = (NMTREEVIEW*)lParam;
					TVITEM tvi = pnmtv->itemNew;
					TreeItem *treeItem = (TreeItem *)tvi.lParam;
					if (treeItem)
						SendMessage(hwndDlg, DM_REBUILDICONSPREVIEW, 0, (LPARAM)(
							(SECTIONPARAM_FLAGS(treeItem->value)&SECTIONPARAM_HAVEPAGE)?
							sectionList[ SECTIONPARAM_INDEX(treeItem->value) ] : NULL));
					break;
				}
			case TVN_DELETEITEMA: // no idea why both TVN_SELCHANGEDA/W should be there but let's keep this both too...
			case TVN_DELETEITEMW:
				{
					TreeItem *treeItem = (TreeItem *)(((LPNMTREEVIEW)lParam)->itemOld.lParam);
					if (treeItem) {
						mir_free(treeItem->paramName);
						mir_free(treeItem);
					}
					break;
				}
			}
			if (bNeedRebuild) {
				{
					mir_cslock lck(csIconList);
					bNeedRebuild = FALSE;
				}
				SendMessage(hwndDlg, DM_REBUILD_CTREE, 0, 0);
			}
		}
		break;

	case WM_DESTROY:
		SaveCollapseState( GetDlgItem(hwndDlg, IDC_CATEGORYLIST));
		DestroyWindow(dat->hwndIndex);
		{
			mir_cslock lck(csIconList);
			for (int indx = 0; indx < iconList.getCount(); indx++) {
				IcolibItem *item = iconList[indx];

				SAFE_FREE((void**)&item->temp_file);
				SafeDestroyIcon(&item->temp_icon);
			}
		}

		SAFE_FREE((void**)&dat);
		break;
	}

	return FALSE;
}
Пример #28
0
/**
 * @internal
 *
 * @brief This function parses the last end of a channel request packet.
 *
 * This is normally converted to a SSH message and placed in the queue.
 *
 * @param[in]  session  The SSH session.
 *
 * @param[in]  channel  The channel the request is made on.
 *
 * @param[in]  packet   The rest of the packet to be parsed.
 *
 * @param[in]  request  The type of request.
 *
 * @param[in]  want_reply The want_reply field from the request.
 *
 * @returns             SSH_OK on success, SSH_ERROR if an error occured.
 */
int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet,
    const char *request, uint8_t want_reply) {
  ssh_message msg = NULL;
  enter_function();
  msg = ssh_message_new(session);
  if (msg == NULL) {
    ssh_set_error_oom(session);
    goto error;
  }

  ssh_log(session, SSH_LOG_PACKET,
      "Received a %s channel_request for channel (%d:%d) (want_reply=%hhd)",
      request, channel->local_channel, channel->remote_channel, want_reply);

  msg->type = SSH_REQUEST_CHANNEL;
  msg->channel_request.channel = channel;
  msg->channel_request.want_reply = want_reply;

  if (strcmp(request, "pty-req") == 0) {
    ssh_string term = NULL;
    char *term_c = NULL;
    term = buffer_get_ssh_string(packet);
    if (term == NULL) {
      ssh_set_error_oom(session);
      goto error;
    }
    term_c = ssh_string_to_char(term);
    if (term_c == NULL) {
      ssh_set_error_oom(session);
      ssh_string_free(term);
      goto error;
    }
    ssh_string_free(term);

    msg->channel_request.type = SSH_CHANNEL_REQUEST_PTY;
    msg->channel_request.TERM = term_c;

    buffer_get_u32(packet, &msg->channel_request.width);
    buffer_get_u32(packet, &msg->channel_request.height);
    buffer_get_u32(packet, &msg->channel_request.pxwidth);
    buffer_get_u32(packet, &msg->channel_request.pxheight);

    msg->channel_request.width = ntohl(msg->channel_request.width);
    msg->channel_request.height = ntohl(msg->channel_request.height);
    msg->channel_request.pxwidth = ntohl(msg->channel_request.pxwidth);
    msg->channel_request.pxheight = ntohl(msg->channel_request.pxheight);
    msg->channel_request.modes = buffer_get_ssh_string(packet);
    if (msg->channel_request.modes == NULL) {
      SAFE_FREE(term_c);
      goto error;
    }
    goto end;
  }

  if (strcmp(request, "window-change") == 0) {
    msg->channel_request.type = SSH_CHANNEL_REQUEST_WINDOW_CHANGE;

    buffer_get_u32(packet, &msg->channel_request.width);
    buffer_get_u32(packet, &msg->channel_request.height);
    buffer_get_u32(packet, &msg->channel_request.pxwidth);
    buffer_get_u32(packet, &msg->channel_request.pxheight);

    msg->channel_request.width = ntohl(msg->channel_request.width);
    msg->channel_request.height = ntohl(msg->channel_request.height);
    msg->channel_request.pxwidth = ntohl(msg->channel_request.pxwidth);
    msg->channel_request.pxheight = ntohl(msg->channel_request.pxheight);

    goto end;
  }

  if (strcmp(request, "subsystem") == 0) {
    ssh_string subsys = NULL;
    char *subsys_c = NULL;
    subsys = buffer_get_ssh_string(packet);
    if (subsys == NULL) {
      ssh_set_error_oom(session);
      goto error;
    }
    subsys_c = ssh_string_to_char(subsys);
    if (subsys_c == NULL) {
      ssh_set_error_oom(session);
      ssh_string_free(subsys);
      goto error;
    }
    ssh_string_free(subsys);

    msg->channel_request.type = SSH_CHANNEL_REQUEST_SUBSYSTEM;
    msg->channel_request.subsystem = subsys_c;

    goto end;
  }

  if (strcmp(request, "shell") == 0) {
    msg->channel_request.type = SSH_CHANNEL_REQUEST_SHELL;
    goto end;
  }

  if (strcmp(request, "exec") == 0) {
    ssh_string cmd = NULL;
    cmd = buffer_get_ssh_string(packet);
    if (cmd == NULL) {
      ssh_set_error_oom(session);
      goto error;
    }
    msg->channel_request.type = SSH_CHANNEL_REQUEST_EXEC;
    msg->channel_request.command = ssh_string_to_char(cmd);
    ssh_string_free(cmd);
    if (msg->channel_request.command == NULL) {
      goto error;
    }
    goto end;
  }

  if (strcmp(request, "env") == 0) {
    ssh_string name = NULL;
    ssh_string value = NULL;
    name = buffer_get_ssh_string(packet);
    if (name == NULL) {
      ssh_set_error_oom(session);
      goto error;
    }
    value = buffer_get_ssh_string(packet);
    if (value == NULL) {
      ssh_set_error_oom(session);
      ssh_string_free(name);
      goto error;
    }

    msg->channel_request.type = SSH_CHANNEL_REQUEST_ENV;
    msg->channel_request.var_name = ssh_string_to_char(name);
    msg->channel_request.var_value = ssh_string_to_char(value);
    if (msg->channel_request.var_name == NULL ||
        msg->channel_request.var_value == NULL) {
      ssh_string_free(name);
      ssh_string_free(value);
      goto error;
    }
    ssh_string_free(name);
    ssh_string_free(value);

    goto end;
  }

  if (strcmp(request, "x11-req") == 0) {
    ssh_string auth_protocol = NULL;
    ssh_string auth_cookie = NULL;

    buffer_get_u8(packet, &msg->channel_request.x11_single_connection);

    auth_protocol = buffer_get_ssh_string(packet);
    if (auth_protocol == NULL) {
      ssh_set_error_oom(session);
      goto error;
    }
    auth_cookie = buffer_get_ssh_string(packet);
    if (auth_cookie == NULL) {
      ssh_set_error_oom(session);
      ssh_string_free(auth_protocol);
      goto error;
    }

    msg->channel_request.type = SSH_CHANNEL_REQUEST_X11;
    msg->channel_request.x11_auth_protocol = ssh_string_to_char(auth_protocol);
    msg->channel_request.x11_auth_cookie = ssh_string_to_char(auth_cookie);
    if (msg->channel_request.x11_auth_protocol == NULL ||
        msg->channel_request.x11_auth_cookie == NULL) {
      ssh_string_free(auth_protocol);
      ssh_string_free(auth_cookie);
      goto error;
    }
    ssh_string_free(auth_protocol);
    ssh_string_free(auth_cookie);

    buffer_get_u32(packet, &msg->channel_request.x11_screen_number);

    goto end;
  }

  msg->channel_request.type = SSH_CHANNEL_REQUEST_UNKNOWN;
end:
  ssh_message_queue(session,msg);
  leave_function();
  return SSH_OK;
error:
  ssh_message_free(msg);

  leave_function();
  return SSH_ERROR;
}
Пример #29
0
/****************************************************************************
reply to a session setup spnego negotiate packet for kerberos
****************************************************************************/
static int reply_spnego_kerberos(connection_struct *conn, 
				 char *inbuf, char *outbuf,
				 int length, int bufsize,
				 DATA_BLOB *secblob)
{
	DATA_BLOB ticket;
	char *client, *p, *domain;
	fstring netbios_domain_name;
	struct passwd *pw;
	char *user;
	int sess_vuid;
	NTSTATUS ret;
	DATA_BLOB auth_data;
	DATA_BLOB ap_rep, ap_rep_wrapped, response;
	auth_serversupplied_info *server_info = NULL;
	DATA_BLOB session_key = data_blob(NULL, 0);
	uint8 tok_id[2];
	DATA_BLOB nullblob = data_blob(NULL, 0);
	fstring real_username;

	ZERO_STRUCT(ticket);
	ZERO_STRUCT(auth_data);
	ZERO_STRUCT(ap_rep);
	ZERO_STRUCT(ap_rep_wrapped);
	ZERO_STRUCT(response);

	if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) {
		return ERROR_NT(NT_STATUS_LOGON_FAILURE);
	}

	ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, &session_key);

	data_blob_free(&ticket);

	if (!NT_STATUS_IS_OK(ret)) {
		DEBUG(1,("Failed to verify incoming ticket!\n"));	
		return ERROR_NT(NT_STATUS_LOGON_FAILURE);
	}

	data_blob_free(&auth_data);

	DEBUG(3,("Ticket name is [%s]\n", client));

	p = strchr_m(client, '@');
	if (!p) {
		DEBUG(3,("Doesn't look like a valid principal\n"));
		data_blob_free(&ap_rep);
		data_blob_free(&session_key);
		SAFE_FREE(client);
		return ERROR_NT(NT_STATUS_LOGON_FAILURE);
	}

	*p = 0;
	if (!strequal(p+1, lp_realm())) {
		DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
		if (!lp_allow_trusted_domains()) {
			data_blob_free(&ap_rep);
			data_blob_free(&session_key);
			SAFE_FREE(client);
			return ERROR_NT(NT_STATUS_LOGON_FAILURE);
		}
	}

	/* this gives a fully qualified user name (ie. with full realm).
	   that leads to very long usernames, but what else can we do? */

	domain = p+1;

	{
		/* If we have winbind running, we can (and must) shorten the
		   username by using the short netbios name. Otherwise we will
		   have inconsistent user names. With Kerberos, we get the
		   fully qualified realm, with ntlmssp we get the short
		   name. And even w2k3 does use ntlmssp if you for example
		   connect to an ip address. */

		struct winbindd_request wb_request;
		struct winbindd_response wb_response;
		NSS_STATUS wb_result;

		ZERO_STRUCT(wb_request);
		ZERO_STRUCT(wb_response);

		DEBUG(10, ("Mapping [%s] to short name\n", domain));

		fstrcpy(wb_request.domain_name, domain);

		wb_result = winbindd_request(WINBINDD_DOMAIN_INFO,
					     &wb_request, &wb_response);

		if (wb_result == NSS_STATUS_SUCCESS) {

			fstrcpy(netbios_domain_name,
				wb_response.data.domain_info.name);
			domain = netbios_domain_name;

			DEBUG(10, ("Mapped to [%s]\n", domain));
		} else {
			DEBUG(3, ("Could not find short name -- winbind "
				  "not running?\n"));
		}
	}

	asprintf(&user, "%s%c%s", domain, *lp_winbind_separator(), client);
	
	/* lookup the passwd struct, create a new user if necessary */

	map_username( user );

	pw = smb_getpwnam( user, real_username, True );
	
	if (!pw) {
		DEBUG(1,("Username %s is invalid on this system\n",user));
		SAFE_FREE(user);
		SAFE_FREE(client);
		data_blob_free(&ap_rep);
		data_blob_free(&session_key);
		return ERROR_NT(NT_STATUS_LOGON_FAILURE);
	}

	/* setup the string used by %U */
	
	sub_set_smb_name( real_username );
	reload_services(True);
	
	if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info, real_username, pw))) 
	{
		DEBUG(1,("make_server_info_from_pw failed!\n"));
		SAFE_FREE(user);
		SAFE_FREE(client);
		data_blob_free(&ap_rep);
		data_blob_free(&session_key);
		return ERROR_NT(ret);
	}

        /* make_server_info_pw does not set the domain. Without this we end up
	 * with the local netbios name in substitutions for %D. */

        if (server_info->sam_account != NULL) {
                pdb_set_domain(server_info->sam_account, domain, PDB_SET);
        }

	/* register_vuid keeps the server info */
	/* register_vuid takes ownership of session_key, no need to free after this.
 	   A better interface would copy it.... */
	sess_vuid = register_vuid(server_info, session_key, nullblob, client);

	SAFE_FREE(user);
	SAFE_FREE(client);

	if (sess_vuid == -1) {
		ret = NT_STATUS_LOGON_FAILURE;
	} else {
		/* current_user_info is changed on new vuid */
		reload_services( True );

		set_message(outbuf,4,0,True);
		SSVAL(outbuf, smb_vwv3, 0);
			
		if (server_info->guest) {
			SSVAL(outbuf,smb_vwv2,1);
		}
		
		SSVAL(outbuf, smb_uid, sess_vuid);

		if (!server_info->guest && !srv_signing_started()) {
			/* We need to start the signing engine
			 * here but a W2K client sends the old
			 * "BSRSPYL " signature instead of the
			 * correct one. Subsequent packets will
			 * be correct.
			 */
		       	srv_check_sign_mac(inbuf, False);
		}
	}

        /* wrap that up in a nice GSS-API wrapping */
	if (NT_STATUS_IS_OK(ret)) {
		ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_AP_REP);
	} else {
		ap_rep_wrapped = data_blob(NULL, 0);
	}
	response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD);
	reply_sesssetup_blob(conn, outbuf, response, ret);

	data_blob_free(&ap_rep);
	data_blob_free(&ap_rep_wrapped);
	data_blob_free(&response);

	return -1; /* already replied */
}
Пример #30
0
void sha1_final(unsigned char *md, SHACTX c)
{
    mbedtls_md_finish(c, md);
    mbedtls_md_free(c);
    SAFE_FREE(c);
}